macos-cleaner
Diagnoses and safely reclaims macOS disk space. Use when a Mac is low on storage, reports “Caching needs more space,” shows large Apple Content Caching or AssetCacheManagerUtil usage, or needs analysis of caches, logs, application remnants, large or duplicate files, Docker or OrbStack, Chromium code-sign clones, Homebrew, npm, pip, Xcode, and other developer storage. Routes known suspects to targeted read-only diagnosis before broad scans, distinguishes nominal path accounting from physical release, requires an impact-and-recovery plan plus explicit confirmation before state changes, and verifies disk space and co-resident services afterward.
1How It Works & Mechanism
Ingress routing mechanism: Takes the narrowest path based on user signals—named suspect sources (Apple Content Caching / Docker / Chromium code-sign clones / specific cache directories) consult dedicated reference docs first; broad generic scans are used only when the source is truly unknown.
Choose the narrowest path that can answer the request
The safety core is a 4-phase state machine featuring 'separation of observation and mutation + precise approval gates': Observe (read-only) → Plan (pause at confirmation gate) → Execute (approved scope only) → Verify (independent read-back); phases 2 and 3 must never be collapsed into a single message.
Do not compress phases 2 and 3 into one message. A plan printed beside a cleanup command is not a confirmation gate.
Read-only diagnosis is executed via custom Python scripts (analyze_caches / analyze_dev_env / find_app_remnants / analyze_large_files / analyze_code_sign_clones) coupled with strict physical allocation accounting: du is nominal path accounting, not physical release (APFS clones share extents).
shared extents can be attributed to every path, so actual release remains unknown until deletion and `df` readback
Dual-track deletion paths: Finder Trash is preferred (recoverable deletion via osascript, though physical space is released only after emptying Trash); the legacy safe_delete.py is a permanent deletion helper with denylists and interactive confirmation, explicitly downgraded in documentation (does not Trash, does not inspect all user data roots, does not check open files).
HIGH_RISK_PATHS = frozenset( _canonical_path(path) for path in [ '/System', '/Library/Apple', '/usr', '/bin', '/sbin', '/etc', '/private/var/db', '~/.ssh', '~/.aws', '~/.gnupg', '~/Library/Keychains', ] )
Docker / OrbStack discipline: Per-object analysis (lists each image/container/volume, inspects references and library content, checks sparse file physical allocation), with database volume names (mysql/postgres/redis/mongo/mariadb) mandating content inspection before deletion can be proposed; **never use the prune family of commands**.
**Never use Docker prune-family commands.** This includes image, container, volume, system, builder, and buildx prune.
Post-verification discipline: Calculates actual reclaim from before/after df readings (never trusting deletion tool self-reports), re-checks cleaned subsystems, re-resolves PIDs and health probes for critical co-resident services, and observes at bounded intervals if APFS accounting lags or potential backfills occur; never report 'fixed' when only the exit code is known.
Never report “fixed” when only the command exit code is known. A successful cleanup requires both the intended state and the protected invariants.
2Core Capabilities
3External Dependencies
| Kind | Dependency / Endpoint |
|---|---|
| cli | df / du / lsof / pgrep / launchctl / ps(系统状态与分配测量) |
| cli | uv(运行 bundled python 脚本) |
| cli | osascript(Finder Trash 删除) |
| cli | docker(可选:per-object 分析 + 受权后的临时只读检查容器) |
| cli | mo / Mole(可选第三方全盘扫描器 github.com/tw93/Mole,需用户批准其固定宽扫描根) |
| cli | sudo AssetCacheManagerUtil / AssetCache(受权后的服务控制) |
4Recommended Governance & Evidence
- scripts/: Executes local scripts or commands: scripts/analyze_caches.py / analyze_dev_env.py / find_app_remnants.py / ana
- scripts/ 或 SKILL.md: Declares dynamic installation of external language package dependencies
- 本地工作目录: File I/O and artifact generation: ~/.macos-cleaner/{before,after}.json (cleanup_report.py snapshots)
5Second-Pass Verification
- [ok] safe_delete.py denylist 与删除逻辑 — HIGH_RISK_PATHS 含 /System、/usr、/bin、/etc、~/.ssh、~/.aws、~/.gnupg、~/Library/Keychains 等;delete_path 对 is_high_risk_path 直接拒绝;文件 unlink/目录 shutil.rmtree。
- [ok] 『观察/变更分离 + 确认门禁』在源码与文档双重存在 — SKILL.md 10 条 contract + 四相状态机 + 'Do not compress phases 2 and 3 into one message';safe_delete 每次删除前交互 input('[y/N]')。
- [ok] nominal vs physical 纪律有代码/文档支撑 — SKILL.md 明示 du 路径记账 vs df 物理读回;cleanup_report 只做 df 快照不做释放断言;safe_delete 输出 'Measured size removed' 并提示 'Physical release: verify with before/after df -k'。
- [ok] Docker prune 禁令与 per-object 纪律 — SKILL.md 六行明文禁 prune 家族;docker_analysis.md 给 --pull=never --network=none --read-only --cap-drop=ALL 的只读检查容器配方。
- [ok] 无网络/无凭证(安全结论基础) — 全目录扫描零网络调用代码、零凭证读取;Mole/AssetCacheManagerUtil 等外部工具仅在有授权与安装前提下由宿主调用。
- [ok] batch 'all' 可跳过逐项危险模式警告的注意点 — safe_delete.py batch_confirm 支持输入 'all' 直接返回全部 items(不做 danger_patterns 逐项检查,仅 denylist 兜底)——已在 risks 注明;SKILL.md 也限定该助手仅用于精确批准的非用户数据目标。
- [ok] 元数据(commit/license/stars) — 本地 HEAD == pin d5c4678cb5d4fd6acc9c922690df035dbd33d247;GitHub API:MIT、stars 1385(2026-09-09 实采)、pushed_at 2026-09-09T12:33:29Z。
6Verdict & Scenarios
2e94bb1d20bbcc55…