Disk Space Cleanup
Reclaim disk space with a safety-first workflow: investigate first, run obvious low-risk cleanup wins, then do targeted analysis for larger opportunities.
Bundled helpers:
scripts/rust_target_dirs.py: inventory and guarded deletion for explicit Rusttarget/directoriesreferences/rust-target-roots.txt: machine-specific roots for Rust artifact scansreferences/ignore-paths.md: machine-specific excludes fordu/ncdu
Execution Default
- Start with non-destructive investigation and quick sizing.
- Prioritize easy wins first (
nix-collect-garbage, container prune, Cargo artifacts). - Propose destructive actions with expected impact before running them.
- Run destructive actions only after confirmation, unless the user explicitly requests immediate execution of obvious wins.
- Capture new reusable findings by updating this skill before finishing.
Workflow
- Establish current pressure and biggest filesystems
- Run easy cleanup wins
- Inventory Rust build artifacts and clean the right kind of target
- Investigate remaining heavy directories with
ncdu/du - Investigate
/nix/storeroots when large toolchains still persist - Summarize reclaimed space and next candidate actions
- Record new machine-specific ignore paths, Rust roots, or cleanup patterns in this skill
Step 1: Baseline
Run a quick baseline before deleting anything:
df -h /
df -h /home
df -h /nix
Optionally add a quick home-level size snapshot:
du -xh --max-depth=1 "$HOME" 2>/dev/null | sort -h
Step 2: Easy Wins
Use these first when the user wants fast, low-effort reclaiming:
sudo -n nix-collect-garbage -d
sudo -n docker system prune -a
sudo -n podman system prune -a
Notes:
- Add
--volumesonly when the user approves deleting unused volumes. - Re-check free space after each command to show impact.
- Prefer
sudo -nfirst so cleanup runs fail fast instead of hanging on password prompts. - If root is still tight after these, run app cache cleaners before proposing raw
rm -rf:
uv cache clean
pip cache purge
yarn cache clean
npm cache clean --force
Step 3: Rust Build Artifact Cleanup
Do not start with a blind find ~ -name target or with hard-coded roots that may miss worktrees. Inventory explicit target/ directories first using the bundled helper and the machine-specific root list in references/rust-target-roots.txt.
Inventory the biggest candidates:
python /home/imalison/dotfiles/dotfiles/agents/skills/disk-space-cleanup/scripts/rust_target_dirs.py list --min-size 500M --limit 30
Focus on stale targets only:
python /home/imalison/dotfiles/dotfiles/agents/skills/disk-space-cleanup/scripts/rust_target_dirs.py list --min-size 1G --older-than 14 --output tsv
Use cargo-sweep when the repo is still active and you want age/toolchain-aware cleanup inside a workspace:
nix run nixpkgs#cargo-sweep -- sweep -d -r -t 30 <workspace-root>
nix run nixpkgs#cargo-sweep -- sweep -r -t 30 <workspace-root>
nix run nixpkgs#cargo-sweep -- sweep -d -r -i <workspace-root>
nix run nixpkgs#cargo-sweep -- sweep -r -i <workspace-root>
Use direct target/ deletion when inventory shows a discrete stale directory, especially for inactive repos or project-local worktrees. The helper only deletes explicit paths named target that are beneath configured roots and a Cargo project:
python /home/imalison/dotfiles/dotfiles/agents/skills/disk-space-cleanup/scripts/rust_target_dirs.py delete /abs/path/to/target
python /home/imalison/dotfiles/dotfiles/agents/skills/disk-space-cleanup/scripts/rust_target_dirs.py delete /abs/path/to/target --yes
Recommended sequence:
- Run
rust_target_dirs.py listto see the largesttarget/directories across~/Projects,~/org,~/dotfiles, and other configured roots. - For active repos, prefer
cargo-sweepfrom the workspace root. - For inactive repos, abandoned branches, and
.worktrees/*/target, prefer guarded direct deletion of the explicittarget/directory. - Re-run the list command after each deletion round to show reclaimed space.
Machine-specific note:
- Project-local
.worktrees/*/targetdirectories are common cleanup wins on this machine and are easy to miss with the old hard-coded workflow.
Step 4: Investigation with ncdu and du
Avoid mounted or remote filesystems when profiling space. Load ignore patterns from references/ignore-paths.md.
Use one-filesystem scans to avoid crossing mounts:
ncdu -x "$HOME"
sudo ncdu -x /
When excluding known noisy mountpoints:
ncdu -x --exclude "$HOME/keybase" "$HOME"
sudo ncdu -x --exclude /keybase --exclude /var/lib/railbird /
If ncdu is missing, use:
nix run nixpkgs#ncdu -- -x "$HOME"
For quick, non-blocking triage on very large trees, prefer bounded probes:
timeout 30s du -xh --max-depth=1 "$HOME/.cache" 2>/dev/null | sort -h
timeout 30s du -xh --max-depth=1 "$HOME/.local/share" 2>/dev/null | sort -h
Machine-specific heavy hitters seen in practice:
~/.cache/uvcan exceed 20G and is reclaimable withuv cache clean.~/.cache/spotifycan exceed 10G; treat as optional app-cache cleanup.~/.local/share/Trashcan exceed several GB; empty only with user approval.
Step 5: /nix/store Deep Dive
When /nix/store is still large after GC, inspect root causes instead of deleting random paths.
Useful commands:
nix path-info -Sh /nix/store/* 2>/dev/null | sort -h | tail -n 50
nix-store --gc --print-roots
Avoid du -sh /nix/store as a first diagnostic; it can be very slow on large stores.
For repeated GHC/Rust toolchain copies:
nix path-info -Sh /nix/store/* 2>/dev/null | rg '(ghc|rustc|rust-std|cargo)'
nix-store --gc --print-roots | rg '(ghc|rust)'
Resolve why a path is retained:
/home/imalison/dotfiles/dotfiles/lib/functions/find_store_path_gc_roots /nix/store/<store-path>
nix why-depends <consumer-store-path> <dependency-store-path>
Common retention pattern on this machine:
- Many
.direnv/flake-profile-*symlinks under~/Projectsand worktrees keepnix-shell-env/ghc-shell-*roots alive. - Old taffybar constellation repos under
~/Projectscan pin large Haskell closures through.direnvandresultsymlinks. Deletinggtk-sni-tray,status-notifier-item,dbus-menu,dbus-hslogger, andgtk-strutand then rerunningnix-collect-garbage -dreclaimed about 11G of store data in one validated run. find_store_path_gc_rootsis especially useful for proving GHC retention: many largeghc-9.10.3-with-packagespaths are unique per project, while the baseghc-9.10.3and docs paths are shared.- Quantify before acting:
find ~/Projects -type l -path '*/.direnv/flake-profile-*' | wc -l
find ~/Projects -type d -name .direnv | wc -l
nix-store --gc --print-roots | rg '/\\.direnv/flake-profile-' | awk -F' -> ' '{print $1 \"|\" $2}' \
| while IFS='|' read -r root target; do \
nix-store -qR \"$target\" | rg '^/nix/store/.+-ghc-[0-9]'; \
done | sort | uniq -c | sort -nr | head
- If counts are high and the projects are inactive, propose targeted
.direnvcleanup for user confirmation.
Safety Rules
- Do not delete user files directly unless explicitly requested.
- Prefer cleanup tools that understand ownership/metadata (
nix,docker,podman,cargo-sweep) overrm -rf. - For Rust build artifacts, deleting an explicit directory literally named
targetis acceptable when it is discovered by the bundled helper; Cargo will rebuild it. - Present a concise “proposed actions” list before high-impact deletes.
- If uncertain whether data is needed, stop at investigation and ask.
Learning Loop (Required)
Treat this skill as a living playbook.
After each disk cleanup task:
- Add newly discovered mountpoints or directories to ignore in
references/ignore-paths.md. - Add newly discovered Rust repo roots in
references/rust-target-roots.txt. - Add validated command patterns or caveats discovered during the run to this
SKILL.md. - Keep instructions practical and machine-specific; remove stale guidance.
微信扫一扫