跳到主要内容
知仓学习社ZHICANG

disk-cleanup

Scan and clean macOS caches, package-manager data, crash dumps, and app caches to reclaim disk space. Deterministic — a config registry (targets.jso…

执行命令严重 0 · 高危 7glebis/claude-skills

它会碰到什么

扫了多少9 个文本文件,46 KB
它会碰到什么执行命令
命中总数7 处
命中统计严重 0 · 高 7 · 中 0 · 低 0
逐条看命中(7 条严重或高危)
  • scripts/clean.py:30exec-spawn
    return subprocess.run(["pgrep", "-x", app], capture_output=True, text=True).returncode == 0
  • scripts/clean.py:41exec-spawn
    subprocess.run(["osascript", "-e", f'quit app "{a}"'], capture_output=True, text=True)
  • scripts/clean.py:88exec-spawn
    subprocess.run(["xcrun", "simctl", "delete", "unavailable"],
  • scripts/clean.py:148exec-spawn
    subprocess.run(t["command"], capture_output=True, text=True, timeout=300)
  • scripts/lib.py:73exec-spawn
    out = subprocess.run(["du", "-sk", str(path)], capture_output=True, text=True, timeout=120)
  • scripts/lib.py:144exec-spawn
    out = subprocess.run(["trash", *[str(p) for p in paths]], capture_output=True, text=True, timeout=300)
  • scripts/lib.py:152exec-spawn
    out = subprocess.run(

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

Disk Cleanup

Deterministic by design. All target knowledge lives in targets.json; all measuring and

deleting lives in scripts/survey.py (read-only) and scripts/clean.py (executor, **dry-run by

default). They run headless with zero dependencies** (stdlib only) — a user can run them in a

terminal without any agent. The agent's job is small: run the scripts, relay the compressed

output, and decide the handful of things that need human judgment.

The two scripts

python3 scripts/survey.py            # read-only: sizes, risk, flags, uncategorized. Touches nothing.
python3 scripts/survey.py --json     # same, machine-readable (preferred for the agent)

python3 scripts/clean.py --preset safe              # DRY-RUN plan (default — nothing deleted)
python3 scripts/clean.py --preset safe --go         # execute (safe risk only)
python3 scripts/clean.py --preset full --allow-medium --go --empty-trash   # safe+medium, then empty Trash
python3 scripts/clean.py --ids cargo-registry-cache,go-mod-cache --go       # specific targets
python3 scripts/clean.py --preset safe --skip ollama-models --go            # exclude one

trash is used for all file removal (never rm); freed space sits in Trash until emptied

(--empty-trash, or the user empties it). Sizes are du estimates — approximate on APFS.

Safety model (enforced in code, not prose)

  • Risk gating: safe runs automatically; medium needs --allow-medium; never is

refused even if named by id. advisory targets only print guidance, never execute.

  • Preflight on every trashed path: canonical realpath → must resolve under an

allowed_roots entry → must not be a symlink → never $HOME or /. Anything failing is

skipped and reported, not deleted.

  • Dry-run by default: clean.py prints the plan and touches nothing unless --go.

Agent workflow

  1. Run python3 scripts/survey.py --json. Relay the compressed summary: disk free,

safe/medium recoverable totals, any flags (e.g. crash-loop), and the top targets.

Do not dump the whole JSON.

  1. Auto-path: for a plain "clean up safe stuff", show the safe total and run

clean.py --preset safe --go (offer --empty-trash). Safe targets are regenerable.

  1. Escalate to the user ONLY for (these are genuine judgment calls the scripts deliberately

refuse to auto-decide):

  • medium targets (ML models, device support, project node_modules) — confirm before --allow-medium.

ML-model targets (ollama-models, huggingface-models) carry a last_used_days field

(newest file atime under the target, aggregate across all models in that store — not

per-model) as a "how stale is this" signal; surface it before suggesting deletion.

  • uncategorized discoveries — unknown dirs >100 MB; ask or investigate before adding.
  • advisory notes — surface them (Telegram cache, simulators via simctl, uv/tools,

Chrome whole-dir, Xcode Archives, mo clean deep-clean); never act on them automatically.

For mole-deep-clean: suggest the user run mo clean themselves (interactive TUI, permanent

deletes, sudo for system caches) — never invoke it from the agent. **Never shell out to mo

at all** (not even --dry-run): it's TUI-only and blocks waiting for a real terminal even in

dry-run mode — confirmed hanging under a piped subprocess, stdin=DEVNULL, and even a

script(1)-allocated pty. A mole flag in survey.py's output only reads the mtime of

mole's own leftover ~/.config/mole/clean-list.txt (last-run recency), never invokes it.

  • surgical Docker / simulator decisions (see below).
  1. Run clean.py with the resolved selection. Relay the result (freed_human, disk before→after).

Maintaining the registry

Add or correct targets by editing targets.json — no code change needed. Each target:

{id, category, risk, method, paths|find, regenerates, priority, note}. Methods:

  • trash — trash literal paths (globs allowed).
  • find-trash — exact-name dir sweep with a min_mb floor (crash dumps, project node_modules).
  • command — run a CLI (npm cache clean…); set scope_path so freed bytes can be measured.
  • simctlxcrun simctl delete unavailable (removes only sims for uninstalled runtimes; safe).
  • downloads-scan — config-driven (config.jsondownloads_scan): files older than age_days

whose name doesn't match exclude_patterns. The dry-run lists every file by name for review.

  • advisory — never executes; only prints guidance.

Keep installed software at risk: never (learned the hard way: uv/tools, uv/python,

~/.rustup/toolchains, ~/.bun, ~/.deno are NOT caches). Every non-advisory target's paths

must resolve under allowed_roots or preflight will (correctly) refuse them.

Customization & setup (per-machine, never committed)

config.json ships generic, public-safe defaults. Anything personal — names, family

names, a non-English tax/legal/financial vocabulary — or machine-specific goes in

config.local.json (gitignored). load_config() deep-merges it over config.json:

lists are unioned (local terms only add protection to the Downloads exclude list), scalars

override. See config.local.example.json for the shape.

Setup mode — when the user first uses the skill, asks to personalize it, or has sensitive

files in ~/Downloads, offer to build config.local.json by asking (one short batch):

  1. Names/keywords in Downloads filenames that must never be swept (own name, family names).
  2. Their language's tax/legal/financial terms (e.g. German steuer, rechnung, vertrag).
  3. Their projects directory (for the node_modules sweep) and any extra app caches.

Then write config.local.json (copy config.local.example.json and fill it in). Confirm what

was saved. Never commit it.

Per-machine paths in targets.json (allowed_roots, the node-modules-projects find root

~/ai_projects) are examples — adjust them to the user's layout. Targets whose paths don't

exist on this machine simply measure 0 and are skipped.

Still agent-driven (only what genuinely can't be deterministic)

  • Docker only — surgical and stateful: survey with docker images / docker ps -as /

docker system df -v, let the user pick per-name (docker rm/rmi/volume rm/builder prune),

or blunt docker system prune -a -f. A named volume removed = data gone; confirm by name.

(Everything else — simulators via the simctl method, Downloads via downloads-scan,

crash dumps, all caches — now runs through the scripts.)

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。