Que fait mac-declutter ?
Un playbook éprouvé pour désencombrer un Mac de développeur : prolifération d'agents IA, services d'arrière-plan morts, résidus d'applications, pièges de proxy, et audits de performance.
Principes de base :
- Inventorier avant de supprimer. Ne jamais désinstaller à l'aveugle — mesurer d'abord la taille, la date de dernière utilisation et l'état d'exécution, puis laisser l'utilisateur choisir.
- Ne jamais toucher aux enregistrements de session ou aux données utilisateur sauf demande explicite. Les caches se régénèrent ; les sessions non.
- Vérifier après chaque modification — processus disparu, port fermé, élément de connexion supprimé.
- L'Intégrité de Protection du Système (SIP) est un mur infranchissable. Les applications détenues par root, les conteneurs sandbox et les extensions DriverKit ont chacun un chemin de suppression autorisé ; ne pas lutter contre l'OS.
Phase 0 — Triage réseau (à faire en premier)
Le symptôme « tout est déconnecté » est presque toujours un proxy local mort, pas une application cassée :
scutil --proxy # ce vers quoi le proxy système pointe
nc -z -w 2 127.0.0.1 <port> # quelque chose écoute-t-il réellement ?
lsof -nP -iTCP:<port> -sTCP:LISTEN # qui le possède
Le piège classique : les outils de type Clash/V2Ray configurent le proxy système macOS sur 127.0.0.1:PORT, puis le noyau meurt — le mode de règle n'a pas d'importance, tout le trafic meurt à la porte. Les applications qui respectent le proxy système (la plupart des applications GUI, quelques CLI) échouent toutes ; curl fonctionne encore parce qu'il contourne le proxy système, ce qui induit en erreur le diagnostic. Corrections : redémarrer le noyau du proxy, ou désactiver le proxy (networksetup -setwebproxystate Wi-Fi off + -setsecurewebproxystate + -setsocksfirewallproxystate + WPAD off), ou pointer le propre paramètre proxy de l'application vers rien. Rappelez-vous : curl ignore le proxy système — testez la connectivité de type application avec curl -x http://127.0.0.1:PORT.
Phase 1 — Inventaire (lecture seule)
Exécutez scripts/inventory.sh, ou couvrez manuellement ces dimensions :
- Répertoires de configuration des agents :
~/.claude,~/.codex,~/.pi,~/.jcode,~/.config/opencode, etc. Pour chacun : taille (du -sh), dernière activité (mtime du fichier le plus récent), si le binaire CLI existe encore (which). - État de connexion/auth :
auth.json,openai-auth.json, fichiers d'identifiants — lister les clés, ne jamais imprimer les secrets. - Services d'arrière-plan :
launchctl list | grep -v com.appleet~/Library/LaunchAgents/*.plist— lire lesProgramArgumentsde chaque plist pour savoir ce qu'il exécute réellement. - Applications : pour chaque
.appnon Apple dans/Applicationset~/Applications, collecter la taille,kMDItemLastUsedDateviamdls, et la présence de_MASReceipt(applications App Store). « Jamais ouvert » + grand = candidat idéal. - Caches :
~/Library/Caches,~/.npm, caches pip/bun — gros et toujours sûr à purger.
Présentez les résultats sous forme de tableau garder/supprimer et laissez l'utilisateur choisir. Signalez les applications payantes/par abonnement (par ex. _MASReceipt, produits d'abonnement connus) afin que l'utilisateur annule la facturation avant de supprimer.
Phase 2 — Guide de désinstallation
Par cible, dans l'ordre :
- Arrêter les services :
launchctl remove <label>pour chaque LaunchAgent/Daemon associé. - Supprimer les plists :
~/Library/LaunchAgents/<label>.plist. - Supprimer l'application/CLI :
rm -rfle.app/npm uninstall -g <pkg>/ supprimer le binaire.Permission denied→ propriété root (installé par package). Utilisezosascript -e 'do shell script "rm -rf ..." with administrator privileges'(une seule invite de mot de passe GUI). Ne jamais fairesudoaveuglément.
- Résidus dans la bibliothèque : vérifier et supprimer
~/Library/{Application Support,Caches,Containers,HTTPStorages,Preferences}/<app-or-bundle-id>.- Les
Containers/*sandboxés peuvent résister même à root (protection du gestionnaire de conteneurs). S'ils sont minuscules, laissez-les — l'OS récupère les conteneurs orphelins ; désactiver SIP n'en vaut jamais la peine.
- Les
- Extensions système :
systemextensionsctl list. SIP bloque la désinstallation directe — le seul chemin propre est de réinstaller l'application du fournisseur et d'exécuter son désinstalleur officiel (cherchezuninstall.shdans/Library/Application Support/<vendor>/). Les pilotes DriverKit.dextse déchargent uniquement au prochain redémarrage — dites à l'utilisateur qu'ils ont disparu après le redémarrage. - Éléments de connexion obsolètes : après avoir supprimé une application, son entrée « Ouvrir à la connexion » reste souvent comme un zombie. Supprimez-la avec
osascript -e 'tell application "System Events" to delete login item "<name>"'. - Restes en cours d'exécution : les applications supprimées peuvent laisser des processus en cours d'exécution provenant de répertoires temporaires du programme de mise à jour (par ex. staging Squirrel
ShipIt).ps aux | grep -i <name>, tuez-les et vérifiez s'il existe un répertoire de données dans$HOME(~/.<appname>) — les démons lancés par le programme de mise à jour cachent souvent des centaines de Mo là-bas.
Phase 3 — Purge du cache (risque zéro)
npm cache clean --force
rm -rf ~/Library/Caches/pip ~/.bun/install/cache
rm -rf ~/Library/Caches/<deleted-app>/*
Les caches se régénèrent. Les historiques de session (sessions/, projects/, *.jsonl journaux de conversation) ne le font pas — laissez-les sauf si l'utilisateur dit explicitement le contraire.
Phase 4 — Audit de performance
memory_pressure | tail -2 # pourcentage libre et pression
sysctl -n vm.swapusage # l'échange utilisé devrait être ~0 sur une machine saine
sysctl -n vm.loadavg
ps -axm -o rss,comm | awk 'NR>1 {rss=$1; $1=