Smarter Foreman repo list: sections, favorites, and animated moves#59
Merged
Conversation
Collapse ForemanConfiguration's parallel enabledRepoIDs/repoOptions into a single RepoConfiguration record per RepoID (isEnabled, isFavorite, options), dropping the old on-disk format (Foreman has no users yet). Add a persisted, worker-free Repo.isFavorite, and RepoSection — the pure, tested enabled/ disabled sectioning rule that floats favorites to the top of each section. Co-authored-by: Cursor <cursoragent@cursor.com>
Render session.repoSections as Enabled/Disabled sections in the sidebar, show a star on favorited rows with a right-click Add/Remove Favorite context menu, and add a star toggle to the worker detail view's toolbar. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Attach .animation(.snappy, value:) to the sidebar List keyed on the flattened row order, so a repo tweens as it moves between the Enabled/Disabled sections or floats within a section on favorite — regardless of what triggered it. Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the sidebar's SwiftUI Sections with a single flat ForEach of headers and rows sharing one identity space, so a repo moving between the Enabled and Disabled groups animates as one glide rather than a cross-container remove/insert. Group headers render inline and are selection-disabled; the .animation is keyed on the flattened row identities. Co-authored-by: Cursor <cursoragent@cursor.com>
- Correct the RepoSection doc (the app renders group headers in a flat list, not SwiftUI Sections). - Build the persisted record directly from the repo in repoDidChange instead of reading-then-overwriting the existing entry. - Cover that disabling a favorited repo keeps its entry with isFavorite set. Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve AGENTS conflicts in favor of main's slimmed module-shape docs: main reduced every AGENTS.md to terse invariants (per-type detail now lives in each module's README.md), so the verbose Key-types/invariants additions from this branch are dropped. The RepoConfiguration / isFavorite / RepoSection detail is already carried by ForemanCore/README.md; folded the new sidebar sections + favoriting affordances into Foreman's app README so that user-facing behavior stays documented. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes the Foreman sidebar "smarter" and restructures how per-repo state is persisted.
RepoSection.sections(from:)) inForemanCore; the view only renders it.Repo.isFavorite, toggled from a right-click context menu on the sidebar row (with a star glyph on favorited rows) and a star button in the detail view's toolbar.ForemanConfiguration's parallelenabledRepoIDs+repoOptionsinto a singleRepoConfiguration(isEnabled,isFavorite,options) keyed byRepoID, so the flags and options can't drift apart. This is a breaking change to the on-disk JSON — intentional, as Foreman has no users yet (no migration / custom decoder). A repo left atRepoConfiguration.standardhas no entry, so the file stays free of no-op records.ForEachof headers + rows (one identity space) rather than SwiftUISections, so a repo glides across the group boundary when toggled (instead of a cross-container remove/insert)..animation(.snappy, value:)keyed on the flattened row identities tweens every reorder (toggle, favorite, rescan).Test plan
./swiftformat --linttuist test Foreman-macOS-Tests --no-selective-testing -- -destination 'platform=macOS'(app target builds; all suites pass)ForemanCorecoverage:RepoSectionTests— enabled/disabled partition, favorites float to the top of each section, empty sections omitted, alphabetical order otherwise preserved.WorkerConfigStoreTests— save/load round-trip incl.isFavorite,configuration(for:)defaults to.standard, prune drops stale per-repo entries only under the scan directory.RepoTests—isFavoritepersists, same-value is a no-op, and it never starts/stops the worker.ForemanServicesTests— favoriting writes through to the saved record and a saved favorite is restored on launch.Made with Cursor