Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
Shell
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203#!/bin/bash# Safe, user-level macOS disk inventory/cleanup for the AC fleet Macs.# Default is report-only; known regenerable caches require --apply.set -euo pipefail
APPLY=0INSTALL=0THIN_SNAPSHOTS=0
usage() { cat <<'EOF'Usage: ac-disk-clean [--apply] [--thin-snapshots] [--install]
(no args) Report disk use and cleanup candidates; change nothing. --apply Clear known regenerable user caches when their app is idle. --thin-snapshots With --apply, ask tmutil to reclaim local snapshots. --install Install in ~/.local/bin and enable a weekly LaunchAgent.
Protected: repositories, node_modules, Downloads, Documents/Shelf, modelweights, Codex/Claude state, mail archives, application data, and caches ownedby a currently running application.EOF}
while (($#)); do case "$1" in --apply) APPLY=1 ;; --install) INSTALL=1 ;; --thin-snapshots) THIN_SNAPSHOTS=1 ;; -h|--help) usage; exit 0 ;; *) echo "Unknown option: $1" >&2; usage >&2; exit 2 ;; esac shiftdone
human_size() { if [[ -e "$1" ]]; then du -sh -- "$1" 2>/dev/null | awk '{print $1}' || echo "?" else echo "0" fi}
data_volume() { [[ -d /System/Volumes/Data ]] && echo /System/Volumes/Data || echo /}
disk_used_kb() { df -k "$(data_volume)" | awk 'NR == 2 {print $3}'}
report() { local volume snapshots volume=$(data_volume) snapshots=$(tmutil listlocalsnapshots / 2>/dev/null | grep -c '^com\.apple\.' || true)
echo "$(scutil --get LocalHostName 2>/dev/null || hostname) disk report — $(date '+%Y-%m-%dT%H:%M:%S%z')" echo df -h "$volume" | awk 'NR == 1 || NR == 2' echo "Local snapshots: $snapshots" echo printf '%-35s %9s %s\n' "Path/category" "Size" "Policy" printf '%-35s %9s %s\n' "-----------------------------------" "---------" "------" printf '%-35s %9s %s\n' "aesthetic-computer/.git" "$(human_size "$HOME/aesthetic-computer/.git")" "PROTECTED" printf '%-35s %9s %s\n' "aesthetic-computer/node_modules" "$(human_size "$HOME/aesthetic-computer/node_modules")" "PROTECTED" printf '%-35s %9s %s\n' "Documents/Shelf" "$(human_size "$HOME/Documents/Shelf")" "PROTECTED; curate manually" printf '%-35s %9s %s\n' "Chrome cache" "$(human_size "$HOME/Library/Caches/Google")" "safe when Chrome idle" printf '%-35s %9s %s\n' "Puppeteer cache" "$(human_size "$HOME/.cache/puppeteer")" "safe when browser tooling idle" printf '%-35s %9s %s\n' "Spotify cache" "$(human_size "$HOME/Library/Caches/com.spotify.client")" "safe when Spotify idle" printf '%-35s %9s %s\n' "pip cache" "$(human_size "$HOME/Library/Caches/pip")" "safe when pip idle" printf '%-35s %9s %s\n' "Messages cache" "$(human_size "$HOME/Library/Messages/Caches")" "safe when Messages idle" printf '%-35s %9s %s\n' "npm content cache" "$(human_size "$HOME/.npm/_cacache")" "safe when node/npm idle" printf '%-35s %9s %s\n' "Slab recordings" "$(human_size "$HOME/.local/share/slab/sessions")" "keeps last 7 days" printf '%-35s %9s %s\n' "Trash" "$(human_size "$HOME/.Trash")" "safe with --apply" printf '%-35s %9s %s\n' "CoreSimulator volumes" "$(human_size /Library/Developer/CoreSimulator/Volumes)" "report only" echo if ((APPLY == 0)); then echo "Report only. Run 'ac-disk-clean --apply' to clear safe caches." fi}
clean_contents() { [[ -d "$1" ]] || return 0 find "$1" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +}
skip() { echo " skip: $1"}
apply_cleanup() { local before after reclaimed before=$(disk_used_kb) echo "Applying safe user-cache cleanup..."
if pgrep -f '/Google Chrome( |$)|Google Chrome Helper' >/dev/null; then skip "Chrome is active; Chrome and Puppeteer caches kept" else clean_contents "$HOME/Library/Caches/Google" clean_contents "$HOME/.cache/puppeteer" fi
if pgrep -x Spotify >/dev/null; then skip "Spotify is active; its cache kept" else clean_contents "$HOME/Library/Caches/com.spotify.client" fi
if pgrep -x Messages >/dev/null; then skip "Messages is active; its cache kept" else clean_contents "$HOME/Library/Messages/Caches" fi
if pgrep -f '(^|/)(pip|pip3)( |$)' >/dev/null; then skip "pip is active; its cache kept" else clean_contents "$HOME/Library/Caches/pip" fi
if pgrep -f '(^|/)(node|npm|pnpm|yarn)( |$)' >/dev/null; then skip "node/npm workload is active; npm cache kept" else clean_contents "$HOME/.npm/_cacache" fi
if pgrep -f '(^|/)(swift|swiftc|xcodebuild)( |$)' >/dev/null; then skip "Swift/Xcode build is active; .build directories kept" elif [[ -d "$HOME/aesthetic-computer" ]]; then find "$HOME/aesthetic-computer" -name .build -type d -prune -exec rm -rf -- {} + 2>/dev/null || true fi
if [[ -d "$HOME/.local/share/slab/sessions" ]]; then find "$HOME/.local/share/slab/sessions" -maxdepth 1 -type f -mtime +7 -delete fi clean_contents "$HOME/.Trash"
if ! pgrep -x brew >/dev/null; then if [[ -x /opt/homebrew/bin/brew ]]; then /opt/homebrew/bin/brew cleanup --prune=all >/dev/null 2>&1 || true elif [[ -x /usr/local/bin/brew ]]; then /usr/local/bin/brew cleanup --prune=all >/dev/null 2>&1 || true fi fi
if ((THIN_SNAPSHOTS)); then tmutil thinlocalsnapshots / 10000000000 4 >/dev/null 2>&1 || skip "tmutil could not thin snapshots without administrator approval" fi
after=$(disk_used_kb) reclaimed=$((before - after)) ((reclaimed < 0)) && reclaimed=0 echo "Cleanup complete: $(awk -v kb="$reclaimed" 'BEGIN {printf "%.1f MiB", kb / 1024}') reclaimed." df -h "$(data_volume)" | awk 'NR == 1 || NR == 2'}
install_utility() { local bin_dir agent_dir plist source uid bin_dir="$HOME/.local/bin" agent_dir="$HOME/Library/LaunchAgents" plist="$agent_dir/computer.aesthetic.disk-clean.plist" source=$(cd "$(dirname "$0")" && pwd)/$(basename "$0") uid=$(id -u) mkdir -p "$bin_dir" "$agent_dir" "$HOME/Library/Logs" if [[ "$source" != "$bin_dir/ac-disk-clean" ]]; then install -m 0755 "$source" "$bin_dir/ac-disk-clean" else chmod 0755 "$bin_dir/ac-disk-clean" fi
cat >"$plist" <<EOF<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict> <key>Label</key><string>computer.aesthetic.disk-clean</string> <key>ProgramArguments</key><array> <string>$bin_dir/ac-disk-clean</string><string>--apply</string> </array> <key>StartCalendarInterval</key><dict> <key>Weekday</key><integer>1</integer><key>Hour</key><integer>3</integer><key>Minute</key><integer>15</integer> </dict> <key>StandardOutPath</key><string>$HOME/Library/Logs/ac-disk-clean.log</string> <key>StandardErrorPath</key><string>$HOME/Library/Logs/ac-disk-clean.log</string></dict></plist>EOF
plutil -lint "$plist" launchctl bootout "gui/$uid/computer.aesthetic.disk-clean" >/dev/null 2>&1 || true launchctl bootstrap "gui/$uid" "$plist" echo "Installed $bin_dir/ac-disk-clean and weekly LaunchAgent."}
if ((INSTALL)); then install_utility exit 0fi
reportif ((APPLY)); then echo apply_cleanupfi