Skip to content

macOS parity: every Windows page on the Mac, plus signing, iCloud and native menus - #1

Merged
gjnail merged 2 commits into
mainfrom
macos-parity
Oct 1, 2026
Merged

gjnail merged 2 commits into
mainfrom
macos-parity

Conversation

@nathandavismail-cmyk

Copy link
Copy Markdown
Collaborator

Every page Heft has on Windows now has a Mac counterpart, and this PR adds the 21-item macOS follow-up list on top: signing, iCloud, leftovers of deleted apps, native menus, Settings and more. It's large (91 files, about +20.9k / −0.7k lines, 15.5k of them in new files), so there's a suggested reading order below.

Before the next release: the code builds and the tests pass, but the hand tests in docs/testing-macos.md haven't been run yet. Merging doesn't ship anything by itself, and signing stays off until the Apple secrets are set. See "What's left before a release".

What's in it

New Mac pages (the counterparts of the Windows tools)

Page Windows counterpart Where
Hardware monitor: temperatures, loads, clocks and power for P/E cores, GPU, Neural Engine and memory, plus fans, SSD wear, network and battery. No administrator password needed. heft --sensors works, and --report dumps raw SMC/HID data for Macs that haven't been tested Hardware src/sensors/mac/
Login items: login items, launch agents and daemons, turned off with launchd's own switch (launchctl disable), removed with a backup, and who signed each one. Show all background items lists what sfltool dumpbtm reports Startup src/mac/startup.rs, src/app/tools/startup_mac.rs
Apps: measured sizes, publisher, date added and last opened. Uninstalls through the app's own uninstaller, Homebrew or the Trash, then scans for leftovers (and stops their launch agents and daemons). Leftovers of deleted apps finds files by bundle id only, with nothing ticked by default. Updates come from Homebrew and mas; Sparkle feeds are only checked when turned on in Settings Programs src/mac/apps.rs, src/mac/apps/{brew,updaters,orphans}.rs, src/app/tools/programs_mac.rs
Broken items: launch agents, login items, Dock icons, command-line links, Open With entries and package receipts that point at things that no longer exist. Every change is backed up and can be restored Registry check src/mac/broken.rs, src/app/tools/broken_mac.rs

Mac integration

  • Menu bar icon: free space alerts keep running after the window closes, with an optional Start at login launch agent. Alerts go through Notification Center when Heft runs as Heft.app, and heft --tray starts hidden. See src/mac/menubar.rs and src/mac/notify.rs.
  • Native menus (Heft, File, View, Window and Help with the usual shortcuts, ⌘1–⌘6 for pages) and a Settings window on ⌘,. See src/mac/appmenu.rs and src/app/settings_view.rs.
  • FSEvents quick rescans: Rescan only re-lists the folders that changed, and View › Update automatically reacts as soon as macOS reports a change. This also roughly halves memory use after a whole-disk scan. See src/scan/fsevents.rs and src/scan/walk/update.rs.
  • Trash: Heft now moves items to the Trash itself instead of going through the trash crate or Finder, so it no longer needs Finder automation permission. Finder's Put Back is available as a Settings option, and the Removed tab restores items either way.
  • iCloud Remove download in the right-click menu and in Suggestions. It only touches files iCloud has finished syncing. See src/mac/icloud.rs and src/app/icloud_view.rs.
  • Compress / Uncompress on APFS and HFS+. Apps installed for all users can be included after the administrator prompt, and each file is checked against the original before it's swapped in. See src/compress.rs.
  • Purgeable space on the start screen and in the status bar, so Heft's free space agrees with Finder's. There's also a Full Disk Access note with a button that opens the right settings page.

Cleaner and suggestions

  • src/clean/mac.rs plus new rules: temporary files, Quick Look thumbnails, Metal shader caches, iPhone/iPad updates, system logs (administrator), Docker build cache, and privacy rules (recent items, clipboard, DNS cache). Safari's rules only appear with Full Disk Access. Caches for Teams, Epic, Java, Adobe, NuGet, Deno and Composer are also covered, and weekly cleaning runs through a launch agent.
  • Cookie and history rules for Chromium browsers and Firefox now work on macOS and Linux too.
  • Open files are skipped on macOS and Linux. Each clean asks for the password once (pkexec on Linux, the administrator prompt on macOS).
  • New suggestions: old macOS installers, iPhone/iPad backups and software downloads, Time Machine local snapshots, Docker's disk, Xcode archives and more. Anything that carries a warning is no longer pre-selected.

On every platform

  • A light/dark toggle in the top-right corner (src/app/theme_toggle.rs).
  • Fix: a Unity project's Library folder was flagged as the Mac's Library folder.

Release and packaging

  • release.yml: Developer ID signing and notarization. Both stay off until the APPLE_TEAM_ID variable and the related secrets are set. The release notes now describe Windows and macOS signing separately.
  • packaging/macos/heft.entitlements (hardened runtime plus Apple Events), and bundle-macos.sh accepts HEFT_SIGN_IDENTITY.
  • scripts/homebrew-cask.sh writes heft.rb, which is uploaded as the homebrew-cask artifact.
  • The bug report template has the new areas and a field for the sensor report.

Docs

README, CONTRIBUTING and CHANGELOG (Unreleased) are updated. docs/releasing.md covers setting up signing and Homebrew, and the new docs/testing-macos.md is the hand-test checklist. The website guides are updated, with a new site/guides/mac-tools.html.

What's left before a release

  1. Hand testing. Nothing in docs/testing-macos.md has been ticked yet. The automated tests cover parsing and planning, but not anything behind the administrator prompt or anything that changes login items, the Dock, Finder, iCloud, notifications or launch agents. The checklist only uses throwaway items.
  2. Signing. This needs an Apple Developer Program membership and the secrets and variables listed in docs/releasing.md › Signing and notarizing for macOS. Setting APPLE_TEAM_ID turns it on.
  3. Homebrew tap. Once a release is out, create gjnail/homebrew-heft using the cask from the release run.
  4. Other Macs. Everything was developed and run on one Apple silicon Mac. Sensor readings on Intel Macs and other chips are untested, and heft --sensors --report is there to help fix them.

Suggested reading order

  1. src/mac/mod.rs: shared helpers (property lists, launchd, the administrator prompt, backups) that the other Mac modules build on.
  2. src/platform/unix.rs: the Trash, the drive list and purgeable space.
  3. After that, each area stands on its own: Login items → Apps → Broken items, then src/sensors/mac/, then FSEvents (scan/fsevents.rs and scan/walk/update.rs together), then the cleaner (clean/mac.rs, clean/rules_unix.rs).

Testing

  • cargo test on macOS (Apple silicon): 186 passed, 5 ignored. The ignored ones change real system state; run them with cargo test -- --ignored.
  • cargo check --all-targets passes for Windows and Linux.
  • CI runs on all three platforms for this PR.

🤖 Generated with Claude Code

…menus

Mac counterparts of every Windows page (Hardware, Login items, Apps,
Broken items), the menu bar icon and notifications, FSEvents quick
rescans, the macOS cleaner and suggestions, and the macOS follow-up
list: Developer ID signing and notarization (off until the Apple
secrets are set), iCloud Remove download, leftovers of deleted apps,
native menus and Settings. See CHANGELOG.md and docs/testing-macos.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GitHub's Ubuntu runners make /usr/share writable for everyone, so
root_may_remove rightly refuses it there. Check the folders' owner and
mode before expecting it to allow a path under them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gjnail
gjnail merged commit 0c8e0f0 into main Oct 1, 2026
10 checks passed
@nathandavismail-cmyk nathandavismail-cmyk mentioned this pull request Oct 1, 2026
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.

2 participants