fix: register PureMac with TCC so Full Disk Access works (#75) + dashboard redesign#80
Open
ceorkm wants to merge 2 commits intomomenbasel:mainfrom
Open
fix: register PureMac with TCC so Full Disk Access works (#75) + dashboard redesign#80ceorkm wants to merge 2 commits intomomenbasel:mainfrom
ceorkm wants to merge 2 commits intomomenbasel:mainfrom
Conversation
added 2 commits
April 29, 2026 04:28
The uninstaller delegated file deletions to Finder via NSAppleScript,
which meant Finder made the TCC-gated syscalls — not PureMac. macOS
only adds an app to the Full Disk Access list once that app itself
hits a protected path, so granting FDA to PureMac had no effect.
Replaced trashViaFinder with FileManager.trashItem, and added a
launch-time triggerRegistration() that performs real reads on protected
paths so the bundle gets registered on first run. Onboarding now walks
the user through Settings step-by-step with reveal-in-Finder and
tccutil reset helpers for the Homebrew-quarantine and stale-bundle
cases that surfaced in the issue thread.
Cleaning fixes that surfaced while debugging the same issue:
- extend isSafeToDelete allow-list with dev caches (Xcode/DerivedData,
~/.npm, ~/.cache, Docker container) and the symlink-resolved forms
of /private/var/log and /private/var/tmp
- accept whole-root paths so Xcode/Brew/Node scanners that emit at
the root no longer get silently skipped
- track cleanedPaths so the UI removes only items that actually got
deleted instead of wiping the list and pretending success
- escalate EACCES failures to a single admin-privileged xargs/rm
pass via NSAppleScript "with administrator privileges"; one auth
prompt covers the whole batch
- surface a real failure alert with paths logged for diagnosis
Also fixes the size display bug noted in the comments: directories
were rendering as 0 B because attributesOfItem(.size) returns the
directory metadata size, not its contents. Now uses
totalFileAllocatedSizeKey in AppFilesView and OrphanListView.
Removed the 5,000-entry cap from scanLargeFiles — with hundreds of
thousands of files in Downloads/Documents/Desktop, the scan never
reached anything actually large.
Info.plist gains the per-folder usage description keys
(NSDesktopFolderUsageDescription etc.) so the OS surfaces consent
prompts that register PureMac in the relevant TCC panes.
Replaces the old Smart Scan landing with a storage-led dashboard:
- circular gauge showing % of disk used; gradient turns orange/red
once usage crosses 85%
- free-space hero numerals with a stacked usage bar (used / junk /
purgeable) and a legend
- four stat tiles (Free Space, Junk Found, Apps, Purgeable)
- contextual suggestion cards — surfaces the largest pending category
and an FDA nudge when access is missing; nothing is shown when
there are no real suggestions
- same surface for scanning/completed/cleaning/cleaned states with
an animated rotating gauge during scans
Sidebar gets tinted icon tiles per row, capsule size badges per
category, and a persistent system-health footer that turns orange
when FDA isn't granted. Category detail pages get a hero card on
top showing the tinted icon, description, item count + size, and
the rescan action.
The flat orange FDA bar is replaced with a gradient toast card that
matches the dashboard surfaces. Toolbar gets a 3-segment appearance
pill (system / light / dark) with an animated indicator that slides
between segments — backed by a ThemeManager whose preference lives
in AppStorage so it persists.
docs/ui-prototype/{old,new}.html are clickable HTML mockups of the
previous and proposed designs, included for design review.
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.
Closes #75 (and likely #78 — same root cause).
The bug
PureMac never appears in System Settings → Privacy & Security → Full Disk Access, even after a fresh install via Homebrew. Granting FDA manually with the
+button doesn't help — the uninstaller still fails with "files could not be removed."The reason is that the uninstaller delegated deletions to Finder via
NSAppleScript. macOS records the Finder process as the requester for those file syscalls, so PureMac itself never tripped TCC and never got registered in the FDA pane. Granting access to PureMac was a no-op because PureMac wasn't the process being blocked.What changed
Fixes
FileManager.trashItem, so the syscall originates from PureMac and TCC registers it.FullDiskAccessManager.triggerRegistration()invoked at launch, which performs real reads on a few protected paths (/Library/Application Support/com.apple.TCC/TCC.db,~/Library/Mail,~/Library/Safari/CloudTabs.db). Forces TCC registration on first run.tccutil reset SystemPolicyAllFiles com.puremac.appfor the stale-bundle case.FileHandle/contentsOfDirectoryreads instead ofisReadableFilemetadata calls, since metadata calls don't always trigger TCC.Info.plistgainsNSDesktopFolderUsageDescription,NSDocumentsFolderUsageDescription,NSDownloadsFolderUsageDescription,NSRemovableVolumesUsageDescription,NSSystemAdministrationUsageDescription,NSAppleEventsUsageDescriptionso the OS surfaces per-folder consent prompts.Cleaning fixes (surfaced while debugging)
isSafeToDeleteallow-list with the dev-cache roots scanners actually emit (~/Library/Developer/Xcode/DerivedData,Xcode/Archives,CoreSimulator/Caches,~/.npm,~/.cache,~/Library/Containers/com.docker.docker) and/var/log//var/tmp(the symlink-resolved forms of/private/var/...). System log/tmp deletion was silently failing the safety check before.isSafeToDeletenow accepts whole-root paths (path == root), not just paths inside roots. Xcode/Brew/Node scanners emit at the root, so they were getting silently skipped.CleaningResult.cleanedPathstracks what actually got deleted; the UI now removes only those items instead of wiping the list and pretending success.do shell script "xargs -0 /bin/rm -rf -- < <tempfile>" with administrator privileges. One auth prompt covers the whole batch. Paths are re-validated against the safety allow-list before escalation, passed via NUL-separated tempfile so quoting can't go wrong, and post-stat'd to confirm what disappeared.cleanErrornow surfaces a real failure dialog with paths logged toLogger, instead of fake-succeeding.Other fixes flagged in the issue comments
attributesOfItem(.size)returns the directory's metadata size, not its contents.AppFilesViewandOrphanListViewnow usetotalFileAllocatedSizeKey.depth > 5000 { break }cap fromscanLargeFilesthat bailed after 5,000 enumerated entries. With 600,000+ files in Downloads/Documents/Desktop, the scan never reached anything actually large.UI overhaul
ThemeManagerpersists the preference viaAppStorage.docs/ui-prototype/{old,new}.htmlare clickable HTML mockups of the previous and proposed designs, included for design review.Test plan
xcodebuild -project PureMac.xcodeproj -scheme PureMac build)~/.npm/_cacache)/Library/Caches/*,/private/var/log/*) trigger the admin auth prompt and get deleted via the privileged pass