Loading...
Loading...
macOS disk cleanup, cache pruning, stale file detection, and Downloads triage. TRIGGERS - disk space, cleanup, disk usage, stale files, cache clean, brew cleanup, forgotten files, Downloads cleanup, free space, storage, dust, dua, gdu, ncdu.
npx skill4agent add terrylica/cc-skills disk-hygieneAudit disk usage, clean developer caches, find forgotten large files, and triage Downloads on macOS.
1. Run disk overview (df -h / and major directories)
2. Audit developer caches (uv, brew, pip, npm, cargo, rustup, Docker)
3. Scan for forgotten large files (>50MB, not accessed in 180+ days)
4. Present findings with AskUserQuestion for cleanup choices
5. Execute selected cleanups
6. Report space reclaimed1. Measure current cache sizes
2. Run safe cache cleanups (brew, uv, pip, npm)
3. Report space reclaimed1. List Downloads contents with dates and sizes
2. Categorize into groups (media, dev artifacts, personal docs, misc)
3. Present AskUserQuestion multi-select for deletion/move
4. Execute selected actions1. Scan home directory for large files not accessed in 180+ days
2. Group by location and type (media, ISOs, dev artifacts, documents)
3. Present findings sorted by size
4. Offer cleanup options via AskUserQuestion/usr/bin/env bash << 'OVERVIEW_EOF'
echo "=== Disk Overview ==="
df -h /
echo ""
echo "=== Major Directories ==="
du -sh ~/Library/Caches ~/Library/Logs ~/Library/Application\ Support \
~/.Trash ~/Downloads ~/Documents ~/Desktop ~/Movies ~/Music ~/Pictures \
2>/dev/null | sort -rh
echo ""
echo "=== Developer Tool Caches ==="
du -sh ~/.docker ~/.npm ~/.cargo ~/.rustup ~/.local ~/.cache \
~/.conda ~/.pyenv ~/.local/share/mise 2>/dev/null | sort -rh
OVERVIEW_EOF| Cache | Location | Typical Size | Clean Command |
|---|---|---|---|
| uv | | 5-15 GB | |
| Homebrew | | 3-10 GB | |
| pip | | 0.5-2 GB | |
| npm | | 0.5-2 GB | |
| cargo | | 1-5 GB | |
| rustup | | 2-8 GB | |
| Docker | Docker.app | 5-30 GB | |
| Playwright | | 0.5-2 GB | |
| sccache | | 1-3 GB | |
| huggingface | | 1-10 GB | |
/usr/bin/env bash << 'CACHE_CLEAN_EOF'
set -euo pipefail
echo "=== Measuring current cache sizes ==="
echo "uv: $(du -sh ~/Library/Caches/uv/ 2>/dev/null | cut -f1 || echo 'N/A')"
echo "Homebrew: $(du -sh ~/Library/Caches/Homebrew/ 2>/dev/null | cut -f1 || echo 'N/A')"
echo "pip: $(du -sh ~/Library/Caches/pip/ 2>/dev/null | cut -f1 || echo 'N/A')"
echo "npm: $(du -sh ~/.npm/_cacache/ 2>/dev/null | cut -f1 || echo 'N/A')"
echo ""
echo "=== Cleaning ==="
brew cleanup --prune=all 2>&1 | tail -3
uv cache clean --force 2>&1
pip cache purge 2>&1
npm cache clean --force 2>&1
CACHE_CLEAN_EOF| Issue | Cause | Solution |
|---|---|---|
| Another uv process running | Use |
| Linked but not latest | Safe to ignore, or |
| System pip vs user pip | Use |
| Docker not running | Docker Desktop not started | Start Docker.app first, or skip |
/usr/bin/env bash << 'STALE_EOF'
echo "=== Large forgotten files (>50MB, untouched 180+ days) ==="
echo ""
# Scan home directory (excluding Library, node_modules, .git, hidden dirs)
find "$HOME" -maxdepth 4 \
-not -path '*/\.*' \
-not -path '*/Library/*' \
-not -path '*/node_modules/*' \
-not -path '*/.git/*' \
-type f -atime +180 -size +50M 2>/dev/null | \
while read -r f; do
mod_date=$(stat -f '%Sm' -t '%Y-%m-%d' "$f" 2>/dev/null)
size=$(du -sh "$f" 2>/dev/null | cut -f1)
echo "${mod_date} ${size} ${f}"
done | sort
echo ""
echo "=== Documents & Desktop (>10MB, untouched 180+ days) ==="
find "$HOME/Documents" "$HOME/Desktop" \
-type f -atime +180 -size +10M 2>/dev/null | \
while read -r f; do
mod_date=$(stat -f '%Sm' -t '%Y-%m-%d' "$f" 2>/dev/null)
size=$(du -sh "$f" 2>/dev/null | cut -f1)
echo "${mod_date} ${size} ${f}"
done | sort
STALE_EOF| Type | Typical Location | Example |
|---|---|---|
| Windows/Linux ISOs | Documents, Downloads | |
| CapCut/iMovie exports | Movies/ | Large |
| Phone video transfers | Pictures/, DCIM/ | |
| Old Zoom recordings | Documents/ | |
| Orphaned downloads | Documents/ | |
| Screen recordings | Documents/, Desktop/ | Capto/QuickTime |
~/Downloads/usr/bin/env bash << 'DL_LIST_EOF'
echo "=== Downloads by date and size ==="
find "$HOME/Downloads" -maxdepth 1 \( -type f -o -type d \) ! -path "$HOME/Downloads" | \
while read -r f; do
mod_date=$(stat -f '%Sm' -t '%Y-%m-%d' "$f" 2>/dev/null)
size=$(du -sh "$f" 2>/dev/null | cut -f1)
echo "${mod_date} ${size} $(basename "$f")"
done | sort
DL_LIST_EOF| Tool | Wall Time | CPU Usage | Interactive Delete | Install |
|---|---|---|---|---|
| dust | 20.4s | 637% (parallel) | No (view only) | |
| gdu-go | 28.8s | 845% (very parallel) | Yes (TUI) | |
| dua-cli | 37.1s | 237% (moderate) | Yes (staged safe delete) | |
| ncdu | 96.6s | 43% (single-thread) | Yes (TUI) | |
dustdua igdu-go# dust - instant tree overview
dust -d 2 ~ # depth 2
dust -r ~/Library # reverse sort (smallest first)
# dua - interactive TUI with safe deletion
dua i ~ # navigate, mark, delete with confirmation
# gdu-go - ncdu-like TUI, fast on SSDs
gdu-go ~ # full TUI with delete support
gdu-go -n ~ # non-interactive (for scripting/benchmarks)brew install dust dua-cli gdugdu-go| Action | Typical Savings | Risk | Command |
|---|---|---|---|
| 5-15 GB | None (re-downloads) | |
| 3-10 GB | None (re-downloads) | |
| Delete movie files in Downloads | 2-10 GB | Check first | Manual after AskUserQuestion |
| 0.5-2 GB | None (re-downloads) | |
| 0.5-2 GB | None (re-downloads) | |
| Prune old rustup toolchains | 2-5 GB | Keep current | |
| Docker system prune | 5-30 GB | Removes stopped containers | |
| Empty Trash | Variable | Irreversible | |
/usr/bin/env bash << 'EOF'$HOME| Issue | Cause | Solution |
|---|---|---|
| Lock held by running uv | Use |
| Already clean or formulae linked | Run |
| System Integrity Protection | Add |
| Installed as | Use |
| Counting method differs | Normal - |
| Stale file scan is slow | Deep directory tree | Limit |
| Docker not accessible | Desktop app not running | Start Docker.app or skip Docker cleanup |