Repository navigation
Revert "Workspaces as todos: inferred status lifecycle + per-workspace checklist" (#7216) - #7761
Conversation
|
Too many files changed for review. ( Bypass the limit by tagging |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe PR removes workspace todo and status functionality across CLI commands, control-socket APIs, workspace models, persistence, panels, sidebar UI, settings, shortcuts, documentation, tests, and project source membership. It also updates focus handling, sidebar interactions, session persistence, and Swift file-length budget enforcement. ChangesWorkspace todo removal
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 23 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (23 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Sources/AppDelegate.swift (1)
13762-13773: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueAvoid the hardcoded
"cmux.settings"literal and the duplicate window resolution.
targetWindowis resolved twice (once in theif let, once in theelse), and the settings window is matched by a bare string literal. If a shared identifier constant /cmuxWindowShouldOwnCloseShortcut-style helper exists, prefer it over the raw literal, and hoist the window resolution to a singlelet.♻️ Proposed simplification
if matchConfiguredShortcut(event: event, action: .closeOtherTabsInPane) { - if let targetWindow = event.window ?? shortcutRoutingActiveWindow, - targetWindow.identifier?.rawValue == "cmux.settings" { + let targetWindow = event.window ?? shortcutRoutingActiveWindow + if let targetWindow, targetWindow.identifier?.rawValue == "cmux.settings" { targetWindow.performClose(nil) } else { - let targetWindow = event.window ?? shortcutRoutingActiveWindow if let terminalContext = focusedTerminalShortcutContext(preferredWindow: targetWindow) { terminalContext.tabManager.closeOtherTabsInFocusedPaneWithConfirmation() } else { tabManager?.closeOtherTabsInFocusedPaneWithConfirmation() } } return true }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/AppDelegate.swift` around lines 13762 - 13773, Refactor the close-other-tabs shortcut handling to resolve the target window once before branching. In the matchConfiguredShortcut block for .closeOtherTabsInPane, replace the hardcoded "cmux.settings" comparison with the existing shared window-identifier constant or cmuxWindowShouldOwnCloseShortcut-style helper, then reuse the resolved window for both the settings-close and terminal-context paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@Sources/AppDelegate.swift`:
- Around line 13762-13773: Refactor the close-other-tabs shortcut handling to
resolve the target window once before branching. In the matchConfiguredShortcut
block for .closeOtherTabsInPane, replace the hardcoded "cmux.settings"
comparison with the existing shared window-identifier constant or
cmuxWindowShouldOwnCloseShortcut-style helper, then reuse the resolved window
for both the settings-close and terminal-context paths.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: d71d01fb-79cb-450e-b017-1053034de73b
⛔ Files ignored due to path filters (1)
.github/swift-file-length-budget.tsvis excluded by!**/*.tsv
📒 Files selected for processing (106)
CLI/CMUXCLI+CommandSuggestions.swiftCLI/CMUXCLI+WorkspaceTodo.swiftCLI/cmux.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/ControlCommandContext.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/ControlCommandCoordinator.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Debug/ControlCommandCoordinator+Debug.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Debug/ControlDebugContext.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlCommandCoordinator+WorkspaceTodo.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlCommandCoordinator+WorkspaceTodoSetOpen.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoChecklistResolution.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoChecklistSnapshot.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoContext.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoMutationResolution.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoOpenResolution.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoSetResolution.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoStatusResolution.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoStatusSnapshot.swiftPackages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlCommandContextTestStubs+Debug.swiftPackages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlCommandCoordinatorWorkspaceTodoSetOpenTests.swiftPackages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlCommandCoordinatorWorkspaceTodoTests.swiftPackages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlWorkspaceTodoContextTestStubs.swiftPackages/macOS/CmuxSettings/Sources/CmuxSettings/Keys/BetaFeaturesCatalogSection.swiftPackages/macOS/CmuxSettings/Sources/CmuxSettings/Values/ShortcutAction+Defaults.swiftPackages/macOS/CmuxSettings/Sources/CmuxSettings/Values/ShortcutAction.swiftPackages/macOS/CmuxSettings/Sources/CmuxSettings/Values/WorkspaceTodoChecklistStyle.swiftPackages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Navigation/CuratedSettingEntry+Default.swiftPackages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/BetaFeaturesSection.swiftPackages/macOS/CmuxSettingsUI/Tests/CmuxSettingsUITests/SettingsRowAnchorResolutionTests.swiftPackages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Core/Values/SurfaceKind.swiftPackages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Values/WorkspaceChecklist.swiftPackages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Values/WorkspaceChecklistItem.swiftPackages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Values/WorkspaceChecklistProgressSummary.swiftPackages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Values/WorkspaceChecklistReplacement.swiftPackages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Values/WorkspaceTaskStatus.swiftPackages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Values/WorkspaceTaskStatusOverride.swiftPackages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Values/WorkspaceTaskStatusSignals.swiftPackages/macOS/CmuxWorkspaces/Tests/CmuxWorkspacesTests/Values/WorkspaceChecklistReplacementTests.swiftPackages/macOS/CmuxWorkspaces/Tests/CmuxWorkspacesTests/Values/WorkspaceChecklistTests.swiftPackages/macOS/CmuxWorkspaces/Tests/CmuxWorkspacesTests/Values/WorkspaceTaskStatusTests.swiftResources/Localizable.xcstringsSources/AllShortcutsPopover.swiftSources/App/ForeignFirstResponderPolicy.swiftSources/AppDelegate+AgentChat.swiftSources/AppDelegate+CmuxNavigationDeepLinks.swiftSources/AppDelegate+WorkspaceTodoShortcut.swiftSources/AppDelegate.swiftSources/Canvas/WorkspaceCanvasHostView.swiftSources/ChecklistInputField.swiftSources/ClosedItemHistory.swiftSources/CmuxLifecycleEventPublishing.swiftSources/CmuxSettingsJSONPathSupport.swiftSources/ContentView+RightSidebarCommandPalette.swiftSources/ContentView.swiftSources/KeyboardShortcutSettings+SystemWideHotkeyConflicts.swiftSources/KeyboardShortcutSettings.swiftSources/KeyboardShortcutSettingsFileStore+SectionParsers.swiftSources/KeyboardShortcutSettingsFileStore+Template.swiftSources/KeyboardShortcutSettingsFileStore.swiftSources/Mobile/MobileWorkspaceListObserver.swiftSources/Panels/Panel.swiftSources/Panels/PanelContentView.swiftSources/Panels/WorkspaceTodoPanel.swiftSources/Panels/WorkspaceTodoPanelView.swiftSources/Search/GlobalSearchDocuments.swiftSources/SessionPersistence+Todos.swiftSources/SessionPersistence.swiftSources/SettingsNavigation.swiftSources/SettingsSearchAliases.swiftSources/ShortcutDiscoveryButton.swiftSources/Sidebar/SidebarWorkspaceSnapshotRefreshPolicy.swiftSources/SidebarTabItemContextMenuState.swiftSources/SidebarWorkspaceChecklistPopover.swiftSources/SidebarWorkspaceChecklistView.swiftSources/SidebarWorkspaceSnapshotBuilder.swiftSources/SidebarWorkspaceStatusPopover.swiftSources/SidebarWorkspaceTaskStatusGlyph.swiftSources/SidebarWorkspaceTodoPopoverHost.swiftSources/TabItemView+WorkspaceTodo.swiftSources/TabManager+NotificationDismissalHosting.swiftSources/TabManager.swiftSources/TerminalController+ControlDebugContext.swiftSources/TerminalController+ControlSurfaceContext.swiftSources/TerminalController+ControlWorkspaceTodoContext.swiftSources/TerminalController+DebugMethodNames.swiftSources/TerminalController.swiftSources/TerminalPaneDropTargetView.swiftSources/VerticalTabsSidebar+EmptyAreasAndFooter.swiftSources/Workspace+LayoutCapture.swiftSources/Workspace+SurfaceNavigation.swiftSources/Workspace+TodoNotifications.swiftSources/Workspace+TodoPane.swiftSources/Workspace+Todos.swiftSources/Workspace.swiftSources/WorkspaceSidebarObservation.swiftSources/WorkspaceTodoFeature.swiftSources/WorkspaceTodoState.swiftcmux.xcodeproj/project.pbxprojcmuxTests/ForeignFirstResponderPolicyTests.swiftcmuxTests/SidebarWorkspaceRowInteractionStateTests.swiftcmuxTests/SidebarWorkspaceSnapshotRefreshPolicyTests.swiftcmuxTests/WorkspaceTodoSidebarModelTests.swiftcmuxTests/WorkspaceTodoSnapshotTests.swiftdocs/cli-contract.mddocs/configuration.mdweb/data/cmux-shortcuts.tsweb/data/cmux.schema.json
💤 Files with no reviewable changes (85)
- Sources/KeyboardShortcutSettings+SystemWideHotkeyConflicts.swift
- Packages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlCommandCoordinatorWorkspaceTodoTests.swift
- Sources/WorkspaceTodoState.swift
- Sources/SidebarTabItemContextMenuState.swift
- Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Values/WorkspaceTaskStatusSignals.swift
- Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoStatusResolution.swift
- Packages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlWorkspaceTodoContextTestStubs.swift
- Sources/SidebarWorkspaceSnapshotBuilder.swift
- Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoSetResolution.swift
- Packages/macOS/CmuxSettings/Sources/CmuxSettings/Keys/BetaFeaturesCatalogSection.swift
- cmuxTests/WorkspaceTodoSidebarModelTests.swift
- Packages/macOS/CmuxSettings/Sources/CmuxSettings/Values/ShortcutAction+Defaults.swift
- Sources/ContentView+RightSidebarCommandPalette.swift
- Sources/ChecklistInputField.swift
- Sources/AllShortcutsPopover.swift
- Sources/Workspace+TodoNotifications.swift
- Sources/KeyboardShortcutSettingsFileStore+SectionParsers.swift
- CLI/CMUXCLI+CommandSuggestions.swift
- Sources/Workspace+TodoPane.swift
- Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlCommandCoordinator+WorkspaceTodo.swift
- Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Values/WorkspaceChecklistItem.swift
- cmuxTests/WorkspaceTodoSnapshotTests.swift
- Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoStatusSnapshot.swift
- Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoMutationResolution.swift
- Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoChecklistResolution.swift
- Sources/VerticalTabsSidebar+EmptyAreasAndFooter.swift
- Sources/ClosedItemHistory.swift
- Packages/macOS/CmuxWorkspaces/Tests/CmuxWorkspacesTests/Values/WorkspaceChecklistReplacementTests.swift
- Sources/ShortcutDiscoveryButton.swift
- Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoChecklistSnapshot.swift
- Sources/CmuxSettingsJSONPathSupport.swift
- Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Values/WorkspaceChecklistProgressSummary.swift
- Sources/Panels/WorkspaceTodoPanel.swift
- Sources/AppDelegate+CmuxNavigationDeepLinks.swift
- Sources/SessionPersistence+Todos.swift
- Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Values/WorkspaceTaskStatus.swift
- Sources/SettingsNavigation.swift
- Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoOpenResolution.swift
- cmuxTests/SidebarWorkspaceRowInteractionStateTests.swift
- web/data/cmux-shortcuts.ts
- Sources/TerminalController+ControlDebugContext.swift
- Sources/SidebarWorkspaceChecklistPopover.swift
- CLI/CMUXCLI+WorkspaceTodo.swift
- Packages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlCommandContextTestStubs+Debug.swift
- Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlWorkspaceTodoContext.swift
- Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Values/WorkspaceChecklistReplacement.swift
- Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/WorkspaceTodo/ControlCommandCoordinator+WorkspaceTodoSetOpen.swift
- Sources/SidebarWorkspaceStatusPopover.swift
- Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Core/Values/SurfaceKind.swift
- Sources/TerminalController+DebugMethodNames.swift
- Sources/SidebarWorkspaceChecklistView.swift
- Packages/macOS/CmuxSettingsUI/Tests/CmuxSettingsUITests/SettingsRowAnchorResolutionTests.swift
- Sources/WorkspaceTodoFeature.swift
- Sources/SidebarWorkspaceTodoPopoverHost.swift
- Packages/macOS/CmuxWorkspaces/Tests/CmuxWorkspacesTests/Values/WorkspaceChecklistTests.swift
- Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Navigation/CuratedSettingEntry+Default.swift
- Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Values/WorkspaceChecklist.swift
- Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Debug/ControlDebugContext.swift
- Packages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlCommandCoordinatorWorkspaceTodoSetOpenTests.swift
- Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/ControlCommandContext.swift
- Sources/Panels/WorkspaceTodoPanelView.swift
- Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Values/WorkspaceTaskStatusOverride.swift
- Sources/TabItemView+WorkspaceTodo.swift
- Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/ControlCommandCoordinator.swift
- Packages/macOS/CmuxSettings/Sources/CmuxSettings/Values/WorkspaceTodoChecklistStyle.swift
- Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Debug/ControlCommandCoordinator+Debug.swift
- Sources/AppDelegate+WorkspaceTodoShortcut.swift
- Sources/AppDelegate+AgentChat.swift
- Sources/Canvas/WorkspaceCanvasHostView.swift
- Sources/TerminalController+ControlWorkspaceTodoContext.swift
- Sources/SidebarWorkspaceTaskStatusGlyph.swift
- Sources/Mobile/MobileWorkspaceListObserver.swift
- Sources/CmuxLifecycleEventPublishing.swift
- Sources/Panels/Panel.swift
- Sources/KeyboardShortcutSettingsFileStore+Template.swift
- Packages/macOS/CmuxWorkspaces/Tests/CmuxWorkspacesTests/Values/WorkspaceTaskStatusTests.swift
- Sources/Workspace+Todos.swift
- Sources/Workspace+SurfaceNavigation.swift
- Sources/SettingsSearchAliases.swift
- Sources/TabManager+NotificationDismissalHosting.swift
- web/data/cmux.schema.json
- Sources/TerminalController+ControlSurfaceContext.swift
- cmuxTests/ForeignFirstResponderPolicyTests.swift
- Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/BetaFeaturesSection.swift
- docs/configuration.md
c6a2dbd to
b352f09
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Sources/TerminalController.swift (1)
240-243: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winKeep socket error replies independent from localized UI text.
This v1 socket reply is derived from
terminalSurfaceUnavailableMessage, which usesString(localized:). The same command will emit different wire text per locale, breaking clients or tests that match exactERROR:replies. Use a stable, nonlocalized protocol literal and reserve the localized message for UI presentation.Based on learnings, v1 socket-protocol replies must remain stable literals and should not be localized.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/TerminalController.swift` around lines 240 - 243, The v1 socket error reply currently derives from localized UI text, making the wire protocol vary by locale. In the command handling associated with focusIntentV1Commands, replace terminalSurfaceUnavailableMessage usage for socket replies with a stable nonlocalized protocol literal, while retaining terminalSurfaceUnavailableMessage only for UI presentation.Source: Learnings
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/swift_file_length_budget.py`:
- Around line 275-302: Replace the range-wide range_has_revert_commit exemption
with a per-file exemption derived from the reverted commit diff, identifying
only files actually restored by a Revert commit. Update the growth-limit and
incidental-growth checks to consult that file-specific set, keeping enforcement
enabled for unrelated files and preserving the 800-line production Swift hard
cap unless the individual file is restored by the revert.
In `@Sources/TerminalController.swift`:
- Around line 11737-11748: The arrow cases in parseShortcutCombo() currently
store private-use key codes in StoredShortcut.key; replace them with the
canonical glyphs ←, →, ↓, and ↑ while preserving the existing keyCode and
charactersIgnoringModifiers assignments so shortcut parsing round-trips and
compares consistently.
---
Outside diff comments:
In `@Sources/TerminalController.swift`:
- Around line 240-243: The v1 socket error reply currently derives from
localized UI text, making the wire protocol vary by locale. In the command
handling associated with focusIntentV1Commands, replace
terminalSurfaceUnavailableMessage usage for socket replies with a stable
nonlocalized protocol literal, while retaining terminalSurfaceUnavailableMessage
only for UI presentation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8885dcb1-5f0e-423e-ab59-a4bd9fef88ef
⛔ Files ignored due to path filters (1)
.github/swift-file-length-budget.tsvis excluded by!**/*.tsv
📒 Files selected for processing (8)
Sources/KeyboardShortcutSettings.swiftSources/KeyboardShortcutSettingsFileStore+SectionParsers.swiftSources/KeyboardShortcutSettingsFileStore.swiftSources/SessionPersistence+RightSidebarTool.swiftSources/SessionPersistence.swiftSources/TerminalController.swiftcmux.xcodeproj/project.pbxprojscripts/swift_file_length_budget.py
💤 Files with no reviewable changes (2)
- Sources/KeyboardShortcutSettings.swift
- Sources/SessionPersistence.swift
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Sources/TerminalController.swift (1)
240-243: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winKeep socket error replies independent from localized UI text.
This v1 socket reply is derived from
terminalSurfaceUnavailableMessage, which usesString(localized:). The same command will emit different wire text per locale, breaking clients or tests that match exactERROR:replies. Use a stable, nonlocalized protocol literal and reserve the localized message for UI presentation.Based on learnings, v1 socket-protocol replies must remain stable literals and should not be localized.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/TerminalController.swift` around lines 240 - 243, The v1 socket error reply currently derives from localized UI text, making the wire protocol vary by locale. In the command handling associated with focusIntentV1Commands, replace terminalSurfaceUnavailableMessage usage for socket replies with a stable nonlocalized protocol literal, while retaining terminalSurfaceUnavailableMessage only for UI presentation.Source: Learnings
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/swift_file_length_budget.py`:
- Around line 275-302: Replace the range-wide range_has_revert_commit exemption
with a per-file exemption derived from the reverted commit diff, identifying
only files actually restored by a Revert commit. Update the growth-limit and
incidental-growth checks to consult that file-specific set, keeping enforcement
enabled for unrelated files and preserving the 800-line production Swift hard
cap unless the individual file is restored by the revert.
In `@Sources/TerminalController.swift`:
- Around line 11737-11748: The arrow cases in parseShortcutCombo() currently
store private-use key codes in StoredShortcut.key; replace them with the
canonical glyphs ←, →, ↓, and ↑ while preserving the existing keyCode and
charactersIgnoringModifiers assignments so shortcut parsing round-trips and
compares consistently.
---
Outside diff comments:
In `@Sources/TerminalController.swift`:
- Around line 240-243: The v1 socket error reply currently derives from
localized UI text, making the wire protocol vary by locale. In the command
handling associated with focusIntentV1Commands, replace
terminalSurfaceUnavailableMessage usage for socket replies with a stable
nonlocalized protocol literal, while retaining terminalSurfaceUnavailableMessage
only for UI presentation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8885dcb1-5f0e-423e-ab59-a4bd9fef88ef
⛔ Files ignored due to path filters (1)
.github/swift-file-length-budget.tsvis excluded by!**/*.tsv
📒 Files selected for processing (8)
Sources/KeyboardShortcutSettings.swiftSources/KeyboardShortcutSettingsFileStore+SectionParsers.swiftSources/KeyboardShortcutSettingsFileStore.swiftSources/SessionPersistence+RightSidebarTool.swiftSources/SessionPersistence.swiftSources/TerminalController.swiftcmux.xcodeproj/project.pbxprojscripts/swift_file_length_budget.py
💤 Files with no reviewable changes (2)
- Sources/KeyboardShortcutSettings.swift
- Sources/SessionPersistence.swift
🛑 Comments failed to post (2)
scripts/swift_file_length_budget.py (1)
275-302: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift
Scope the revert exemption to files actually restored by the revert.
Any commit subject starting with
Revertdisables both growth limits for every existing tracked file in the PR. A PR containing a legitimate revert plus unrelated large additions therefore bypasses the hard cap and incidental-growth checks globally.Keep enforcement enabled for unrelated files; derive a per-file exemption from the reverted diff rather than a range-wide subject heuristic.
As per coding guidelines, existing production Swift files over 800 lines must not receive substantial growth unless the required architectural reduction or package boundary is provided.
Also applies to: 315-315, 335-338, 550-550, 592-592
🧰 Tools
🪛 ast-grep (0.44.1)
[error] 275-281: Command coming from incoming request
Context: subprocess.run(
["git", "-C", str(repo_root), "log", "-1", "--format=%s", ref],
check=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').(subprocess-from-request)
[error] 292-298: Command coming from incoming request
Context: subprocess.run(
["git", "-C", str(repo_root), "log", "--format=%s", range_expr],
check=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').(subprocess-from-request)
🪛 Ruff (0.15.20)
[warning] 276-282: Prefer
capture_outputover sendingstdoutandstderrtoPIPEReplace with
capture_outputkeyword argument(UP022)
[error] 276-276:
subprocesscall: check for execution of untrusted input(S603)
[error] 277-277: Starting a process with a partial executable path
(S607)
[warning] 289-292: Use ternary operator
range_expr = head_ref if base_ref is None else f"{base_ref}..{head_ref}"instead ofif-else-blockReplace
if-else-block withrange_expr = head_ref if base_ref is None else f"{base_ref}..{head_ref}"(SIM108)
[warning] 293-299: Prefer
capture_outputover sendingstdoutandstderrtoPIPEReplace with
capture_outputkeyword argument(UP022)
[error] 293-293:
subprocesscall: check for execution of untrusted input(S603)
[error] 294-294: Starting a process with a partial executable path
(S607)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/swift_file_length_budget.py` around lines 275 - 302, Replace the range-wide range_has_revert_commit exemption with a per-file exemption derived from the reverted commit diff, identifying only files actually restored by a Revert commit. Update the growth-limit and incidental-growth checks to consult that file-specific set, keeping enforcement enabled for unrelated files and preserving the 800-line production Swift hard cap unless the individual file is restored by the revert.Source: Coding guidelines
Sources/TerminalController.swift (1)
11737-11748: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash set -euo pipefail rg -n -C 5 'parseShortcutCombo|ParsedShortcutCombo|\.storedKey|storedKey\(' \ Sources/TerminalController.swift Sources/KeyboardShortcutSettings.swiftRepository: manaflow-ai/cmux
Length of output: 6018
🏁 Script executed:
#!/usr/bin/env bash set -euo pipefail sed -n '1784,1815p' Sources/KeyboardShortcutSettings.swift printf '\n---\n' sed -n '11691,11795p' Sources/TerminalController.swift printf '\n---\n' rg -n -C 3 'storedKey\(keyCode:|case "left"|case "right"|case "down"|case "up"|specialKey|RecordableKey|StoredShortcut' Sources/KeyboardShortcutSettings.swift Sources/TerminalController.swiftRepository: manaflow-ai/cmux
Length of output: 50372
🏁 Script executed:
#!/usr/bin/env bash set -euo pipefail rg -n -C 4 'struct StoredShortcut|enum StoredShortcut|storedKey|displayString|carbonHotKeyRegistration|Codable|Equatable' Sources/KeyboardShortcutSettings.swift Sources/TerminalController.swiftRepository: manaflow-ai/cmux
Length of output: 24664
🏁 Script executed:
#!/usr/bin/env bash set -euo pipefail sed -n '11000,11080p' Sources/TerminalController.swift printf '\n---\n' sed -n '2111,2336p' Sources/KeyboardShortcutSettings.swiftRepository: manaflow-ai/cmux
Length of output: 11028
🏁 Script executed:
#!/usr/bin/env bash set -euo pipefail sed -n '1444,1605p' Sources/KeyboardShortcutSettings.swift printf '\n---\n' sed -n '2337,2475p' Sources/KeyboardShortcutSettings.swiftRepository: manaflow-ai/cmux
Length of output: 9717
🏁 Script executed:
#!/usr/bin/env bash set -euo pipefail rg -n -C 4 'usesDirectKeyCodeMatching|resolvedKeyCode\(|parseConfigKeyToken|menuItemKeyEquivalent|keyEquivalent|storedKey\(keyCode:' Sources/KeyboardShortcutSettings.swiftRepository: manaflow-ai/cmux
Length of output: 4168
🏁 Script executed:
#!/usr/bin/env bash set -euo pipefail sed -n '900,980p' Sources/KeyboardShortcutSettings.swift printf '\n---\n' sed -n '2337,2425p' Sources/KeyboardShortcutSettings.swiftRepository: manaflow-ai/cmux
Length of output: 6001
🏁 Script executed:
#!/usr/bin/env bash set -euo pipefail sed -n '660,740p' Sources/KeyboardShortcutSettings.swift printf '\n---\n' sed -n '2070,2105p' Sources/KeyboardShortcutSettings.swiftRepository: manaflow-ai/cmux
Length of output: 4850
Use the canonical arrow glyphs for parsed shortcuts.
parseShortcutCombo()stores\u{F700}–\u{F703}inStoredShortcut.key, but the rest of the shortcut model compares and serializes arrows as←/→/↓/↑. That breaks round-tripping and equality for arrow bindings created through this path.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/TerminalController.swift` around lines 11737 - 11748, The arrow cases in parseShortcutCombo() currently store private-use key codes in StoredShortcut.key; replace them with the canonical glyphs ←, →, ↓, and ↑ while preserving the existing keyCode and charactersIgnoringModifiers assignments so shortcut parsing round-trips and compares consistently.
The raw revert of #7216 reintroduced several unrelated code blocks that had been extracted into sibling files purely to satisfy the Swift file-length budget (not because they were todo-specific): AppDelegate's authURLDebugSummary/feedWorkstreamTitle helpers, TabManager's hashNotifications, and Workspace's surfaceKind/ hasUnreadNotification. Remove the reintroduced duplicates from the main files and restore them in their extraction siblings. Also wire KeyboardShortcutSettingsFileStore+SectionParsers.swift and KeyboardShortcutSettings+SystemWideHotkeyConflicts.swift into project.pbxproj. Both files were already committed on this branch but never added to the Sources build phase, so Xcode silently skipped compiling them: KeyboardShortcutSettingsFileStore.swift called parseFileEditorSection/parseFileExplorerSection but their definitions in the unwired extraction file were invisible to the build, breaking activation-session-benchmark and app-host unit tests in CI.
…7790) * Restore workspaces-as-todos, default new workspaces to None status Reverts the revert (PR #7761) of "Workspaces as todos: inferred status lifecycle + per-workspace checklist" (#7216), restoring the feature. Additionally flips WorkspaceTodoState.statusHidden's default to true so newly created workspaces start with the status glyph hidden (the existing "None" opt-out state) instead of Auto — the feature is opt-in per workspace going forward. Pre-existing persisted workspaces that predate this field still restore to their historical visible/Auto state. * Route the checklist's first item through the popover in popover style (#7797) * Route the checklist's first item through the popover in popover style usesPopoverPresentation && totalCount > 0 forced inline entry for a workspace's very first checklist item regardless of the popover setting, since an empty checklist has no summary line to anchor a popover to. Move the popover anchor from the summary line to the section container (stable across the 0->1 item transition), route the ghost "Add item" button through the same popover-toggle path as the summary line, and fix the "Add Checklist Item..." notification handler in ContentView.swift (it special-cased non-empty checklists, so the context-menu/palette path still fell back to inline for a fresh workspace even after the view-level fix). Inline style is unaffected. * Fix: checklist section never rendered for hidden-status workspaces taskStatus is nil whenever a workspace's status is hidden (statusHidden), which restore-workspace-todos-default-none made the default for all new workspaces. The checklist section's render gate required taskStatus != nil, so "Add Checklist Item..." silently did nothing for any new workspace. Drop that condition; the checklist section only needs its own content/token gate. * Add hover-reveal delete button to checklist item rows The only way to delete a checklist item was a hidden right-click "Remove" context menu entry. Add a trailing xmark.circle.fill button that appears on row hover (reserved layout space, opacity/hit-test toggle only, so row height never jumps) in both row implementations: the inline sidebar row and the NSPopover-hosted row. Both call the existing actions.removeItem(_:) closure, the same one the context menu already used; the context menu entry is unchanged. New localized tooltip key sidebar.checklist.removeItemTooltip ("Remove item" / "項目を削除"). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Fix checklist popover focus ambiguity, ghost row, and item alignment; add keyboard delete - Highlighting a checklist item (click, Up/Down) and typing a new item in the add field are now mutually exclusive: a non-empty draft clears any highlight, and highlight-setting paths no-op while a draft exists. Makes Return's outcome (toggle item vs. commit new item) unambiguous. - Popover-style checklists no longer show a persistent ghost "Add item" row inline when a workspace has zero items. "Add Checklist Item…" now opens the popover directly with nothing shown inline until an item is actually added, at which point the existing summary line is the small status preview. - Item rows now center-align the checkbox and text (was firstTextBaseline, which misaligned the checkbox glyph against the text's baseline). - Backspace with an empty draft and a highlighted item now removes it, a keyboard-driven delete alongside the existing hover "x" and context menu "Remove". * Fix checklist popover anchor for zero-item workspaces An empty VStack collapses to a degenerate frame, which broke the NSPopover anchor view's bounds/window attachment when a workspace had zero checklist items — "Add Checklist Item…" silently failed to open the popover. Keep a minimal invisible placeholder so the anchor always has real geometry. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Fix checklist popover open reliability, hover, scroll cap, and multi-line alignment The prior zero-item placeholder fix didn't retry reliably: it depended on an unrelated later re-render landing after the anchor NSView actually attached to its window, so "Add Checklist Item..." on a fresh workspace usually opened nothing until some other UI event fired. Replace it with an AnchorView subclass that retries present() from viewDidMoveToWindow(), so the popover opens deterministically as soon as AppKit finishes attaching it. The popover host's NSViewRepresentable anchor was also stacked as a .background() spanning the whole checklist section, which suppressed .onHover for the item rows underneath it (the hover-reveal delete "x" rarely appeared). Shrink the anchor to a fixed 1x1pt .overlay corner so it never intercepts hover/hit-testing, and drop the now-unnecessary Color.clear placeholder that caused the "bottom padding" artifact. Both the inline expansion and the popover now show all items in a ScrollView capped at 6 rows instead of hard-clamping with a "... N more" row, and item rows use .firstTextBaseline alignment with an alignmentGuide offset (derived from font ascender/descender) so the checkbox and delete button center on the first line of wrapped multi-line item text rather than the baseline or the whole block. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Fix checklist item text wrap in the dedicated Todo Pane view WorkspaceTodoPaneItemRow was missing the same multi-line-wrap fix already applied to the sidebar's inline list and popover: long item text overflowed unwrapped past the pane's edge instead of wrapping. Adds .fixedSize(horizontal: false, vertical: true) + .multilineTextAlignment(.leading) to the item Text, and centers the checkbox on the text's first line via .alignmentGuide(.firstTextBaseline). * Fix checklist popover zero-item anchor, hover-reveal delete, and re-present churn Three root causes, each verified against a live tagged build: - Zero-item anchor: the section VStack renders no children for an empty checklist in popover style, so .overlay(.topTrailing) collapsed to the row's LEFT edge. The container now claims the row's full width (maxWidth: .infinity) so the anchor always sits at the real right edge. - Hover-reveal delete x: per-row .onContinuousHover state died whenever popover content was recreated or rows reflowed under a stationary pointer (no new mouse-moved event arrives). hoveredItemId is now DERIVED from one container-level pointer location plus row frames collected via preference, seeded from NSEvent.mouseLocation at window attach, so the x survives model changes and fresh presents. - Re-present churn: when AppKit closed the transient popover (app deactivation, click-away) the container's isPresented=false write landed asynchronously, so a stale re-render tick re-presented the popover the user just dismissed (observed live: five didShows in 18s). The host coordinator now latches after an AppKit-side close until the container acknowledges false; an explicit add-request token change clears the latch so "Add Checklist Item…" can always present. Also: programmatic/keyboard workspace switches now dismiss open checklist/status popovers (no outside click for transient behavior to catch), and the Todo Pane keeps arrow-key scroll-follow. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Own checklist popover hover tracking in AppKit, not SwiftUI hover modifiers Independent artifact verification of the previous commit caught the delete x vanishing on a 1px pointer move right after a checklist mutation: SwiftUI's .onContinuousHover rebuilds its NSTrackingArea on content updates, and the first mouse event after a rebuild can arrive as a spurious .ended from the torn-down area with no follow-up .active until the next event. The popover's pointer location is now tracked by a persistent AppKit NSView (PopoverPointerTracker) whose NSTrackingArea only changes with geometry, never content: mouseEntered/mouseMoved report the location, mouseExited clears it, and viewDidMoveToWindow seeds from NSEvent.mouseLocation so a popover presenting under a resting pointer still shows hover affordances. .activeAlways keeps hover alive when the terminal pane steals key status from the popover window. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Split checklist popover pointer tracking and summary modifier into own files Keeps SidebarWorkspaceChecklistPopover.swift and SidebarWorkspaceChecklistView.swift under the 500-line tracking threshold of the Swift file-length budget gate. Pure moves: PopoverPointerTracker + ChecklistPopoverRowFramesKey to ChecklistPopoverPointerTracking.swift, ChecklistSummaryPopoverModifier to ChecklistSummaryPopoverModifier.swift (private -> internal). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Ratchet ContentView.swift file-length budget down to actual (16262) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Trim ContentView comment growth to net zero for the file-length hard cap Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Fix spontaneous checklist popover re-presents and Open as Pane focus Root cause of the popover opening by itself while typing in the todo pane (user video 2026-07-13): the popover host coordinator captured its isPresented @binding once at creation. The binding's get closure closes over that render's value snapshot, so a coordinator created while the popover was hidden read a frozen `false` forever. On an AppKit-side close (click-away), popoverDidClose's `if isPresented` guard read that stale false and skipped writing false back, leaving the container's checklistPopoverWorkspaceId stuck set — and every later model change (e.g. committing an item in the todo pane) re-rendered the host with isPresented=true and re-presented the popover with no user action. The coordinator now holds a Binding<Bool> refreshed on every updateNSView tick, so reads and write-backs always target current container state. Reproduced deterministically before the fix (todo add to the selected workspace -> didShow ~1s later, zero user actions). Open as Pane now focuses an already-open todo pane usefully: the footer closes the popover BEFORE opening the pane (NSPopover teardown restores the previous first responder, which clobbered the focus openPane had just set), and openOrFocusWorkspaceTodoSurface bumps a new addFieldArmToken on WorkspaceTodoPanel so the pane re-arms its add field even when it was already focused and isFocused never transitions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Only nonzero activation tokens unlatch the popover's dismissal ack The external-dismissal latch treated ANY presentationRequestToken change as a fresh present request, but the container RESETS the token to zero after the add field arms (consumption) — that reset unlatched a popover the user had just dismissed and let a stale re-render tick re-present it. Token zero now means consumed, not requested. Also logs checklist popover container-state changes (DEBUG) for lifecycle forensics. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Consume pending add-field activation when the checklist popover closes Review finding (Greptile P1 / Cursor): dismissing the first-item popover without committing (Escape, click-away, app deactivation, workspace switch) cleared checklistPopoverWorkspaceId but left the add-field activation token set, leaving the workspace in stale "add requested" state and keeping the empty section mounted invisibly. Any false write through the popover-presented binding now also consumes the activation, and the workspace-switch dismissal path clears the dismissed workspace's token directly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Run the popover's window-wide pre-show layout only on hidden-to-shown Review finding (Codex P1): present() re-enters on every parent update tick while the popover is shown, and the root layoutSubtreeIfNeeded() added for same-transaction first presents ran before the isShown guard — synchronously flushing the entire main window's layout on every checklist/title/status change while any todo popover was open. The root layout, identity bump, and initial sizing now all sit behind the isShown guard; shown-popover content and size updates flow through update(model:) -> refreshContent() as before. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address review: keep popover host mounted, hit-test pass-through, coalesced hover Three review findings on the checklist popover: - The empty-section mount condition now includes the popover-presented state: unmounting on token consumption dismantled the popover's anchor mid-presentation, so Return on an empty first-item draft or deleting the last item tore the popover down (and the first add could race the snapshot refresh). - PopoverPointerTracker's view returns nil from hitTest: tracking areas fire from geometry alone, and the full-size background view must never win clicks over the SwiftUI controls it sits behind. - Pointer location now lives in a reference box mutated per mouse event; SwiftUI state (hoveredItemId) is written only when the hovered row actually changes, so per-pixel mouse movement no longer rebuilds every popover row. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com> * Reconcile Swift file-length budget after merging main Union of both sides' entries kept stale pre-merge numbers; ratchet each flagged entry to the merged tree's actual length and track the two files the merge pushed over the 500-line threshold. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Fit todos-restore growth inside the Swift file-length hard cap The file-length gate forbids any net growth in >900-line files and any file newly crossing the 500-line threshold. The restore's additions to seven such files are irreducible call-site/persistence code, so offset them by folding this branch's own added blocks into the files' existing dense style and tightening verbose doc comments (content and links preserved). Pure line folds; no behavior, ordering, or declaration changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Deduplicate SidebarWorkspaceRowInteractionStateTests after merge The branch had extracted the suite to its own file while main updated the in-file copy (hover-lifecycle hang fix removed tests asserting the old force-publish behavior). Keep the branch's file layout with main's current suite content, one definition total; the sharding guard fails on duplicate selector identifiers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Fix missing newline at test-suite splice Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com>
* test: guard sidebar workspace rows against status circle glyphs Red commit: asserts the sidebar row rendering sources reference no task-status circle glyph (SidebarWorkspaceTaskStatusGlyph/Control, the row-anchored status popover wiring, and the glyph-only snapshot fields). Fails on current main where PR #7790's feature restore resurfaced the circles on pre-existing workspaces; the follow-up commit removes them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Remove status circle glyphs from sidebar workspace rows Sidebar workspace rows no longer render the leading task-status circle (empty = Todo, half-filled = Working/Needs Attention). The circles shipped with workspaces-as-todos (#7216), were removed by the full revert (#7761, 657248a), and came back with the feature restore (#7790, 998e7fb): statusHidden only defaults true for NEW workspaces, so every pre-existing persisted workspace restored to visible/Auto and the circles reappeared on all old rows. PR #7901 is exonerated — its diff never touches the status glyph code. Surgical removal of the row indicator only: - Drop the SidebarWorkspaceTaskStatusGlyphControl block from the row title line in ContentView.swift, its fixed-width slot, and the row-anchored status popover state (statusPopoverWorkspaceId, isStatusPopoverPresented, onStatusPopoverPresentedChange, Equatable). - Drop the glyph-only snapshot fields (taskStatusHasOverride, taskStatusInferred) from SidebarWorkspaceSnapshotBuilder and the context-menu refresh policy; taskStatus stays for the done-row dim. - Delete the now-dead SidebarWorkspaceTaskStatusGlyphControl and the unused WorkspaceTodoActions.toggleDone (glyph option-click). The status feature itself is untouched: context-menu Status submenu, command palette, CLI, shortcuts, checklist, and the todo pane (which keeps its header glyph and status popover) all still work. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Normalize project.pbxproj test wiring order Run scripts/normalize-pbxproj.py so the SidebarWorkspaceRowStatusGlyphRemovalTests pbxproj entries sit in sorted position; fixes the workflow-guard-tests normalization check (linux-preflight fails only downstream of it). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Reverts #7216. The status glyph becomes visible in the sidebar as soon as any agent or CLI touches the todo verbs (the sidebar.workspaceTodos setting auto-enables on first use), so agent-created workspaces show a completion pie to the user from the start. Reverting to unblock while the feature is reworked to default the status UI to none from creation.
🤖 Generated with Claude Code
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Note
Medium Risk
Large feature removal across CLI, automation socket, and shared packages; scripts or agents calling removed verbs will break until the feature is reintroduced with new defaults.
Overview
This reverts the workspaces-as-todos feature so agent-created workspaces no longer surface a status glyph when todo APIs are used.
CLI: Deletes
CLI/CMUXCLI+WorkspaceTodo.swiftand drops the top-levelcmux todocommand,cmux workspace status, and their help/suggestion entries; workspace usage text no longer mentions status.Control socket: Removes the entire
WorkspaceTodocoordinator domain (workspace.status.*,workspace.todo.*),ControlWorkspaceTodoContextfrom the umbrella protocol, dispatch inControlCommandCoordinator, anddebug.workspace_todo.checklist_add_field.Settings & shortcuts: Removes checklist-style beta setting,
WorkspaceTodoChecklistStyle, and shortcuts for mark-done, cycle status, and toggle checklist completion.CmuxWorkspaces: Deletes checklist/task-status value types,
SurfaceKind.todo, and associated unit tests.CI: Adjusts
.github/swift-file-length-budget.tsvafter the deletions.Reviewed by Cursor Bugbot for commit 70e8cee. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Reverts the “workspaces as todos” feature to remove inferred status and per-workspace checklists. Restores prior behavior and prevents showing a status glyph on agent-created workspaces.
Migration
cmux todo ...andcmux workspace status ....workspace.status.*,workspace.todo.*, andworkspace.todo.open.workspaceTodopanel type andSurfaceKind.todo.sidebar.beta.workspaceTodos.checklistStyleand related settings/search entries.CmuxWorkspaces; removed the todo coordinator and context fromCmuxControlSocket.debug.workspace_todo.checklist_add_field.Refactors
cmux.xcodeproj(KeyboardShortcutSettingsFileStore+SectionParsers.swift,KeyboardShortcutSettings+SystemWideHotkeyConflicts.swift).Written for commit 70e8cee. Summary will update on new commits.
Summary by CodeRabbit
Removed Features
workspace statusandtodoCLI commands are no longer available.Improvements
Documentation