- name
- nuclear-cleanup
- description
- Maxi/mega/nuclear macOS cleanup — reclaim disk space by removing caches, unused apps, orphaned files, iCloud empty containers, and startup junk, with safety confirmations and before/after measurements. Use when the user asks for a deep clean, "nuclear cleanup", "free space", "clean my Mac", or to tidy startup/boot items.
# Nuclear Cleanup (macOS)
A phased, **non-destructive-by-default** deep clean. Reclaim maximum disk space while never destroying irreplaceable data. Always report space recovered (before/after) per batch and a running total.
## 🛡️ CORE SAFETY RULES — read before any deletion
1. **Look at the target before deleting.** If it's not pure cache/junk, inspect size + contents first. Surface anything surprising instead of deleting.
2. **NEVER auto-delete (always inspect + confirm):** user projects/code, journals/notes (DayOne, Bear, Obsidian, Ulysses…), crypto wallets, password vaults, photos/originals, Documents/Desktop content, anything with real user data.
3. **ALWAYS preserve:** `~/.ssh` and secrets (offer an encrypted `.dmg` backup instead of deleting — `hdiutil create -encryption AES-256`), app logins/profiles (Chrome/Arc/Google — keep), user projects, Music/photo originals (unless explicitly confirmed).
4. **Measure space every batch:** `df -k /System/Volumes/Data | awk 'NR==2{print $4}'` before & after; report `RÉCUPÉRÉ` in Go.
5. **TCC-protected paths** (`~/Documents`, `~/Desktop`, `~/Downloads`, `~/Library/Mobile Documents` top-level): `rm` returns *"Permission denied"*. Use Finder instead:
`osascript -e 'tell application "Finder" to delete (POSIX file "/full/path" as alias)'`
(If Finder errors `-1700 can't make alias`, the file is already gone — it's a stale Finder entry; `killall Finder` to refresh.)
6. **Root-owned items** (App Store apps, `/Library/*`, `/Applications/Xcode.app`, etc.): `rm` fails. **I cannot run `sudo`** (needs the user's password). Collect ALL root-owned targets and emit **ONE consolidated command** for the user to paste: ``! sudo rm -rf "path1" "path2" …``
7. **Empty iCloud containers** (0 files): safe to delete via Finder. Warn they may **reappear** from iPhone/iCloud re-sync (kill for good on the iPhone: Settings → iCloud → Manage Storage).
8. Confirm each destructive *category* with the user (use AskUserQuestion multiselect). Quick wins (pure caches) can proceed without asking.
9. Run big deletions with `run_in_background: true`; guard zsh globs (no-match aborts) — prefer `find … -exec` or explicit paths.
## Phase 0 — Diagnose
```bash
df -h /System/Volumes/Data | sed -n '2p'
du -sh ~/Library/*/ 2>/dev/null | sort -rh | head -15
du -sh ~/Library/Application\ Support/*/ 2>/dev/null | sort -rh | head -10
du -sh /Applications/* 2>/dev/null | sort -rh | head -20
du -sh /Library/* 2>/dev/null | sort -rh | head -8 # audio plugins (Arturia), Developer, etc.
```
Note: `/` is the sealed System volume (small); real data is on `/System/Volumes/Data`. `/Applications` & parts of `/Library` are firmlinked into Data (count there).
## Phase 1 — Safe caches (zero risk, no confirm needed)
```bash
rm -rf ~/Library/Caches/* ~/.cache/* 2>/dev/null
# Electron app caches (preserve logins/favorites — only cache dirs):
for app in Arc Notion Claude Slack Figma Linear; do
base="$HOME/Library/Application Support/$app"; [ -d "$base" ] || continue
find "$base" -type d \( -name Cache -o -name 'Code Cache' -o -name GPUCache -o -name DawnCache \
-o -name DawnGraphiteCache -o -name DawnWebGPUCache -o -name ShaderCache -o -name GrShaderCache \
-o -name component_crx_cache -o -name CacheStorage \) -prune -exec rm -rf {} + 2>/dev/null
done
# Dev caches:
command -v pnpm >/dev/null && pnpm store prune
command -v npm >/dev/null && npm cache clean --force
rm -rf ~/.nvm/.cache 2>/dev/null # keep node versions
command -v brew >/dev/null && brew cleanup --prune=all
# .rustup (1GB+ toolchains, reinstallable) — confirm first; restore: curl https://sh.rustup.rs
# Empty trash:
osascript -e 'tell application "Finder" to empty trash' 2>/dev/null
```
Cache freed while apps run may only fully release after an app/Mac restart — mention it.
## Phase 2 — Heavy files (>800 MB)
```bash
find "$HOME" -type f -size +800M 2>/dev/null | while read f; do echo "$(du -h "$f"|cut -f1) ${f/#$HOME/~}"; done | sort -rh | head -20
```
Common safe targets: Chrome on-device AI model (`OptGuideOnDeviceModel`), Claude `vm_bundles` (re-downloads), Electron app old DB backups, CloudKit cache. Present + confirm.
## Phase 3 — Apps (inventory by last-used)
```bash
for a in /Applications/*.app /Applications/Setapp/*.app; do
[ -e "$a" ] || continue
last=$(mdls -name kMDItemLastUsedDate -raw "$a" 2>/dev/null | cut -c1-10)
sz=$(du -sm "$a" 2>/dev/null | cut -f1)
echo "${last:-jamais}|${sz:-0}|$(basename "$a")"
done | sort | awk -F'|' '{printf "%-11s %6s Mo %s\n",($1=="(null)"||$1==""?"jamais":$1),$2,$3}'
```
- `mdls` last-used can be wrong for menubar/login-item apps (e.g. Notion shows "jamais") — cross-check before recommending.
- Present "never used" + "stale (months)" as delete candidates → AskUserQuestion multiselect.
- For each chosen app: `rm -rf "/Applications/X.app"` (or Setapp). If it fails → add to the **sudo batch**. Then remove residuals: `~/Library/Application Support/X`, `~/Library/Caches/*X*`, `~/Library/Preferences/*X*`, `~/Library/Containers/*X*` (use `find … -exec` for patterns). **Check for user data first** (e.g. Bear/notes DB in `~/Library/Group Containers/*` — preserve if it has real content).
## Phase 4 — iCloud empty containers
```bash
cd ~/Library/Mobile\ Documents
for c in */; do c="${c%/}"
[ -d "$c" ] || continue
nf=$(find "$c" -type f ! -name '.DS_Store' 2>/dev/null | head -1 | wc -l | tr -d ' ')
if [ "$nf" = 0 ]; then
osascript -e "tell application \"Finder\" to delete (POSIX file \"$PWD/$c\" as alias)" >/dev/null 2>&1
fi
done
```
Keep non-empty ones; list them. Before deleting any **non-empty** container, inspect (crypto wallets / journals / messaging backups are often here — never bulk-delete those).
## Phase 5 — Startup / clean boot
```bash
ls -1 ~/Library/LaunchAgents 2>/dev/null | grep -v '^\.'
ls -1 /Library/LaunchAgents /Library/LaunchDaemons 2>/dev/null | grep -viE '^com\.apple\.'
osascript -e 'tell application "System Events" to get the name of every login item'
```
- Remove **orphan login items** (app no longer installed):
`osascript -e 'tell application "System Events" to delete login item "NAME"'`
- Remove **orphan user LaunchAgents** (`~/Library/LaunchAgents/…`): `launchctl bootout gui/$(id -u)/LABEL; rm -f the.plist`
- **System** LaunchAgents/Daemons + `/Library/PrivilegedHelperTools` orphans → add to the **sudo batch**.
- Keep legit ones (Setapp, Google Updater, Raycast, Swish, apps the user actually uses). Ask about unknowns before removing.
## Phase 6 — Residue hunt (uninstalled-app leftovers)
Look for orphaned `~/Library/Application Support/*`, `~/Library/Application Scripts/*`, `HTTPStorages`, prefs, CrashReporter/DiagnosticReports for apps already removed (Dropbox, Docker, Arturia, deleted apps…). Also orphaned audio plugins in `/Library/Audio/Plug-Ins/{VST3,Components}` (→ sudo batch). macFUSE leftover from Mountain Duck → sudo batch (note it may need its own uninstaller / System Settings → Login Items & Extensions).
## Phase 7 — Final consolidated sudo command
Emit ONE line for the user (everything root-owned collected across phases), then tell them to **reboot**:
```
! sudo rm -rf "/Applications/Foo.app" "/Library/LaunchDaemons/…" "/Library/Audio/Plug-Ins/VST3/…" …
```
## Reporting (end)
- Total recovered (start → end, in Go) and current free space.
- Bullet list of what was **preserved** (projects, logins, secrets, user data) for reassurance.
- Any pending user actions (sudo command, reboot, browser-extension removals, iCloud-on-iPhone cleanup).
Voir sur GitHub