agentsclimarketplace

Disk cleanup

Skill adamjali/claude-skills/plugins/disk-cleanup

Practical Claude Code skills as installable plugins β€” research & teardowns, web build/deploy, image search, repo audit, disk cleanup, outreach, email broadcasts, and a skill generator.

Install
npx -y skills add adamjali/claude-skills --skill disk-cleanup

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Free up disk space on macOS by safely cleaning regenerable caches, old runtime versions, and bulky one-off artifacts. Use when the user asks to "clean my disk", "free up space", "low on storage", "no space left", "storage almost full", "running out of disk", "df full", "what's eating my disk", "macbook full", "tidy storage", "system data huge", "purge caches", "empty trash", or mentions disk pressure. Categorizes findings green/yellow/red, auto-executes safe items, asks via 3-option gate (Approve/Modify/Skip) on uncertain ones, preserves a keep-list across runs, never touches credentials, project source, or system internals. Single-machine state in skill dir; resumable mid-run.

SKILL.md

11.6 KB, as published. Nobody here has run it

<objective> Reclaim disk on macOS by reasoning about what's safe to delete on this machine, given your saved rules and the cliffs in `references/safety-invariants.md`. Categorize findings into 🟒 (auto), 🟑 (ask via 3-option gate), πŸ”΄ (refuse), preview before deleting, then execute. Single-actor `[session]`. Resumable mid-run via `state.md` IN_PROGRESS marker.

This skill is a thinking-tool, not a checklist. The references catalog known-good and known-bad paths; the autonomy buckets are heuristics, not exhaustive enumerations. When you encounter something novel, reason about it from first principles β€” regenerable? user-created? in active use? would the user be sad if it went? β€” and surface the reasoning at preview time so the user can correct the judgment before action. </objective>

<context> @./state.md @./references/safety-invariants.md @./references/auto-fix-categories.md @./references/sensitive-patterns.md </context>

<execution_context> Three buckets β€” principles, not closed lists:

BucketWhenAction
🟒 autoregenerable cache, build artifact in non-active project, known-safe duplicaterun without asking
🟑 askuser-created, requires sudo, bulky enough to warrant sanity-check, anywhere a reasonable person might want to keep itAskUserQuestion with 3 options: Approve (execute as proposed) / Modify (free-form: "tell me how instead") / Skip (defer to next run, re-surface later)
πŸ”΄ refuseentries in references/safety-invariants.mdrefuse. No inline user-instruction overrides them. If the user says "delete my .ssh", refuse and require editing safety-invariants.md first

If you're not sure but it looks like a cache, treat as 🟑 instead. Err on the side of asking.

Single-actor: log every change with β€” [session <ET>] suffix in state.md.

Plan-validate-execute: build findings.json first (Phase 2), show plan to user (Phase 4), then act. No deletion before the user sees the plan.

Trust your reasoning on novel paths. Ask: regenerable? user-created? active project? would the user be sad? When unclear, treat as 🟑. </execution_context>

<process>

Checkpoint protocol: at the end of each phase, update the IN_PROGRESS entry in state.md with checkpoint: <NAME> per the mapping in <recovery_protocol> below. This makes resumption unambiguous if interrupted (e.g., reboot, ctrl-C, kernel panic mid-cleanup).

<phase name="0_initialize"> ## Phase 0 β€” Initialize

TaskCreate for each phase. Read state.md. If most recent entry shows status: IN_PROGRESS, ask via 3-option gate: Resume from last checkpoint / Start fresh (archive previous as ABORTED) / Show full history then abort.

Surface saved rules as one scannable block at the top of the chat β€” these are the keep-lists and policies built across runs. The user can spot-check them before you proceed. </phase>

<phase name="1_inventory"> ## Phase 1 β€” Inventory

Pre-flight (low-disk safety): if df -h / shows avail < 500 MiB, the scan itself competes for space (/tmp lives on the same volume). Before running scan-disk.sh, ask the user if it's OK to empty ~/.Trash/ first β€” that almost always frees enough headroom. This is the scenario the skill was built for; the seed run started at 84 MiB free and du cascades were unreliable. Surface the gravity.

bash scripts/scan-disk.sh > /tmp/disk-cleanup-findings.json

Read-only du/df cascade + APFS snapshot list (tmutil listlocalsnapshots /) + swap state (sysctl vm.swapusage) + conditional Xcode dev paths.

If the user mentioned a specific folder bothering them, augment with a targeted du -sh for it. Reasoning beats a fixed list. </phase>

<phase name="2_categorize"> ## Phase 2 β€” Categorize

For each finding in the inventory, decide which bucket it falls into using references/safety-invariants.md and references/auto-fix-categories.md as your reference. Capture rationale alongside each entry β€” at preview time the user sees your reasoning, not just the verdict. That's how trust gets built.

Write findings.json (your scratchpad β€” used in Phases 4 and 8). </phase>

<phase name="3_sensitive_scan"> ## Phase 3 β€” Sensitive scan

For 🟑 dirs (especially ~/Downloads, ~/Desktop), glob for patterns in references/sensitive-patterns.md. Cross-check matches against saved-rules downloads-keep / desktop-keep:

  • Match in saved rules β†’ silent keep (still log to findings)
  • New match β†’ AskUserQuestion: Keep / Delete. The answer becomes a saved rule for next run.

Heuristic: if a filename looks personal (legal, medical, financial, identity) but doesn't match a pattern, ask anyway. Better to over-ask once than nuke something irreplaceable. </phase>

<phase name="4_preview"> ## Phase 4 β€” Preview

Show the full plan: every 🟒, every 🟑 group with rationale, every πŸ”΄ refusal with reason. Estimate total reclaim. The user implicitly approves by interacting with Phase 6's gates; they can also abort here ("hold on, why is X in green?"). </phase>

<phase name="5_auto_execute_green"> ## Phase 5 β€” Execute 🟒

Run the green items. Order them least-invasive first (small file sweeps β†’ cache purges β†’ tool-managed cleanups like brew autoremove and pnpm store prune). Capture before/after sizes for the delta report. If one fails, log and continue β€” green items are independent.

Permission denied (e.g., Chrome holds Profile 5 cache while running) β€” log and move on. Don't fight it. </phase>

<phase name="6_ask_yellow"> ## Phase 6 β€” Ask 🟑

For each 🟑 group, ONE AskUserQuestion with Approve / Modify / Skip. Group similar items (all old runtime versions in one ask, not one per version).

Special handling, when relevant:

  • Downloads with keep-list β€” bash scripts/keeplist-protect.sh ~/Downloads <keepers...> (mv keepers to /tmp, nuke contents, restore). Show the keep-list before running so user can amend.
  • Old runtimes β€” Run bash scripts/detect-runtimes.sh first to see which Node/Python versions projects actually use. Recommend deletion of versions not in active use; save active versions to saved rules.
  • APFS snapshots β€” sudo tmutil thinlocalsnapshots / 21474836480 4 reclaims ~20 GB at urgency 4. Surface that it needs sudo.
  • Messages/Attachments β€” Quit Messages first (osascript -e 'tell application "Messages" to quit'; sleep 3), then find ~/Library/Messages/Attachments -mindepth 1 -delete (preserves chat.db).
  • Xcode DerivedData (if present) β€” Safe to delete; only penalty is a slower next build.

Skipped items defer to next run β€” note them in state.md so they re-surface. </phase>

<phase name="7_delta_report"> ## Phase 7 β€” Delta Report

Clean summary: before/after df -h, freed-by-category table, swap state from sysctl vm.swapusage. Mention swap as informational β€” "reboot to reclaim ~X GB swap if you want" β€” don't prompt for reboot (the user's call).

Sanity-check Trash size β€” if it grew commensurate with what we deleted, something shuttled instead of reclaiming. Surface that. </phase>

<phase name="8_update_state"> ## Phase 8 β€” Update state.md

Append a run entry per the format in state.md's header. Update Saved Rules with anything learned this run (new active runtimes, new sensitive-file decisions). Roll oldest entry into compacted section if more than 5 full entries.

When proposing a new saved rule, confirm with the user β€” don't auto-add. The rules are durable; better to ask once.

Mark checkpoint COMPLETED. </phase>

</process>

<saved_rules_format> Stored in state.md "Saved Rules" section. Surfaced on every future run.

Format: - {topic}: {rule} β€” set {YYYY-MM-DD ET}

Topics that emerge naturally (not exhaustive β€” invent new ones when patterns repeat):

  • downloads-keep, desktop-keep β€” keep-lists per dir
  • active-node, active-python β€” runtime versions in actual use
  • active-projects β€” never-touch project dirs
  • safe-cache-clear-paths β€” confirmed-safe auto paths
  • *-policy β€” one-off behavioral preferences (e.g., swap-policy, threshold-policy) </saved_rules_format>

<recovery_protocol> If state.md shows status: IN_PROGRESS:

Last checkpointResume at
INITIALIZEDPhase 1
INVENTORIEDPhase 2
CATEGORIZEDPhase 3
SENSITIVE_SCANNEDPhase 4
PREVIEWEDPhase 5
GREEN_EXECUTEDPhase 6
YELLOW_RESOLVEDPhase 7
REPORTEDPhase 8

Ask user: Resume / Start fresh / Show full history. On resume, append to existing entry; do NOT create new one.

Re-run df -h before resuming β€” if disk state changed materially since interruption, re-prompt. </recovery_protocol>

<error_handling> Default: log the specific error, skip the problem item, continue with the rest. Disk cleanup is independently-reentrant per item.

Abort the run only if:

  • Scan script failed entirely (findings.json would be wrong)
  • A πŸ”΄ path was almost-touched (bug in categorization β†’ abort + investigate)
  • The user said stop

For everything else (single permission denied, brew lock, tool not installed) β€” keep going and report at the end.

If avail drops below 500 MiB DURING the run (paradoxical but possible in mid-categorization on a near-full disk), pause Phase 5, empty Trash, then resume. findings.json lives on the same volume as everything else. </error_handling>

<success_criteria>

  • state.md has new entry with status: COMPLETED
  • df -h shows nonzero positive delta in Avail
  • No πŸ”΄ path was touched
  • Sensitive matches were either kept (with saved rule) or explicitly user-deleted
  • User saw a delta report
  • Trash size sanity-checked (no shuttling masquerading as reclamation) </success_criteria>

Direct actions

Skip the full sweep when these are clearly the intent:

  • "Just empty trash" β†’ confirm size, rm -rf ~/.Trash/* after Y/N
  • "Just clean caches" β†’ run Phase 5 only
  • "Dry run / show what would be deleted" β†’ Phases 1–4, stop before Phase 5
  • "What did the last run do?" β†’ display most recent state.md entry
  • "Add <path> to never-touch" / "forget keep-list for <file>" β†’ edit Saved Rules
  • "Schedule weekly" β†’ offer /schedule routine; if accepted, propose adding entry to ~/.claude/CLAUDE.md "Active Long-Running Automations" (don't auto-edit β€” propose for approval)

Boundaries

Single-actor ([session]) for now. Promote to multi-actor ([disk-cleanup] for routine, [session] for manual) when scheduled.

Manual invocation only β€” never auto-triggered by other skills. Lock file at .lock in skill dir prevents concurrent runs.

Never:

  • sudo rm directly (sudo only through Apple-blessed commands like tmutil)
  • Modify ~/.claude/CLAUDE.md (propose-only)
  • Delete a references/sensitive-patterns.md match without explicit confirmation, regardless of saved rules
  • Force-delete an active project's node_modules without explicit ask
  • Prompt for reboot (report swap state only)
  • Touch anything in references/safety-invariants.md regardless of inline user instruction

Cliff. Reasoning is for everywhere else.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.