Skip to content

feat: Plugoff & PluginHub parity — categories, duplicates, Rosetta banner, insights, offloading - #24

Open
bounceconnection wants to merge 7 commits into
devfrom
feature/catalog-offload
Open

bounceconnection wants to merge 7 commits into
devfrom
feature/catalog-offload

Conversation

@bounceconnection

Copy link
Copy Markdown
Owner

Stacked on #23 (scan-performance). Merge after #23, or I'll retarget this to dev once #23 lands. Everything here builds on the perf branch's BundleSizeService.

What this adds

Plugoff-style catalog & cleanup

  • Categories — every plugin is classified (Synth, EQ, Reverb, Dynamics, …) during the scan via a bundled 477-entry mapping + heuristics. New Categories sidebar section filters the library, with per-category counts.
  • Duplicates — a Cleanup ▸ Duplicates filter surfaces the same plugin installed across multiple formats, or in both system and user folders.
  • Insights — a toolbar chart button opens an Insights sheet: overview tiles (plugins, manufacturers, total size) + Swift Charts breakdowns by format, category, and top manufacturers.
  • Offloading — right-click Offload to Reclaim Space (with confirmation) moves bundles to ~/PluginventoryOffload; a Storage ▸ Offloaded (N) · X saved sidebar entry lists them with one-click Restore.

PluginHub-style update UX

  • macOS 28 / Rosetta warning banner — a prominent banner counts Intel-only / legacy plugins that stop working when Apple removes Rosetta, plus a Compatibility ▸ Won't run in macOS 28 filter.

Architecture

Pure, deterministic, fully-tested logic layers (DuplicateDetector, ArchitectureCompatibility, InsightsData, PluginCategoryClassifier, OffloadManager) with thin SwiftUI/SwiftData wiring on top. Plugin gains a persisted category; a new OffloadedPlugin model tracks moved bundles.

Testing

369 tests pass locally (swift test, macOS, Xcode 26.6); build clean; SwiftLint clean on changed files. New suites: DuplicateDetector, ArchitectureCompatibility, InsightsData, OffloadedPlugin, plus reconciler category coverage.

⚠️ Offloading moves real files. It's built defensively (moves rather than deletes, refuses to overwrite anything, restore is verified by tests), but please try it on a throwaway plugin first before trusting it with your library.

Not included (possible follow-ups)

Manufacturer sidebar filter, PDF export (CSV export already exists), PluginHub-style vendor grouping + version-diff arch chips, and duplicate "resolve" actions.

🤖 Generated with Claude Code

bounceconnection and others added 6 commits August 19, 2026 14:34
…ends

Two self-contained building blocks for the Plugoff-style features, each
with tests (345 tests pass total):

- PluginCategory + PluginCategoryClassifier: classifies plugins into
  functional categories (Synth, EQ, Dynamics, Reverb, ...) via a bundled
  plugin_categories.json (95 vendor/prefix rules) plus a name-keyword
  heuristic fallback. Resolution: longest bundle-id prefix > exact vendor
  > name keyword > heuristic > uncategorized.
- OffloadManager (actor) + OffloadRecord: moves plugin bundles to an
  offload folder to reclaim disk and restores them, with collision-safe
  path handling and size measured before the move.

UI/model integration follows in subsequent commits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pure, tested logic layers for the competitor-parity features:

- DuplicateDetector: cross-format duplicates (same plugin in VST3/AU/…)
  and location duplicates (same bundle+format in system & user folders),
  mirroring Plugoff's duplicate filter.
- ArchitectureCompatibility + RosettaSunsetSummary: flags Intel-only /
  legacy plugins that stop working when macOS 28 removes Rosetta, for the
  PluginHub-style warning banner.
- InsightsData: aggregates counts by format, category, and manufacturer
  plus totals, backing a Plugoff-style Insights view.

All pure value types, Sendable, deterministic. 21 new tests; suite now 366.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Plugin gains a `category` (persisted via categoryRaw, default uncategorized).
PluginReconciler runs PluginCategoryClassifier on insert and update so every
scanned plugin is categorized (Synth, EQ, Reverb, …). Adds a reconciler test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds visible competitor-parity features to the dashboard:
- Categories sidebar section — filter the library by functional category
  (Synth, EQ, Reverb, …), with per-category counts (Plugoff-style).
- Cleanup > Duplicates filter — surfaces plugins installed in multiple
  formats or in both system and user folders (Plugoff-style).
- Compatibility > "Won't run in macOS 28" filter and a prominent red
  warning banner counting Intel-only / legacy plugins that break when
  Apple removes Rosetta (PluginHub-style).

All computed from the tested DuplicateDetector / ArchitectureCompatibility
layers. Suite: 367 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a Plugoff-style Insights sheet (toolbar chart button) built on the
tested InsightsData layer: overview tiles (plugins, manufacturers, total
size) plus Swift Charts bar breakdowns by format, category, and top
manufacturers, over currently-visible plugins.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wires the tested OffloadManager into the app (Plugoff-style offloading):
- New OffloadedPlugin @model persists what was moved + where from.
- AppState.offloadPlugins moves bundles to ~/PluginventoryOffload and
  drops them from the active list; restoreOffloaded moves them back and
  rescans. Failures are surfaced, never silent; nothing is clobbered.
- Dashboard: right-click "Offload to Reclaim Space" (with a confirmation),
  a "Storage ▸ Offloaded (N) · X saved" sidebar entry, and a restore list.

Adds an offload↔restore round-trip integration test. Suite: 369 tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@bounceconnection
bounceconnection changed the base branch from feature/scan-performance to dev August 19, 2026 22:06
…imeout

The dashboard table was one ~230-line expression (Table + 12 modifiers).
Xcode 26.6 type-checks it fine, but the CI runner's older Xcode hit
"unable to type-check this expression in reasonable time". Extracted the
table, context menu, overlay, banner, footer, toolbar, dialog actions,
inspector, and search handler into small helpers so no single expression
is large. No behavior change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant