๐ŸŽ macOS Launchd Services โ€” 2 plist + 2 scripts: automated daily updates & system cleanup MacOS automation setup using two launchd plist files and two shell scripts to perform daily system updates and hourly cleanup tasks. The daily-update script updates Homebrew, npm, and various developer tools, while the mo-extra script clears caches and removes old downloads, with a 72-hour cooldown to prevent redundant runs. The setup is designed to be privacy-focused, using only `$HOME` or placeholder variables, and requires users to customize file paths before loading the services with launchd. ๐ŸŽ macOS Launchd Services โ€” Automated Daily Updates & System Cleanup macOS 13+ Ventura, Apple Silicon & Intel โ€” 2 launchd plists and 2 shell scripts for keeping your dev machine up to date and clean, automatically. Zero personal data. All paths use $HOME or PLACEHOLDER variables. Download โ†’ tweak paths โ†’ load with launchd โ€” done. No system paths, no tokens, no credentials. --- ๐ŸŽฏ What This Does | Component | What | When | |-----------|------|------| | daily-update.sh + plist | Updates Homebrew, npm, uv, bun, rustup, pipx, conda, pip3, gh extensions, Poetry, AI CLIs Claude Code, Copilot, Cursor Agent, HuggingFace... , Mole, Orbstack and checks for macOS updates | Every day at 09:00 | | mo-extra + plist | Cleans caches brew, npm, bun, uv, pip, go, cargo, Docker and removes old ~/Downloads files 30+ days . Built-in 72h cooldown to avoid redundant runs | Every hour skips if within cooldown | Result: Your machine stays updated and lean โ€” automatically, in the background. --- ๐Ÿ“‹ Files | File | Type | Description | |------|------|-------------| | com.user.daily-update.plist | launchd plist | Runs daily-update.sh every morning at 09:00 | | daily-update.sh | Bash script | 15-step update: brew, npm, uv, bun, rustup, pipx, conda, AI CLIs, macOS | | com.user.mo-extra.plist | launchd plist | Triggers mo-extra every hour cooldown managed in script | | mo-extra | Bash script | 11 cleanup operations: caches, Docker, Downloads | --- ๐Ÿš€ Quick Start bash 1. Decide where to keep the scripts mkdir -p ~/.local/bin 2. Copy scripts there cp daily-update.sh ~/.local/bin/ cp mo-extra ~/.local/bin/ chmod +x ~/.local/bin/daily-update.sh ~/.local/bin/mo-extra 3. Option A โ€” Run manually whenever you want ~/.local/bin/daily-update.sh ~/.local/bin/mo-extra 4. Option B โ€” Automate with launchd First, edit the plists: replace PROGRAM PATH and LOG PATH see "Customization" below cp com.user.daily-update.plist ~/Library/LaunchAgents/ cp com.user.mo-extra.plist ~/Library/LaunchAgents/ launchctl load ~/Library/LaunchAgents/com.user.daily-update.plist launchctl load ~/Library/LaunchAgents/com.user.mo-extra.plist 5. Add aliases for on-demand use optional echo 'alias daily-update="~/.local/bin/daily-update.sh"' ~/.zshrc echo 'alias daily-clean="rm -f ~/.local/state/mo-extra/last-run && ~/.local/bin/mo-extra"' ~/.zshrc --- ๐Ÿ”ง Customization Plist Placeholders | Placeholder | Where | Replace with | |-------------|-------|-------------| | PROGRAM PATH | Both plists | Absolute path to your script e.g., /Users/jane/.local/bin/daily-update.sh | | LOG PATH | Both plists | Log file path e.g., /Users/jane/Library/Logs/daily-update.log | | ERROR LOG PATH | mo-extra plist | Error log path e.g., /Users/jane/Library/Logs/mo-extra-err.log | | HOME DIR | mo-extra plist | Your home directory e.g., /Users/jane | Script Config Variables Edit the top of each script to tune: daily-update.sh: - LOG FILE โ€” where logs go default: ~/Library/Logs/daily-update.log - Sections are modular โ€” comment out any tool you don't use conda, orb, mo, etc. mo-extra: - COOLDOWN HOURS โ€” minimum hours between runs default: 72 - DOWNLOADS OLD DAYS โ€” delete Downloads older than N days default: 30 - LOG DIR โ€” log directory default: ~/Library/Logs --- ๐Ÿ“ Requirements | Tool | Needs | Notes | |------|-------|-------| | Scripts | Bash 5+ | macOS ships Bash 3; install via brew install bash | | brew cleanup | Homebrew https://brew.sh | Most operations depend on it | | npm / bun / uv / go / cargo | Optional | Sections skip automatically if missing | | Docker prune | Docker or Orbstack | Skips if Docker isn't running | | mo clean | Mole https://github.com/tw93/Mole brew install mo + sudo NOPASSWD | Optional โ€” comment out if unused | --- ๐Ÿงน Privacy This gist is fully generic : - No personal paths /Users/real-username/... - No API keys, tokens, or passwords - All user-specific values use $HOME or PLACEHOLDER - Example usernames jane , you are clearly examples - Must be configured before use --- ๐Ÿ’ก Pro Tips - Test without launchd first: Run the scripts manually to make sure they work - Check logs: cat ~/Library/Logs/daily-update.log - Force cleanup early: rm -f ~/.local/state/mo-extra/last-run && mo-extra - Customize tool list: Open daily-update.sh and remove sections you don't need - Add your own tools: Each section follows the same pattern โ€” just copy/paste --- Part of my dev workflow. macOS native launchd โ€” zero extra dependencies.