Repository navigation
Issue #3931: Add goal supervision sidebar UI - #3961
austinywang wants to merge 35 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR implements a native Goals supervision panel as a new right-sidebar mode in cmux, enabling long-running multi-day objectives with persistent storage, lifecycle metrics, and note-keeping. It adds domain models (status, notes, records, snapshots), a JSON-backed observable store with merge-conflict resolution, a complete UI flow (list/detail/new-goal popover), command-palette integration, CLI support, and comprehensive test coverage. ChangesGoals Panel Feature
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 14 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (14 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
Greptile SummaryThis PR adds a Goals supervision panel to the right sidebar, wiring a new
Confidence Score: 5/5Safe to merge — all blocking-I/O, actor-isolation, stale-UI, and error-message issues surfaced in prior rounds have been addressed; the new code is well-structured and consistent with existing sidebar patterns. Every area previously flagged (synchronous I/O on the main actor, ObservableObject broad invalidation, 785-line monolith, stale metrics tiles, stale list-row timestamps, raw Foundation error strings) is resolved in the current revision. The persistence pipeline correctly keeps blocking disk work on a dedicated serial DispatchQueue via a checked-continuation bridge, the actor boundary is clean, and the SwiftUI state model uses @observable with fine-grained tracking. No new actor-isolation mistakes, blocking primitives, or missing locale entries were found. No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant UI as GoalSupervisionPanelView<br/>(@MainActor)
participant Store as GoalSupervisionStore<br/>(@MainActor @Observable)
participant Persist as GoalSupervisionPersistence<br/>(actor)
participant FileIO as GoalSupervisionFileIO<br/>(DispatchQueue)
participant Disk as goals.json
UI->>Store: init (first access of .shared)
Store->>Store: "loadTask = Task { await load() }"
Store->>Persist: await persistence.load()
Persist->>FileIO: await loadData(from: fileURL)
FileIO->>Disk: Data(contentsOf:) [blocking, off coop executor]
Disk-->>FileIO: Data?
FileIO-->>Persist: Data?
Persist->>Persist: decoder.decode(...)
Persist-->>Store: [GoalSupervisionRecord]
Store->>Store: "goals = sorted(loaded)"
Store-->>UI: "@Observable invalidates body"
UI->>Store: createGoal(title:...)
Store->>Store: goals.insert / sortGoals / recordMutation
Store->>Store: "persistTask = Task { await persistence.save(...) }"
Store-->>UI: goals updated → body re-renders
Store->>Persist: await persistence.save(snapshot)
Persist->>FileIO: await saveData(data, to: fileURL)
FileIO->>Disk: data.write(atomic) [blocking, off coop executor]
Disk-->>FileIO: ok
FileIO-->>Persist: ok
Persist-->>Store: ok
Store->>Store: [MainActor] clear lastError / deletedGoalIDs
Reviews (25): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@Sources/GoalSupervisionPanelView.swift`:
- Around line 163-170: The update currently always updates updatedAt / re-sorts
/ persists even when the mutation closure is a no-op (e.g. in
updateStatus(for:id:) where guard goal.status != status returns), causing
spurious recency/activity changes; change updateGoal(id: _ , ...) so the
mutation closure returns a Bool indicating whether it mutated the goal (or have
updateGoal return Bool), then in updateStatus(for:id:) (and the similar block
covering lines ~189-205) only set goal.updatedAt, re-sort, and persist when that
Bool is true; reference the updateGoal(id:), updateStatus(for:id:), and the
other status/mutation closure blocks so you only update timestamps and save when
a real change occurred.
- Around line 4-785: This file mixes domain models, persistence/store logic, and
many SwiftUI views into one large file; split it into focused files: move the
model types (GoalSupervisionStatus, GoalSupervisionNote, GoalSupervisionRecord,
GoalSupervisionSnapshot and their helpers like normalized/normalizedOptional)
into a Models file, move GoalSupervisionStore (keeping `@MainActor`, static
shared, fileURL logic, load/persist and helper methods) into a Store file, and
move GoalSupervisionPanelView and all its view subcomponents (GoalEmptyView,
GoalListView, GoalListRow, GoalDetailView, MetricTile, StatusChip,
NewGoalPopover) into one or more View files; preserve access control, keep
formatters and static helpers near the views that use them (or extract shared
formatters into a small Utilities file), update imports/usages so types like
GoalSupervisionSnapshot and GoalSupervisionStore are referenced from the new
files, and run a build to ensure no symbol or attribute (e.g., `@MainActor`,
`@StateObject`, .shared) was lost during the move.
🪄 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: 0b47b8ad-ac53-4ad8-a820-24a764ffecff
📒 Files selected for processing (7)
GhosttyTabs.xcodeproj/project.pbxprojResources/Localizable.xcstringsSources/ContentView+RightSidebarCommandPalette.swiftSources/GoalSupervisionPanelView.swiftSources/MainWindowFocusController.swiftSources/RightSidebarMode+Availability.swiftSources/RightSidebarPanelView.swift
Dismissed stale CodeRabbit changes-requested review from commit a3c465a after addressing its findings in later commits, resolving all review threads, and receiving a passing CodeRabbit status on the current head.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@Sources/GoalSupervisionStore.swift`:
- Around line 200-210: The persistCurrentGoals() flow can persist a stale
snapshot because persistTask?.cancel() only marks the prior Task cancelled;
update persistCurrentGoals() so the Task cooperatively checks cancellation
before saving: inside the Task block, call try Task.checkCancellation() (or
Task.checkCancellation()) immediately before awaiting
persistence.save(snapshot), and add a catch branch for CancellationError that
returns early without calling persistence.save or updating lastError; keep the
existing catch for other errors to set lastError = error.localizedDescription;
reference persistCurrentGoals(), persistTask, persistence.save(_:), and
lastError when making the change.
🪄 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: 78e47d1c-28fe-42e1-9141-37f867daac00
📒 Files selected for processing (7)
GhosttyTabs.xcodeproj/project.pbxprojSources/GoalSupervisionDetailView.swiftSources/GoalSupervisionModels.swiftSources/GoalSupervisionNewGoalView.swiftSources/GoalSupervisionPanelView.swiftSources/GoalSupervisionStore.swiftSources/RightSidebarPanelView.swift
|
Verified the CodeRabbit persistence-cancellation finding against current HEAD. |
Obsolete automated review on an older commit. The requested persistence cancellation guard is present at current HEAD: persistCurrentGoals() checks cancellation before and after persistence.save(snapshot) and exits on CancellationError without updating lastError.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a19e408. Configure here.

Summary
Implementation proposal
This PR intentionally starts with the native supervision surface and local goal lifecycle record rather than attempting the full multi-day orchestration backend in one change. The next durable steps are:
Validation
jq empty Resources/Localizable.xcstringsgit diff --checkCloses #3931
Note
Medium Risk
Adds a new right-sidebar mode with local persistence and async file I/O, touching sidebar mode routing, focus behavior, and CLI/remote command parsing. Risk is moderate due to new state/persistence paths and UI interactions, though changes are scoped and covered by new tests.
Overview
Adds a new Goals mode to the right sidebar, including list/detail UI for creating goals, changing status, adding notes, viewing simple time/updated metrics, and deleting with confirmation, backed by a new
GoalSupervisionStorethat persists toApplication Support/cmux/goals.json.Wires
goalsinto right-sidebar mode selection, availability, focus handling, command palette entries/titles, andcmux right-sidebar+ remote socket commands/usage strings; also ensures Goals is treated as a non-pane mode (no tool-pane/open-as-pane support). Updates localization strings and expands/adjusts test coverage for CLI forwarding, mode parsing, command palette contributions, pane rejection, and goal store persistence/error handling.Reviewed by Cursor Bugbot for commit a29424f. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Adds a Goals mode to the right sidebar, command palette, and CLI/remote so you can create, view, and track goals with status, notes, and live metrics, persisted to
Application Support/cmux/goals.json. Async file I/O runs on a background queue to keep the UI responsive and completes #3931.New Features
cmux right-sidebarand socket aliases acceptgoals; localized EN/JA strings.Bug Fixes
goals(EN/JA).Written for commit a29424f. Summary will update on new commits. Review in cubic
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes