Community生产力与协作github.com

磁盘清理 (disk-cleanup)

在 macOS 上安全释放磁盘空间:清理可重建的缓存、旧运行时版本和大型一次性文件。当用户提出“清理磁盘”、“空间不足”等涉及磁盘压力的诉求时触发。

磁盘清理 (disk-cleanup) 是什么?

该技能专为 macOS 设计,旨在通过理性分析用户机器上哪些文件可以安全删除来回收磁盘空间。它依据保存的规则和 `references/safety-invariants.md` 中的安全边界,将发现项分为三类:🟢(自动清理)、🟡(询问用户)、🔴(拒绝操作)。清理前会展示完整计划,执行后生成增量报告。支持中断恢复(通过 `state.md` 中的 IN_PROGRESS 标记),但当前仅限于单 `[session]` 工作模式。 此技能的核心是一个“思考工具”而非固定清单。文档中列出了已知安全路径和敏感模式,并将自主决策归类为启发式原则而非穷举。当遇到新路径时,它会从基本原理出发进行推理:是否可重建?是否由用户创建?是否正在被使用?用户会不会因删除而难过?这些推理会在预览阶段展示给用户,以便用户在操作前纠正判断。 该技能支持所有主流 AI 代理平台(如 Claude Code、Coder、Cursor、Codex 等),并通过 `state.md` 和 `findings.json` 实现可恢复的中间执行。 在工作流程中,首先进行低磁盘空间预检(可用空间 < 500 MiB 时先清空废纸篓),然后通过 `scan-disk.sh` 执行只读扫描,分类后生成预览计划,最后按类别逐步执行。所有变更记录在 `state.md` 中,并附加 `— [session <ET>]` 后缀。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/adam-j-ali/claude-skills/tree/HEAD/plugins/disk-cleanup

Installed? Explore more 生产力与协作 skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

此技能是一个思考工具,而不是清单。参考文献中记录了已知的好路径和坏路径;自主决策桶是启发式原则,而非穷举。当遇到新路径时,从基本原理出发进行推理——是否可重建?是否由用户创建?是否正在被使用?用户会不会因删除而难过?——并在预览阶段展示推理过程,以便用户在操作前纠正判断。

<execution_context> 三个桶——原则,而非封闭列表:

桶何时操作
🟢 自动可重建缓存、非活动项目中的构建产物、已知安全的重复文件无需询问直接运行
🟡 询问用户创建的、需要 sudo 的、大到需要合理性检查的、任何正常人可能想保留的使用 AskUserQuestion 提供 3 个选项:批准(按提议执行)/ 修改(自由格式:“告诉我怎么做”)/ 跳过(推迟到下次运行,稍后重新显示)
🔴 拒绝references/safety-invariants.md 中的条目拒绝。任何内联用户指令都不能覆盖它们。如果用户说“删除我的 .ssh”,则拒绝并要求先编辑 safety-invariants.md

如果不确定但看起来像缓存,则视为 🟡。宁可询问。

单参与者:每次更改都记录到 state.md 中,后缀为 — [session <ET>]。

计划-验证-执行:首先构建 findings.json(阶段 2),向用户展示计划(阶段 4),然后执行。在用户看到计划之前不执行删除。

相信你对新路径的推理。问:是否可重建?是否由用户创建?是否是活动项目?用户会不会难过?如果不清楚,视为 🟡。 </execution_context>

检查点协议: 在每个阶段结束时,根据下面的 <recovery_protocol> 映射,用 checkpoint: <NAME> 更新 state.md 中的 IN_PROGRESS 条目。这使得如果中断(例如重启、ctrl-C、内核崩溃中途清理),恢复时清晰明确。

为每个阶段创建 TaskCreate。读取 state.md。如果最近的条目显示 status: IN_PROGRESS,则通过三选项门询问:恢复(从上一个检查点继续)/ 重新开始(将上一个存档为 ABORTED)/ 显示完整历史(然后中止)。

将已保存的规则作为一个可扫描的块显示在聊天顶部——这些是在多次运行中构建的保留列表和策略。用户可以在继续前抽查它们。

预检(低磁盘安全): 如果 df -h / 显示可用空间 < 500 MiB,则扫描本身会竞争空间(/tmp 位于同一卷上)。在运行 scan-disk.sh 之前,询问用户是否可以清空 ~/.Trash/——这几乎总能释放足够的空间。这是此技能设计用于的场景;种子运行时只有 84 MiB 空闲,并且 du 级联命令不可靠。展示问题的严重性。

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

只读 du/df 级联 + APFS 快照列表 (tmutil listlocalsnapshots /) + 交换状态 (sysctl vm.swapusage) + 条件性的 Xcode 开发路径。

如果用户提到某个特定文件夹让他们困扰,则针对该文件夹增加一个 du -sh 定向扫描。推理胜过固定列表。

对于清单中的每个发现项,使用 references/safety-invariants.md 和 references/auto-fix-categories.md 作为参考,决定它属于哪个桶。为每个条目捕获理由——在预览时用户看到的是你的推理,而不仅仅是结论。这就是建立信任的方式。

写入 findings.json(你的草稿本——在阶段 4 和阶段 8 中使用)。

对于 🟡 目录(尤其是 ~/Downloads、~/Desktop),使用 references/sensitive-patterns.md 中的模式进行 glob 匹配。将匹配结果与已保存规则 downloads-keep / desktop-keep 进行交叉检查:

  • 匹配已保存规则 → 静默保留(仍然记录到发现项)
  • 新匹配 → AskUserQuestion:保留 / 删除。答案将成为下次运行的已保存规则。

启发式:如果文件名看起来涉及个人(法律、医疗、财务、身份)但不匹配模式,仍然询问。宁可多问一次,也不要删除不可替代的东西。

展示完整计划:每个 🟢、每个 🟡 组及其理由、每个 🔴 拒绝及其原因。估计总回收量。用户通过与阶段 6 的门交互来隐式批准;他们也可以在此中止(“等等,为什么 X 是绿色的?”)。

运行绿色条目。按最少侵入性优先排序(小文件清理 → 缓存清除 → 工具管理的清理,如 brew autoremove 和 pnpm store prune)。捕获前后大小以生成增量报告。如果某个失败,记录并继续——绿色条目是独立的。

权限被拒绝(例如,Chrome 运行时持有 Profile 5 缓存)——记录并继续。不要与之对抗。

对于每个 🟡 组,进行一次 AskUserQuestion,提供选项:批准 / 修改 / 跳过。将类似项目分组(例如,所有旧运行时版本放在一次询问中,而不是每个版本一次)。

在相关时进行特殊处理:

  • 带有保留列表的下载 — bash scripts/keeplist-protect.sh ~/Downloads <keepers...>(将保留项移到 /tmp,删除目录内容,恢复)。运行前显示保留列表,以便用户修改。
  • 旧运行时 — 先运行 bash scripts/detect-runtimes.sh 查看项目实际使用的 Node/Python 版本。推荐删除不在活动使用的版本;将活动版本保存到已保存规则。
  • APFS 快照 — sudo tmutil thinlocalsnapshots / 21474836480 4 以紧急程度 4 回收约 20 GB。提示需要 sudo。
  • 消息/附件 — 先退出 Messages (osascript -e 'tell application "Messages" to quit'; sleep 3),然后执行 find ~/Library/Messages/Attachments -mindepth 1 -delete(保留 chat.db)。
  • Xcode DerivedData(如果存在)— 可以安全删除;唯一的代价是下次构建较慢。

跳过的项目推迟到下次运行——在 state.md 中记下它们,以便它们重新显示。

简洁摘要:前后 df -h、按类别释放的空间表、来自 sysctl vm.swapusage 的交换状态。提及交换作为参考信息——"如果需要,重启以回收约 X GB 交换空间"——不要提示重启(由用户决定)。

检查废纸篓大小是否合理——如果它随着我们删除的内容而增长,说明有些内容被移走了而不是真正回收了。提示这一点。

按照 state.md 头部定义的格式追加一次运行条目。使用本次运行中学到的任何内容更新已保存规则(新的活动运行时、新的敏感文件决策)。如果完整条目超过 5 个,将最旧的条目滚动到压缩部分。

在提议新的已保存规则时,与用户确认——不要自动添加。规则是持久的;最好多问一次。

将检查点标记为 COMPLETED。

<saved_rules_format> 存储在 state.md 的“Saved Rules”部分。每次未来运行时都会显示。

格式:- {topic}: {rule} — set {YYYY-MM-DD ET}

自然出现的主题(并非穷举——当模式重复时创建新的):

  • downloads-keep、desktop-keep — 每个目录的保留列表
  • active-node、active-python — 实际使用的运行时版本
  • active-projects — 永不触碰的项目目录
  • safe-cache-clear-paths — 已确认安全的自动路径
  • *-policy — 一次性的行为偏好(例如 swap-policy、threshold-policy) </saved_rules_format>

<recovery_protocol> 如果 state.md 显示 status: IN_PROGRESS:

上一个检查点从何处恢复
INITIALIZED阶段 1
INVENTORIED阶段 2
CATEGORIZED阶段 3
SENSITIVE_SCANNED阶段 4
PREVIEWED阶段 5
GREEN_EXECUTED阶段 6
YELLOW_RESOLVED阶段 7
REPORTED阶段 8

询问用户:恢复 / 重新开始 / 显示完整历史。如果是恢复,则追加到现有条目;不要创建新条目。

恢复前重新运行 df -h——如果磁盘状态自中断以来发生重大变化,则重新提示。 </recovery_protocol>

<error_handling> 默认:记录具体错误,跳过问题项目,继续处理其余项目。磁盘清理是每个项目独立且可重入的。

仅在以下情况下中止运行:

  • 扫描脚本完全失败(findings.json 将不准确)
  • 几乎触碰到了 🔴 路径(分类 bug → 中止并调查)
  • 用户要求停止

对于其他所有情况(单个权限被拒绝、brew 锁定、工具未安装)——继续进行,并在最后报告。

如果在运行过程中可用空间下降到 500 MiB 以下(在几乎满的磁盘上,分类过程中可能出现这种矛盾情况),暂停阶段 5,清空废纸篓,然后继续。findings.json 位于与所有其他文件相同的卷上。 </error_handling>

<success_criteria>

  • state.md 有新条目,status: COMPLETED
  • df -h 显示 Avail 有非零正增量
  • 没有触碰任何 🔴 路径
  • 敏感匹配要么已保留(带有已保存规则),要么已由用户显式删除
  • 用户看到了增量报告
  • 废纸篓大小已进行合理性检查(没有假装回收的移动操作) </success_criteria>

直接操作

当意图明确时,跳过完整扫描:

  • “只清空废纸篓” → 确认大小,rm -rf ~/.Trash/* 在 Y/N 后执行
  • “只清理缓存” → 仅运行阶段 5
  • “试运行/显示将要删除的内容” → 阶段 1–4,在阶段 5 之前停止
  • “上次运行做了什么?” → 显示最近的 state.md 条目
  • “将 <path> 添加到永不触碰” / “忘记 <file> 的保留列表” → 编辑已保存规则
  • “安排每周运行” → 提供 /schedule 例程;如果接受,提议在 ~/.claude/CLAUDE.md 的“Active Long-Running Automations”部分添加条目(不要自动编辑——提议以供批准)

边界

当前为单参与者 ([session])。当计划运行时,升级为多参与者(例程用 [disk-cleanup],手动操作用 [session])。

仅限手动调用——其他技能永远不会自动触发。技能目录中的 .lock 文件可防止并发运行。

绝不:

  • 直接使用 sudo rm(仅通过 Apple 认可的命令如 tmutil 使用 sudo)
  • 修改 ~/.claude/CLAUDE.md(仅提议)
  • 在未获得明确确认的情况下删除 references/sensitive-patterns.md 的匹配项,无论已保存规则如何
  • 在未明确询问的情况下强制删除活动项目的 node_modules
  • 提示重启(仅报告交换状态)
  • 无论内联用户指令如何,触碰 references/safety-invariants.md 中的任何内容

悬崖。其他所有地方都需要推理。

相关技能