3.3 KiB
3.3 KiB
macOS Installation Model
How production macOS utilities commonly do it
Apps such as Cloudflare WARP, VPN clients, Docker Desktop, and device agents usually separate:
- a user-facing app or menu bar app;
- one or more background services;
- launchd configuration for automatic startup;
- privileged helpers only when system-level networking, drivers, packet filtering, or protected paths are required.
Common mechanisms:
LaunchAgentin~/Library/LaunchAgentsfor per-user background/login startup.LaunchDaemonin/Library/LaunchDaemonsfor root/system services.SMAppService/ login items for sandboxed or App Store-aligned apps.- Privileged helper tools via
SMJobBlesswhen admin-level installation is required. .pkginstallers when the install needs privileged locations, daemons, receipts, or managed deployment.
Recommended AI Workspace approach
Use a staged model:
-
Current local developer install
- Build a real
.appbundle intoapps/mac/AIWorkspace/dist/. - Install to
~/Applications/AIWorkspace.app. - Install a per-user
LaunchAgentfor start at login.
- Build a real
-
Production-ready local install
- Keep using a per-user LaunchAgent because services are local user tools and do not require root.
- Add a one-step installer script that builds, installs, optionally enables start at login, and opens the app.
- Avoid privileged helpers until a real system-level requirement appears.
-
Future polished distribution
- Create a signed/notarized
.appdistributed in a.dmgwith an Applications shortcut, or a.pkgonly if privileged installation becomes necessary. - Use
SMAppServicefor login item management from inside the app so the user can toggle Start at Login in the UI instead of runninglaunchctlscripts manually. - Add a small daemon API if the UI needs richer lifecycle control than shelling out to
services.py.
- Create a signed/notarized
Desired user-grade install flow
For a Cloudflare/Docker-like local experience, the target should be:
- User opens
AIWorkspace.dmg. - User drags
AIWorkspace.appto/Applicationsor~/Applications. - User launches the app.
- App shows service status and a Start at Login toggle.
- App registers/unregisters itself as a login item using
SMAppService. - App starts/stops workspace services through the service manager.
The existing shell scripts remain useful for development and bootstrap, but should not be the primary end-user experience once the app handles login item registration itself.
Current implementation state
AIWorkspace.appcan be packaged fromapps/mac/AIWorkspace/scripts/package-app.sh.AIWorkspace.dmgcan be built fromapps/mac/AIWorkspace/scripts/build-dmg.sh.- The app UI includes a Start at Login toggle backed by
SMAppService.mainApp. - LaunchAgent scripts remain as development fallbacks, not the preferred user path.
Why not LaunchDaemon now
The current services are user-context services:
- Mattermost Desktop launching must happen in the user's GUI session.
- Photo Inbox writes to user-owned folders and uses clipboard/notifications.
- The MCP and proxy bind localhost ports and do not require root.
A root daemon would add unnecessary permission prompts and security risk. A per-user LaunchAgent is the correct production-leaning step for this stage.