CmuxFleet: board UI — right-sidebar mode, store/rows, config sheet, pane-openable - #7612
austinywang wants to merge 1 commit into
Conversation
Fleet PR 4 of #7361. Adds a beta-gated RightSidebarMode.fleet panel rendering every fleet task in Queue / Running / Needs input / Review / Done sections, driven by a pure FleetBoardProjection in CmuxFleet and a coalescing FleetBoardStore fed by the new FleetEngine.onStateChange chokepoint. Row click and socket fleet.task.open share one FleetTaskWorkspaceOpener path; retry/cancel/add/start/stop go through FleetEngine only. Includes a create-fleet config sheet, quick task add, command-palette wiring gated by the beta toggle, Settings beta row, and en+ja localization for all new strings. Extracts RightSidebarMode into its own file so RightSidebarPanelView stays under its length cap. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR adds the beta-gated Fleet board to the right sidebar and pane system. The main changes are:
Confidence Score: 4/5The Fleet board has two changed paths that need fixes before merging.
Sources/Fleet/FleetBoardStore.swift, Sources/TerminalController+ControlFleetContext.swift
|
| Filename | Overview |
|---|---|
| Sources/Fleet/FleetBoardStore.swift | Adds the app-side Fleet board store and refresh coalescing, but keeps per-board selection state in a shared singleton. |
| Sources/TerminalController+ControlFleetContext.swift | Routes task opening through the shared opener, but Fleet socket commands still bypass the beta gate. |
| Sources/Fleet/FleetBoardPanelView.swift | Adds the Fleet board panel with header actions, quick add, empty state, and snapshot-driven sections. |
| Sources/Fleet/FleetBoardRows.swift | Adds snapshot-based section and row views with localized state chips and context actions. |
| Packages/macOS/CmuxFleet/Sources/CmuxFleet/Board/FleetBoardProjection.swift | Adds pure Fleet state-to-board projection with grouped and sorted row snapshots. |
| Packages/macOS/CmuxFleet/Sources/CmuxFleet/Engine/FleetEngine.swift | Adds a state-change callback and notification calls after Fleet mutations. |
| Sources/RightSidebarMode+Availability.swift | Adds Fleet mode parsing and availability checks behind the new beta setting. |
| Resources/Localizable.xcstrings | Adds English and Japanese strings for the Fleet board, settings, commands, and task states. |
Reviews (1): Last reviewed commit: "Add Fleet board UI: right-sidebar mode, ..." | Re-trigger Greptile
|
|
||
| @MainActor | ||
| final class FleetBoardStore: ObservableObject { | ||
| static let shared = FleetBoardStore() |
There was a problem hiding this comment.
Fleet Selection Bleeds Across Boards
FleetBoardStore.shared owns selectedFleetID and snapshot, but FleetBoardPanelView() is mounted from both the right sidebar and Fleet tool panes. When two board instances are open, changing the fleet picker in one instance refreshes this singleton and silently switches the other instance to the same fleet.
Rule Used: Flag new ambient global state in production Swift:... (source)
| @@ -114,24 +114,12 @@ extension TerminalController: ControlFleetContext { | |||
| } | |||
|
|
|||
| func controlFleetTaskOpen(taskID: String) -> ControlFleetTaskOpenResolution { | |||
There was a problem hiding this comment.
fleet.task.open now reaches the shared opener without checking RightSidebarBetaFeatureSettings.isFleetEnabled(), and the sibling controlFleet* socket handlers call the Fleet engine the same way. A socket client can create, start, mutate, or open Fleet tasks while the Fleet beta is disabled, even though the sidebar and command-palette paths are default-denied.
Rule Used: Flag correctness-critical detection/identity deriv... (source)
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 0148091. Configure here.
| if after == before { | ||
| return .invalidState(before.state) | ||
| } | ||
| notifyStateChanged() |
There was a problem hiding this comment.
Double notifyStateChanged fires in userAction method
Low Severity
The userAction method calls apply(signal, to: id) which internally calls notifyStateChanged() (in the apply function at line 83 of FleetEngine+Signals.swift when next != task), and then userAction unconditionally calls notifyStateChanged() again at line 328 when the task changed. Since next != task and after != before are equivalent conditions, the callback always fires twice per user action. The store's coalescing prevents user-visible impact, but this contradicts the stated "single notification chokepoint" design.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 0148091. Configure here.


Fleet PR 4 of the chain in #7361 (stacks on #7418).
What
RightSidebarMode.fleet(beta-gated, default off): new board panel in the right-sidebar mode switcher, also openable as a pane like Files/Find/Sessions. Enabled via Settings → Beta Features → Fleet, CLI argfleet, and the command palette (all respecting the gate).FleetBoardProjection(CmuxFleet package): pure state→column mapping with exhaustive no-default switches, row snapshots, andcanUserRetry/canUserCancelpredicates mirroring the reducer rules.FleetEngine.onStateChange: single notification chokepoint after every public mutation and signal-driven state change;FleetBoardStorecoalesces refreshes to one rebuild per runloop tick and only publishes onEquatablechange.fleet.task.openboth call the extractedFleetTaskWorkspaceOpener.openTask— clicking a row is the only focus-changing action.RightSidebarModeextracted to its own file soRightSidebarPanelView.swiftlands at 507 lines (was at its 553 cap); no new file exceeds 218 lines; the length-budget TSV is untouched.Snapshot boundary
Nothing below the board's
LazyVStack/ForEachholds an ObservableObject: sections and rows receive immutableFleetBoardRowSnapshotvalues plus a closure action bundle, and row views areEquatablewith.equatable()(per the #2586 rule).Localization audit
All 52 new user-facing keys (mode label, column headers, chips, context menus, config sheet, empty state, Settings row, palette subtitle) have both
enandjaentries inResources/Localizable.xcstrings/ the settings catalog; parity was script-checked. No existing keys modified.Tests
onStateChangecoverage for every mutation and reduced signals).RightSidebarCommandPaletteTests(incl. new beta-gate regression test for the pane command),FileExplorerStateModePersistenceTests,RightSidebarModeShortcutHintTests— all pass. Note: the shortcut-hint suite has a pre-existing environment dependency (expects the feed beta default enabled in the host defaults domain); verified the 3 affected tests fail identically without this diff and pass with the gate on.fleet-board-ui) is green.🤖 Generated with Claude Code
Note
Cursor Bugbot is generating a summary for commit 0148091. Configure here.
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Summary by cubic
Adds a beta-gated Fleet board to the right sidebar (also openable as a pane) to track tasks across Queue, Running, Needs Input, Review, and Done. Keeps the UI live with a new
FleetEngine.onStateChangeand a lightweight projection/store.New Features
fleetmode and pane command, hidden behind the Beta Features toggle; shows column counts and rows with title, state, attempts, PR link, and last error.enandja.Refactors
CmuxFleet: addedFleetBoardProjectionplusFleetBoardSnapshot/FleetBoardRowSnapshot;FleetTaskStatenow exposescanUserRetry/canUserCancel.FleetEngine.onStateChange;FleetBoardStorecoalesces rebuilds and publishes only onEquatablechange.FleetTaskWorkspaceOpener; extractedRightSidebarModeto its own file and updated availability gating.Written for commit 0148091. Summary will update on new commits.