Skip to content

feat(finder): ship native Send to Sorting Hat Quick Action#27

Merged
tcballard merged 5 commits into
mainfrom
codex/issue-26-native-finder-action
Jul 19, 2026
Merged

feat(finder): ship native Send to Sorting Hat Quick Action#27
tcballard merged 5 commits into
mainfrom
codex/issue-26-native-finder-action

Conversation

@tcballard

Copy link
Copy Markdown
Owner

Closes #26

What changed

  • Adds a first-party, non-UI Finder Action Extension named Send to Sorting Hat.
  • Shares one lossless import service between Finder and the in-app Add Files flow.
  • Stages selections into a persistent App Group queue with atomic manifests, crash recovery, quarantine, receipts, retry/remove recovery, and exactly-once delivery.
  • Keeps intake active while sorting is paused and drains staged files when the app next launches.
  • Adds Finder integration status, Inbox bookmark repair, queue/failure recovery, and reversible legacy Automator migration in Settings.
  • Adds a generated Xcode project, nested signing, entitlement audits, CI/release packaging, and migration/architecture documentation.

Product contract

Finder is intake-only. The extension copies regular files and never renames, moves, deletes, sorts, or uploads the originals. Sorting and review remain inside Sorting Hat.

The Action accepts up to 256 files, 256 MB per file, 1 GB per request, with a 25-second extension deadline. Partial failures name unfinished files while preserving already staged successes. Directory-only selections may be suppressed by Finder before invocation; Add Files remains the path for folders or larger files.

No Full Disk Access is requested. The extension is sandboxed, receives read-only user-selected access, and shares only the App Group queue with the main app. The configured Inbox bookmark remains private to the app.

Installed Finder verification

Verified against the signed app installed at /Applications/Sorting Hat.app:

  • PlugInKit registered and enabled exactly one native Send to Sorting Hat Quick Action.
  • Paused app: sent a two-file selection containing spaces and Unicode. Sorting Hat reported two Finder imports, both remained visible in Inbox while paused, and source/Inbox SHA-256 values matched byte-for-byte.
  • Running app: sent a separate fixture while the app was active. It was imported, renamed, filed, and the final output hash matched the untouched source.
  • Closed app: quit Sorting Hat, invoked the same fixture twice, confirmed the app remained closed, then relaunched. Two durable imports appeared as collision-safe Inbox names (original and -2); both hashes matched the source and both were subsequently filed.
  • Settings recorded the current-build delivery receipt and valid Inbox access.
  • The old Automator workflow is preserved under Application Support with Restore Legacy Action available; Finder exposed no duplicate legacy menu item.

A pre-existing downstream output filename from earlier verification caused one visible, recoverable filing-collision history entry; the Inbox queue still delivered both payloads exactly once, and both files were ultimately filed without loss.

File Provider/security-scoped loading is implemented through NSItemProvider and covered structurally, but no personal cloud fixture was uploaded for this manual pass.

Verification

  • Full Swift suite: 59 tests passed, 0 failures.
  • Project generation run twice with no drift; project hash:
    1c55da2dd41e28569d693253a3bb54ff14dbf4e19683aa0f9f2d38b56f47bd56
  • Shell syntax, project.yml, CI YAML, release YAML, and git diff checks passed.
  • Final signed build/install verification passed:
    SORTING_HAT_DERIVED_DATA=/private/tmp/SortingHatFinderFinalHEADDerived BUILD_CONFIGURATION=Debug ./script/build_and_run.sh verify
  • App and extension both satisfy their designated requirements.
  • App/extension share App Group R8HXTBY3NM.com.tcballard.sortinghat.
  • Extension entitlements verify sandbox=true and user-selected read-only=true.
  • Exact CI-style entitlement extraction was reproduced against an ad-hoc signed copy and validated with PlistBuddy.

Review order

  1. Package.swift, InboxImportService, InboxImportQueue, and queue-locking tests.
  2. FinderItemProviderAdapter and ActionRequestHandler.
  3. project.yml, generated Xcode project, entitlements, signing, CI, and release workflow.
  4. HatStore and Settings recovery/migration UI.
  5. README and docs/finder-quick-action.md.

Deferred

Developer ID notarization/release execution remains tracked separately in #24. This PR is ready for review and should not be merged automatically.

@tcballard
tcballard merged commit 5dc6eba into main Jul 19, 2026
1 check passed
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.

feat(finder): ship native Send to Sorting Hat Quick Action

1 participant