From claude-commands
Run disk usage analysis and cleanup preview on the local Mac. Always validates snapshot coverage before quoting and never deletes without user approval.
How this skill is triggered — by the user, by Claude, or both
Slash command
/claude-commands:disk-auditThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Analyze local disk usage, validate snapshot completeness, identify cleanup candidates, and optionally clean safe targets. **Always defaults to dry-run preview.** Never deletes anything without explicit user approval.
Analyze local disk usage, validate snapshot completeness, identify cleanup candidates, and optionally clean safe targets. Always defaults to dry-run preview. Never deletes anything without explicit user approval.
/disk-audit (points here)disk-magician snapshot --output <snap> — emits JSON with snapshot_coverage_pct + timeout_keys. Config via DISK_MAGICIAN_CONFIG=~/projects_other/user_scope/scripts/disk_magician_config.json (user_scope's monitored-dir set). backup-home.sh runs this every 30 min and writes backup/<host>/disk_snapshot.json. The local disk_snapshot.sh generator was removed in favor of the shared disk-magician CLI. Audit/history read user_scope's committed backup/<host>/ tree via the reader scripts below — NOT disk-magician audit/history, which read a separate single-host ~/.disk_magician_backup tree.~/projects_other/user_scope/scripts/disk_audit.sh — snapshot-first: reads pre-measured sizes from the committed snapshot, ranks the top 20 dirs, shows 7-day regressions, and bounds any live du at 60s. Runs in ~6s instead of timing out.~/projects_other/user_scope/scripts/disk_history.sh — trends/regressions from 700+ git-committed snapshots~/projects_other/user_scope/scripts/snapshot_lib.sh → resolve_snapshot_path picks the current host's snapshot (newest timestamp), not the first alphabetical backup/<host>/ dir. Both audit + history source it so they agree. On this Mac it resolves to backup/Mac/disk_snapshot.json.disk_audit.sh (snapshot-ranked preview) → --clean --dry-run for delete candidates--live to force du instead of the snapshot (slow); --no-history to skip the regression section~/.codex/sessions, ~/.codex/sessions_archive/, ~/.codex/state*.sqlite, ~/.codex/log, ~/.claude/projectsWORKTREE APPROVED per CLAUDE.mdResolve the current host's snapshot first — do NOT hardcode a backup/<host>/ path or glob the first match (that picks a stale wrong-host file). Use the shared resolver, then validate:
cd ~/projects_other/user_scope
SNAP="$(bash -c 'source scripts/snapshot_lib.sh; resolve_snapshot_path "$(pwd)"')"
python3 -c "
import json,sys
s = json.load(open(sys.argv[1]))
print('file:', sys.argv[1])
print('host:', s.get('hostname'), '| ts:', s.get('timestamp'))
print(f'coverage: {s.get(\"snapshot_coverage_pct\", \"missing\")}%')
print(f'warning: {s.get(\"snapshot_warning\", \"none\")}')
print(f'timeouts: {s.get(\"timeout_keys\", [])}')
" "$SNAP"
Rules:
hostname/timestamp is not the current machine's latest → the resolver fell back; check backup/*/ for a fresher file or run DISK_MAGICIAN_CONFIG=~/projects_other/user_scope/scripts/disk_magician_config.json disk-magician snapshot --output backup/<host>/disk_snapshot.json to regenerate.snapshot_coverage_pct is missing → snapshot is from an old script version; do not quote it. Regenerate with disk-magician snapshot.snapshot_coverage_pct < 70 or snapshot_warning == "low_coverage" → snapshot is incomplete. Use raw du -sh ~/.[!.]* ~/* instead (or disk_audit.sh --live).timeout_keys is non-empty → those entries are null in the JSON (NOT zero). Re-measure them directly: du -sh ~/.gemini etc.null ≠ empty dir. It means du timed out. Re-measure.Run DISK_MAGICIAN_CONFIG=~/projects_other/user_scope/scripts/disk_magician_config.json disk-magician snapshot --discover to scan ~/.[!.]* and ~/* for dirs >5 GB not currently in the monitored config. If new entries appear, add them to ~/projects_other/user_scope/scripts/disk_magician_config.json.
Run ./scripts/disk_audit.sh. It auto-resolves the current host's snapshot and prints, with no live du over big home dirs:
Source/Coverage/Age header so you can see staleness at a glance.disk_history.sh --days 7 --regressions — this is how you answer "why did my disk grow?" (e.g. it surfaces Docker.raw creeping +2–4 GB/snapshot).This replaces the old slow "du over ~/Library and ~/projects" path. Only reach for live measurement to verify a specific delete candidate:
./scripts/disk_audit.sh --live → re-measure everything with du (slow; use when coverage <70% or snapshot is stale)./scripts/disk_audit.sh --clean --dry-run → show the cleanup candidates that --clean would act on, without deletingAfter user approves dry-run output:
./scripts/disk_audit.sh --clean
Includes Docker system prune candidates:
./scripts/disk_audit.sh --clean-all
VM disk images on macOS are sparse files with two sizes:
stat -f%z): logical max — can be 926 GB even when nearly emptydu -sk): actual blocks on diskAlways use du -sk for these. Never stat. The disk-magician snapshot generator already uses du -sk exclusively. To verify a sparse file's real size manually:
du -h ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw # allocated
docker system df # itemized
Docker.raw grows monotonically and never auto-shrinks (high-water mark). Two reclaim paths, by daemon health:
docker system df -v (inspect volumes first) → docker system prune -a --volumes + docker builder prune --keep-storage 5g (frees inside the VM ext4) → docker run --privileged --pid=host docker/desktop-reclaim-space (official host-level shrink of the .raw; Docker Desktop 4.28+ with Apple Virtualization also auto-TRIMs). This is the default — it lets you keep named volumes.docker … command is blocked, so selective prune is impossible. The only reclaim is to delete the whole Docker.raw while Docker is stopped → rm it, Docker recreates an empty one on next launch. Reclaims the full allocated size instantly but destroys all images, containers, build cache, and named volumes (no review possible) — requires explicit user approval. Confirm ps aux | grep -i '[d]ocker' shows no backend first, then rm. (2026-06-09: reclaimed 132 GiB this way after the daemon wedged.)Daemon-won't-start signature (GUI wedge, needs Mac reboot): in ~/Library/Containers/com.docker.docker/Data/log/host/com.docker.backend.log, opening tray: starting electron: sending file descriptors: broken pipe → monitor exited: exit status 150. The gvisor: unable to accept vfkit connection: invalid magic length line is a downstream symptom, not the cause — the Electron tray failure cancels the backend before the VM starts. A full reboot clears the wedged GUI state; the data is not corrupt.
| Pattern | Where | Typical size | Notes |
|---|---|---|---|
| IDE worktrees with full project copies | ~/.gemini/antigravity/worktrees/, ~/.ao-sessions/<sid>/.gemini/antigravity/worktrees/ | 50–150 GB | Two-level nesting pattern: AO sessions that used Antigravity as their agent store a full .gemini/antigravity/ subtree inside the session dir. That subtree contains a worktrees/worktree_<project>/ dir with one sub-worktree per PR task — each sub-worktree is a complete project clone + venv (~1 GB). Example: ao-5847/.gemini/antigravity/worktrees/worktree_worldarchitect/ held 79 sub-worktrees = 43.7 GB. Don't delete while Antigravity IDE is running (ps aux | grep -i antigravity). Check mtime <14d → needs WORKTREE APPROVED. |
| SQLite repair backups | ~/.codex/*.codex-repair-*.bak | 1–10 GB | Created during state DB repair. Safe to delete if >5 days old AND original DB is healthy. |
| Single runaway logs | ~/Library/Logs/cmux-focus.log, ~/Library/Logs/com.openai.codex/* | 100–800 MB | Truncate with : > path to keep inode open for active writer. |
| Old Python venvs in abandoned projects | ~/projects/*/venv, ~/projects_other/*/.venv | 50–700 MB each | Find with find ~/projects -name '.venv' -mtime +90. Always check git log -1 in parent dir first — only prune from projects with no commits in 90+ days. |
| Updater app caches | ~/Library/Caches/*-updater | 200–700 MB | Safe — apps re-download. |
__pycache__ accumulation | Across projects | 1–2 GB | Always safe to delete (find ~/projects -name __pycache__ -mtime +30 -exec rm -rf {} +). |
df -h /)disk_audit.sh --clean to proceed"du, df, lsof for in-use check)rm -rf directly — go through disk_audit.shnull (post-update). Cross-check.du -sk or docker system df.ps aux | grep -i antigravity and lsof +D ~/.gemini first.git log -1 --format=%ai ≥90 days old.~/.codex/sessions* — these are PROTECTED per repo CLAUDE.md.backup/ holds snapshots from multiple machines (Mac/, Jeff-Ubuntu/, jeffreys-macbook-pro/). A naive backup/*/disk_snapshot.json glob picks the first alphabetical (stale Ubuntu) file → garbage coverage (52254%), null docker_raw, "1 snapshot" history. Always go through resolve_snapshot_path (newest timestamp wins); the scripts now do this automatically.disk-magician CLI (installed at ~/.local/bin/disk-magician); the local disk_snapshot.sh was removed in favor of it~/projects_other/user_scope/scripts/disk_{audit,usage_alert,history}.sh, snapshot_lib.sh (host resolver)~/projects_other/user_scope/scripts/disk_magician_config.json (51-dir coverage), passed via DISK_MAGICIAN_CONFIGcom.$USER.disk-usage-alert.plist (threshold default 787 GB)backup-home.sh calls disk-magician snapshot --output backup/<host>/disk_snapshot.json every 30 min, commits JSON to git~/projects_other/user_scope/tests/test_snapshot_lib.py (host resolution); generator parity is covered upstream in the disk_magician repodisk audit, disk cleanup, clean disk, disk space, reclaim disk, disk usage, snapshot coverage, what's eating my disk
npx claudepluginhub jleechanorg/claude-commands --plugin claude-commandsRuns disk usage diagnostics, growth history logs, and automated cache/temp cleanup on development machines via disk_magician.sh.
Identifies and cleans disk hogs like Rust target/, node_modules, Python venvs, git garbage, Docker images, Homebrew caches, and hidden temps. Use when disk space is low or full.
Automates macOS disk cleanup and memory monitoring with Mole-based safety guards and LaunchAgent alerting. Responds to low disk space, kernel panics, and vm-compressor shortages on Apple Silicon.