关于 maintaining-macos-health
面向 macOS 的磁盘与内存维护技能,适用于处理存储不足、性能异常、监控告警和应用卸载。它采用分层清理流程,并要求在执行删除前由用户查看和确认所选项目。
主要功能
- 01按信号进行磁盘与内存故障分诊
- 02提供从低风险到需讨论的分层清理流程
- 03监控磁盘、内存、Jetsam 与 CPU 异常
- 04通过交互页面查看并选择清理项目
- 05以路径验证和明确确认限制删除操作
适用场景
- 01排查磁盘空间不足或内存压力
- 02为新 Mac 配置监控与告警
- 03审阅扫描结果并确认清理项目
- 04按安全流程卸载应用或处理性能异常
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ codealive-ai/ ai-driven-development --skill maintaining-macos-health安装后在 Claude Code 中输入/maintaining-macos-health确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.gitignoreREADME.mdassets/apply-cleanup-selection.pybuild-space-scan.shcom.local.mac-health-check.plistconfig.shdisk_agent.pydisk_responses.pydisk_review.pydisk_safety.pymac-health-actionmac-health-checkmac-health-diskmole-core-1.39.0.jsonmole-exact-file.shrender-cleanup-plan.pyrender-storage-report.pystorage-tree.jsassets/space-scan/.gitignorecore.hppspace_scan.cpptest.shassets/space-scan/tests/core_tests.cppintegration_macos.pytree_macos.pyreferences/alerting.mdcleanup-tiers.mdmole-techniques.mdnever-touch.mdoptional-disk-responses.md详细介绍
维护 macOS 健康状态
macOS 磁盘和内存危机的恢复与预防手册。已通过真实案例验证:Apple Silicon 上发生 watchdog 超时内核崩溃,原因是 vm_compressor 段饱和至 100 %,同时磁盘占用超过 90 %。同一套手册也适用于日常清理或在新机器上进行首次设置。
目录
适用场景
遇到以下任一情况时使用:
- 磁盘剩余空间 < 20 %,或用户抱怨空间不足
- Watchdog 超时/内核崩溃/“no checkins from watchdogd”
- 出现新的
JetsamEvent-*.ips,并显示vm-compressor-space-shortage - “Mac 很慢”、交换空间 > 6 GB、内存压力持续处于 Critical
- 某个进程持续占用一个核心,或整台机器持续处于 CPU 饱和状态
- 用户想从头开始设置监控/警报
- 迁移到新 Mac → 恢复相同的警报器
- 一般性的“清理我的 Mac”/“检查存储空间”/“释放空间”请求
技能目录
| 文件 | 用途 |
|---|---|
references/triage.md | 前 5 分钟——判断触发了哪种信号,以及从哪个清理等级开始 |
references/cleanup-tiers.md | 分级清理手册(10 个等级,从零风险到需先讨论),可安全复制粘贴的 shell 代码块 |
references/never-touch.md | 即使使用 sudo 也绝不可删除的类别(基于 Mole 黑名单,并根据事故情况补充) |
references/mole-techniques.md | 借鉴 Mole 的做法:mo purge 的标记→目标映射、安全路径验证器、时间阈值 |
references/alerting.md | 完整的警报器设计:磁盘/内存/Jetsam 严重触发条件,以及持续 CPU 异常检测、事故生命周期、迟滞、通知器选择、安装/还原命令 |
references/optional-disk-responses.md | 首次使用时的选项、安装和操作:两项独立的自选启用功能——可用空间低于 2% 时紧急清理 Mole 缓存,以及可用空间达到或低于 5% 时生成 Codex 清理计划/页面,并精确续接会话。 |
assets/mac-health-disk、assets/disk_*.py | 需征得同意的磁盘控制器、确定性清单、受限 Codex 运行器,以及经过身份验证的本地选择/确认页面。两种模式默认均关闭。 |
assets/mole-exact-file.sh、assets/mole-core-1.39.0.json | 与 Mole 兼容且固定版本的精确文件适配器;不允许 Agent 使用通用 mo clean、sudo 或 shell 命令。 |
assets/space-scan/、assets/build-space-scan.sh | 只读批量元数据扫描器,明确排除指定目录,并提供精简的完整文件夹树;手动清单请参阅 references/storage-report.md |
assets/render-storage-report.py、assets/storage-tree.js | 将扫描器输出附加到报告;按需展开文件夹并显示最大文件 |
assets/mac-health-check | 可用于生产环境的 bash 脚本(约 250 行,兼容 bash 3.2) |
assets/mac-health-action | 后台操作分发器,用于只读的 Codex/Claude 调查,以及经明确确认后正常停止进程 |
assets/com.local.mac-health-check.plist | 使用 StartCalendarInterval 的 LaunchAgent plist(StartInterval 在笔记本电脑上有问题) |
assets/config.sh | 使用安全阈值的默认配置 |
assets/render-cleanup-plan.py | 交互式 HTML 清理计划界面。根据扫描结果 JSON 渲染分类复选框,在 127.0.0.1:18347 提供服务,打开浏览器并等待用户选择,然后将选择写入 /tmp/cleanup-selection-<ts>.json。由 Workflow A 使用。 |
assets/apply-cleanup-selection.py | 应用清理选择的唯一获准方式。从选择 JSON 读取 selected_items,并执行每个项目的 command 字段。执行受保护项覆盖检查、路径验证和兼容 Mole 的操作日志记录。防止用户选择的内容与实际删除内容不一致。支持 --dry-run。 |
操作前请阅读相关参考资料。切勿凭记忆操作这些文件——其中的细节是根据真实事故校准的,微小改动也会破坏安全性。
核心思路
- 被动监控——使用 Stats 菜单栏应用(
brew install --cask stats),及时发现问题,而不是等问题爆发。 - 主动警报,安静诊断——磁盘、内存、Jetsam 和整个系统的 CPU 饱和都属于严重问题。单个进程持续消耗 CPU 只有在长时间持续异常后才会发出静默提示;常规采样仅记录到日志中。
- 分级清理——从零风险操作(缓存、孤立数据)开始,仅在必要时升级到项目产物和需要 sudo 权限的类别。Mole 的
mo purge和mo clean是首选工具。 - 以 Mole 作为安全底线——即使手动运行 shell 命令,也要遵循 Mole 的路径验证规则:绝不删除
/System、/bin、/usr、/etc、/var/db中的内容,特定允许列表子路径除外;bin/仅限 .NET;vendor/仅限 PHP;保护 AI/密码/VPN/钥匙串 bundle ID。
标准工作流
首次交互式使用:可选磁盘响应
在 Mac 上首次实际交互式使用时(包括已安装此技能后进行升级),请阅读 references/optional-disk-responses.md,并用用户的语言分别提供这两个选项。请在常规设置前执行此操作;发生故障时,不要因此延误即时排查。请求编辑或审查此技能,并不代表同意在开发机器上启用它。后台调用绝不能提示用户注册。
- **紧急清理,可用空间 < 2%:**允许执行范围受限的 Mole 清理,删除明确获批、可重新生成的缓存,故障发生时无需再次询问。接受同意前,请说明具体配置、删除不可撤销、缓存可能需要重建或重新下载所产生的成本,以及排除项。这不等于允许执行常规
mo clean、清理项目、清空废纸篓、使用 sudo 或终止进程。 - **Agent 清理计划,可用空间 <= 5%:**允许自动启动所选 Agent、检查非机密存储元数据,并在默认浏览器中打开本地选择页面。请说明服务提供商的用量与费用,以及哪些元数据会离开 Mac。Agent 可以提出删除建议,但不能执行删除;提交仅表示选择,实际应用仍需另行确认。
分别记录每项明确答复;沉默、笼统地表示“设置监控”,或同意其中一个选项,都不代表同意另一个选项。用户拒绝的选择在不同会话和升级后仍须保留。仅在用户提出请求、换用新机器或同意范围发生实质性变化时再次询问。即使未同意这两个选项,现有监控也会继续运行。
**实现范围:**内置控制器支持固定版本的 Mole 1.39.0 适配器,以及受限的 Codex CLI 会话;后者使用与工作流 A 相同的清理计划界面。紧急清理仅涵盖旧版 Homebrew 软件包下载文件和 npm 内容缓存文件。自动规划会运行工作流 A 固定的只读批量元数据扫描、Mole clean/purge 预览、Docker 清单检查和 Downloads 审计。自动执行器的范围更窄:只能删除经控制器验证、可重新生成的缓存文件;存储映射和可能包含用户数据的发现会显示出来,但处于禁用状态,且须在之后进行交互式工作流 A 会话。请阅读参考文档、说明这些限制,并在使用 mac-health-disk configure 记录同意前,确认本地兼容性。仅安装绝不会启用任何模式。不得根据功能开发请求推断用户已同意。
A. “立即释放空间”(故障响应)
- 分诊 — 阅读
references/triage.md,确定触发了哪种信号以及紧急程度。 - 记录基线 — 运行
df -h /System/Volumes/Data并记下可用空间(GB)。 - 运行所有扫描,暂不删除 — 若要盘点大型本地磁盘,请使用捆绑的批量扫描器和
references/storage-report.md中所述的完整文件夹树;使用前先构建扫描器,并明确报告构建或扫描失败;不要悄悄改用其他扫描方式。同时运行mo clean --dry-run、mo purge --dry-run --debug、docker system df -v,并审查~/Downloads。捕获所有结果;只有用户通过 UI 选择后才能删除。 - 构建 JSON 前先查明未知项 — 对于每个大于 500 MB、且你无法用一句话说明用途的候选项(不熟悉的应用、不熟悉的 bundle ID、不熟悉的点文件夹、供应商专用缓存、ML 模型权重、VM 镜像等),先进行调查:先检查
references/never-touch.md中是否有相关条目,然后委托web-searcher子 Agent 快速查询(“macOS 上的<path or bundle id>是什么,2026 年是否可以安全删除”)。等待回复后,再为该项目填写具体的description(用用户的语言写 1-3 句话),说明它是什么、由谁创建、哪些功能会用到它、删除后会有什么影响、是否会自动重建。绝不要用“未知”或“ML 数据”之类含糊的占位内容展示报告——这会让 UI 失去意义。如果网页查询结果与never-touch.md矛盾,应优先采用网页查询结果(信息更新),并建议更新参考文件。 - 构建数据 JSON — 每个候选项都必须成为结构化的
item(id、label、path、size_bytes、age_days、kind、command、必填的description,以及可选的protected+warning)。写入/tmp/cleanup-data-<ts>.json。使用assets/render-cleanup-plan.py文档字符串中的 schema。 在报告底部追加只读磁盘清单:可折叠的文件夹大小层级,后接按已分配大小降序排列的最大文件。storage_scan输入、覆盖范围标签和大小语义遵循references/storage-report.md。这些行仅供参考,不得自动成为删除候选项。 - 渲染并打开清理 UI:
脚本会在python3 .../assets/render-cleanup-plan.py /tmp/cleanup-data-<ts>.json127.0.0.1:18347启动一次性 HTTP 服务器,在用户的默认浏览器中打开页面,并阻塞等待用户点击 Submit 或 Cancel。提交后,脚本会将文件写入/tmp/cleanup-selection-<ts>.json,并将该路径打印到 stdout。明确告诉用户:“浏览器已打开——请勾选项目,点击 Submit,然后联系我。”接着停止并等待。 - 用户联系后 — 读取选择 JSON,在聊天中列出用户的选择(类别、项目列表、总 GB 数,以及标记为 ⚠ 的任何受保护项目覆盖),并在删除前明确询问一次确认。用户说“go”之前不要执行任何操作。
- 通过辅助脚本执行 — 绝不手动编写
rm:
脚本会从选择 JSON 中读取python3 .../assets/apply-cleanup-selection.py /tmp/cleanup-selection-<ts>.jsonselected_items并执行每个项目的command字段,同时内置以下安全措施:受保护项目必须出现在protected_overrides中,否则会跳过;执行前会根据硬保护路径列表和..组件检查来验证命令;每项操作都会以 Mole 兼容的 TSV 格式记录到~/.config/mole/operations.log。--dry-run会预览但不执行。执行阶段不要自行编写rm代码块——否则可能删除用户明确取消勾选的项目。选择 JSON 是唯一可信的数据源;若某项不在selected_items中,就不会删除。执行前后都运行df -h /System/Volumes/Data,向用户展示空间变化。 - 达到目标即停止 — 大多数用户的目标是保留 100 GB 可用空间。不要为了多清理而低于这个数字。
该 Python 脚本兼容 bash-3.2,仅使用标准库,可安全地从 Agent 的 shell 中运行。受严格保护的项目(见
references/never-touch.md)必须始终在 UI 中显示,并附带"protected": true和具体的warning字符串——UI 会将其置灰,并要求在勾选前逐项确认。绝不省略任何用户数据所依赖的受保护项目(如 Telegram tdata、Bear 数据库、密码管理器容器等)——让用户看到这些项目,才能了解相关风险。
B.“设置警报”(新设备或首次使用)
完成上述首次使用提示;恢复监控时保留现有选项。对于可选磁盘响应,还需遵循 references/optional-disk-responses.md 安装随附的辅助工具和依赖项,但不要启用任何一种模式。只有在分别获得明确同意后,才记录启用状态。
- 将
assets/mac-health-check和assets/mac-health-action复制到~/bin/(先创建目录;再运行 chmod +x)。 - 将
assets/com.local.mac-health-check.plist复制到~/Library/LaunchAgents/。 - 将
assets/config.sh复制到~/.config/mac-health/config.sh(先创建目录)。 - 运行
brew install vjeantet/tap/alerter(不要安装 terminal-notifier——它在 2026 年的 Sequoia/Tahoe 上已无法正常工作)。 - 为被动监控层运行
brew install --cask stats。 - 运行
launchctl load -w ~/Library/LaunchAgents/com.local.mac-health-check.plist。 - 首次运行时的权限提示:以交互方式打开一次
alerter(运行alerter --message test),让 macOS 请求通知中心权限。 - 告知用户:为期 7 天的校准期间不会发送警报(仅记录日志)。一周后,如果模式过于嘈杂,请编辑
config.sh。
校准期适用于原有的磁盘、内存和 Jetsam 严重传感器。CPU 使用保守的开发者工作站默认值,并立即启动;进程提示在整个事件期间保持静默并去重。
运行 launchctl list | grep mac-health 验证(应显示 PID,且退出码为 0),并运行 tail -f ~/Library/Logs/mac-health/health.log。
C.“已有 alerter,但它停止工作/开始频繁发出警报”
阅读 references/alerting.md §“故障排除”。常见原因:
- 卡住或过时的
terminal-notifier(即该 cask)取代了alerter——请替换。 - macOS 更新后 LaunchAgent 未加载——运行
launchctl bootstrap gui/$(id -u) <plist>。 - 通知发送到了 Script Editor——TCC 权限已被撤销,请重新授予。
- 开发工作负载较重时持续收到警报——运行
touch ~/.config/mac-health/silent以抑制警报。
D.“彻底卸载应用”
运行 mo uninstall <app>——Mole 会扫描 12 个以上位置,查找应用残留(Application Support、Containers、Group Containers、Caches、Preferences、Saved State、LaunchAgents、LaunchDaemons、登录项等)。始终先显示试运行结果,绝不绕过。
安全规则(不可协商)
- 对于等级 ≥ 5 的任何操作或任何 sudo 操作,未经试运行和用户确认,绝不删除。
- 绝不绕过
references/never-touch.md——即使用户明确提出要求也不例外。应予以拒绝,并解释后果。 mo purge和mo clean始终先使用--dry-run。显示预计可释放的空间,并获取确认。- 对于 Time Machine 备份:使用
tmutil delete <path>,绝不使用rm。带有 TM 标记的路径必须使用tmutilAPI。 - 对
/Library、/private/var/db/*执行 sudo 清理时:仅限references/never-touch.md§ Sudo allowlist 中列入允许列表的子路径。 - 不得设置与警报关联的无限制自动清理钩子。 唯一例外是
references/optional-disk-responses.md中低于 2% 的独立批准、范围受限的紧急 Mole 缓存配置。必须针对精确文件执行试运行;对于该配置,预先同意该配置可替代事件发生时的确认。磁盘空间 ≤ 5% 时的规划绝不授予删除权限。紧急授权不能用于批准常规清理等级或受保护路径的清理。 - 不得设置与 CPU 警报关联的自动终止钩子。 CPU 提示可以提供“停止进程…”,但必须由用户明确操作。重新验证 PID/可执行文件的身份和所有权,获取确认后先发送 SIGTERM;发送 SIGKILL 前还必须单独获取确认。
- 不要删除交换文件。 系统运行时执行
rm /private/var/vm/swapfile*会导致内核必然崩溃。 - 应用阶段只能读取选择 JSON。 应用时绝不要手动编写
rm命令块,也不要将先前扫描中的路径硬编码进去。真实事件:Agent 应用了原始扫描中默认选中的录制列表,忽略了用户在提交前已在 UI 中取消勾选这些项目。解决方法是从结构上杜绝此类问题——使用assets/apply-cleanup-selection.py,该脚本只会迭代选择 JSON 中的selected_items。
自动规划使用 helper 的类型化 format_version: 2 分支,并在本地页面上针对该确切选择单独确认。紧急执行器是规则 6 中唯一独立的配置授权路径;它不能复用或扩大用户的交互式选择范围。
记录的领域特性
- macOS Tahoe(26.x)附带
/bin/bash3.2.57。set -u+local var(未初始化)= 首次引用时触发未绑定变量错误。随附脚本已处理此问题。 - LaunchAgent 不会继承用户的 PATH。Plist 必须声明
EnvironmentVariables.PATH,并为解释器使用绝对路径。 - Apple Silicon 笔记本电脑在睡眠期间,
StartInterval计时会暂停(radar 6630231)。请使用包含明确分钟条目的StartCalendarInterval(随附的 plist 包含全部 12 个条目)。 terminal-notifier实际上已无人维护(上次发布于 2019-11),且在 Sequoia/Tahoe Apple Silicon 上会静默失效。请改用alerter。- 从 launchd 调用的
osascript display notification会将通知归属为“脚本编辑器”,且不可靠。请在 launchd 环境中使用alerter。 log show --last 6m速度太慢(超过 30 秒),不适合定期检查。应改为轮询/Library/Logs/DiagnosticReports/JetsamEvent-*.ips;在 5 分钟周期下,异步写入的延迟可以接受。JetsamEvent-*.ips文件位于/Library/Logs/DiagnosticReports/(系统范围),而非~/Library/Logs/DiagnosticReports/。- macOS 的
ps %cpu是最长一分钟内的衰减平均值,且以一个逻辑核心为基准,因此进程占用率可能超过 100 %。第二次iostat采样得到的整机 CPU 占用率范围为 0–100 %。每五分钟启动一次top的开销远高于iostat。 - CPU 通知无需读取命令参数即可确定所属应用:先根据已知工具路径(Playwriter、SourceCraft、Logi Options+)判断,再检查可执行文件/父级链中的外层
.appbundle,最后回退到可执行文件。提醒会同时显示App和Process,因此像Codex (Renderer)这样的辅助进程会归属到 ChatGPT。 - 间隔超过 15 分钟后,CPU 计数器会重置,因此睡眠和错过的日历触发不会被误认为连续的高 CPU 读数。已打开的事件会保持打开状态,但需要新的恢复读数才能重新布防。
- APFS 可清除空间在实际删除后数分钟才会更新。清理后,
df可能不会立即显示变化;请等待一段时间,或运行diskutil info /System/Volumes/Data | grep "Container Free"。 - Claude Desktop
vm_bundles/claudevm.bundle/是 Claude Cowork,不是“Claude Code 沙盒”——它是一个约 10 GB 的 Ubuntu 虚拟机映像(rootfs.img、sessiondata.img、efivars.fd、vmIP),用于 Anthropic 的沙盒代码执行功能。它会在每次启动 Claude Desktop 时通过 SHA1 完整性检查自动配置,因此最近的 mtime ≠ 用户活动。从技术上说,删除它是安全的(不会影响聊天/MCP),但 Claude Desktop 会在下次启动时静默重新下载约 10 GB,期间 CPU 占用率约为 55 %。Claude Code CLI 不使用此 bundle。建议分类为 Tier 10(先讨论),并在操作前退出 Claude Desktop,同时提醒用户:在 Anthropic 发布退出选项开关前,该 bundle 会再次出现(相关问题见 anthropics/claude-code#57371)。 - 通用规则:如果遇到无法用一句话说明用途的文件夹/bundle(尤其是大于 500 MB 的),不要猜测——在编写该项目的
description前,先委派web-searcher子 Agent 快速查证。请参阅 Workflow A 第 4 步。
成效概览
一台 Mac 在高负载开发环境(Docker、多个 AI 工具、IDE、浏览器)中经历长时间内存压力会话后,可将可用空间恢复到约 8 %:
- 在 4 小时的会话中,恢复了约 25 % 的总磁盘容量
- 最大的单项贡献:通过
mo purge清理项目构建产物(多个扫描路径合计约 30–50 GB) - 过时的 IDE 安装、缓存和偏好设置:约 10 GB
- Docker 回收空间(未使用的镜像、已结束的构建器、孤立卷):约 10 GB
- 检查
~/Downloads(旧安装程序、录音、归档的仓库):约 15 GB - 包管理器缓存(npm、pnpm、gradle、maven、cargo、brew):约 5 GB
- Sudo 级清理(系统日志、供应商应用程序包):约 5–10 GB
安装了活跃的告警器,并设置了 7 天的校准期;上线前通过模拟磁盘触发测试进行了验证。已安装统计菜单栏应用,用于被动监控。
具体数据会随工作负载和磁盘大小而变化。轻度用户的回收量会更少;重度 AI/Docker/IDE 用户的回收量会更多。