All notable changes to PermissionPilot are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.2.0 - 2026-07-02
First release hardened by a real sandboxed consumer (integration-tested inside a sandboxed menu-bar app).
OnboardingPresenter.front()— deminiaturizes and re-fronts an already-presented wizard. Hosts that keep a weak presenter reference should call this instead ofNSApp.activate, which neither deminiaturizes nor reorders an existing window.PermissionManager.relaunchAvailable— false when the host has no way to relaunch itself (sandboxed +LSMultipleInstancesProhibited). ThePermissionsViewrelaunch banner now hides its "Quit & Reopen" button in that case (the banner copy already instructs a manual quit-and-reopen), instead of rendering a button that silently does nothing.- README visuals — an animated light/dark wizard-flow GIF (shown side by
side) and a theme-aware 16-permission board grid.
SnapshotModenow renders the board in both themes for regenerable assets. - Downloadable demo — universal, ad-hoc-signed installers attached to the
GitHub release so devs can evaluate without building: a
.pkg(recommended —Example/make-pkg.sh; the installed app opens clean, no per-launch prompt) and a.dmg(Example/make-dmg.sh). Neither is notarized; each needs a one-time GUI approval (right-click → Open / System Settings → Open Anyway). - Wizard customization via
OnboardingConfiguration:showsWelcomeStepandshowsDoneStepto omit the intro / "all set" screens (e.g. when the host has its own onboarding and wants only the permissions step), andcolorSchemeto pin light/dark (defaultnilfollows the system theme). - Localization. Every user-facing string now routes through the localization
system with stable keys and an English base; the SDK is fully translatable
(ships English only — add a
<lang>.lproj/Localizable.stringsper target to contribute a language). See CONTRIBUTING.md. - CI — GitHub Actions builds and tests on macOS for every push and PR.
CHANGELOG.mdandCONTRIBUTING.md.- Regression tests for the relaunch decisions (sandbox detection via injected
entitlement value,
LSMultipleInstancesProhibitedplist forms, the can-relaunch matrix).
- "Open the … list" always opens the pane. The manual-add walkthrough's
step-1 button called
request(), which for Accessibility maps to the AX prompt — shown by macOS only once per app, so every later click was a silent no-op. The button now deep-links to the pane; the Accessibility request path also falls back to opening the pane when the one-shot prompt is spent (mirroring the Screen Recording behavior). - Wizard visible after relaunch. The onboarding window now calls
orderFrontRegardless()— cooperative activation (macOS 14+) can deny activation right after a quit-and-reopen handoff, which could leave the relaunched wizard buried. - Sandbox-safe relaunch.
PermissionManager.quitAndReopen()previously spawned a detached/bin/shhelper, which the App Sandbox forbids — in a sandboxed app the relaunch never happened and the app just quit. Sandboxed apps now relaunch via LaunchServices (NSWorkspace.openApplicationwithcreatesNewApplicationInstance), terminating only once the new instance is underway. Sandboxed apps markedLSMultipleInstancesProhibited(which refuse a second live instance) stay running instead of quitting into nothing; the grant applies on the next manual restart. Non-sandboxed behavior is unchanged. Sandbox detection reads thecom.apple.security.app-sandboxentitlement from the process's own code signature (SecTaskCopyValueForEntitlement) — theAPP_SANDBOX_CONTAINER_IDenvironment variable is not reliably present, and misdetecting sent sandboxed apps down the shell path (quit, no relaunch). All relaunch paths now log to os.log (subsystemPermissionPilot, categoryrelaunch) so a failed relaunch is diagnosable vialog show. - Docs: corrected the App Sandbox guidance. The engine/detection work sandboxed, and the standard privacy permissions are usable with the matching entitlements; only Accessibility, Input Monitoring, Full Disk Access, and Automation are sandbox-incompatible (was an over-broad "non-sandboxed only").
- Demo build script now copies the SwiftPM resource bundles into the
.app, soBundle.module(localizations) resolves at runtime. EKAuthorizationStatusmapping no longer emits a "switch must be exhaustive" warning (mapped on stable raw values).
0.1.0 - 2026-06-20
Initial release.
- 16 macOS permissions across three tiers:
- Prompt-based — Camera, Microphone, Location, Contacts, Calendars, Reminders, Photos, Speech Recognition, Bluetooth, Notifications, plus the system-prompt panes (Accessibility, Screen Recording, Input Monitoring).
- Deep-link-only — Full Disk Access, Automation, Local Network.
PermissionManagerengine: live detection, request/prompt, System Settings deep-links, auto re-check on activation, and relaunch handling.- Components:
PermissionRow,PermissionTile,PermissionChecklist,PermissionsView(List ⇄ Grid),JustInTimePermissionButton,DragToAuthorizeView. OnboardingViewwizard (welcome → permissions → done) with theming and host copy/icon/accent overrides — no SDK branding of its own.- Three composable products (
PermissionPilotCore,PermissionPilotUI,PermissionPilot); zero third-party dependencies.