Skip to main content

主目录卫生 (~/.moai) NEW

更新 2026-08-21 4 分钟阅读 在 GitHub 上编辑 ↗
NEW · v3.1.1

主目录卫生 (~/.moai)

MoAI 放在项目之外的状态,全部汇集在 ~/.moai 这一个地方。按配置档案划分的调试日志、下载的发行版二进制、会话注册表、工作树台账、备份都堆在这里。在用了很久的机器上,这个目录会悄悄涨到好几 GB —— 没人会去看它,所以直到磁盘塞满才会被发现。

信息
一句话: MOAI_HOME 决定主目录根的位置,moai doctor 告诉你塞了多满,moai clean --home 只清理允许名单以内的东西。三个表面讲的是同一件事。

什么堆在哪里

flowchart TD
    Root["~/.moai (主目录根)"] --> Keep["保护 —— 绝不删除"]
    Root --> Clean["清理对象 —— 允许名单 4 类"]

    Keep --> K1["config/ · state/ · projects/
worktrees/ · mcp/ · bin/
search/ · studio/ · plugins/"] Keep --> K2["launch.yaml · preferences.yaml
所有以 credentials 开头的文件"] Clean --> C1["claude-profiles/<配置档案>/debug/
(超过保留期的)"] Clean --> C2["releases/
(当前版本 + 最新 3 个之外的)"] Clean --> C3["logs/
(根日志,超过保留期的)"] Clean --> C4["backups/removed-*
(超过保留期的)"]

不在允许名单上的东西,扫描器根本看不见。而且保护在允许名单内部同样胜出 —— 老旧的 backups/removed-* 目录里只要有一个以 credentials 开头的文件,整个目录就被跳过。与其把备份删成半截,不如完全不碰。

~/.claude 在任何路径下都不会被删除。moai doctor报告它的大小,moai clean --home 连读都不读。

MOAI_HOME —— 迁移主目录根

要把 ~/.moai 挪到别处,把 MOAI_HOME 环境变量指向想要的根路径。

bash
export MOAI_HOME=/Volumes/work/moai-home

规则有三条。

行为
非空的绝对路径该路径成为主目录根
空字符串等同于未设置 —— 回退到 ~/.moai
相对路径被忽略 —— 回退到 ~/.moai
注意
Shell 钩子不遵循 MOAI_HOME 读取这个变量的只有 Go 二进制(moai CLI 及其子命令)。.claude/hooks/ 下的 shell 脚本包装器,以及把 ~/.moai 路径当字符串直接写死的外部工具,都不会查阅这个变量,因此仍然看默认位置。也就是说,迁移 MOAI_HOME 只会带走 Go 一侧的状态,和 shell 钩子使用的路径会分叉。只有在能接受这个限制时才使用它。

用户主目录本身按 HOME 优先解析:HOME 非空就直接用它的值,只有它为空时才回退到操作系统的主目录查询。因此在测试或容器里替换 HOME,在每个平台上的效果都一致。

moai doctor —— 先看塞了多满

moai doctor 的诊断清单里带有 Home Disk Usage 项。它是建议 (advisory) 性质的,超标也不会拦住其他命令。

bash
moai doctor

该项报告的内容:

项目内容
总体大小~/.moai 的总容量与最大的 3 个条目
按配置档案分解每个 claude-profiles/<配置档案> 的大小与分类拆分
发行版数量releases/ 中剩余的二进制数量与当前版本
可清理量下面的 moai clean --home 实际能删除的估算字节数
~/.claude只报告大小 —— 绝不是清理对象

当可清理量超过阈值(编译默认值 500 MB)时,状态转为 WARN,消息会推荐 moai clean --home。低于阈值则保持 OK。可清理量的估算调用的是与 moai clean --home 同一个扫描器,所以 doctor 报出的数字和 clean 删除的清单不会脱节。

moai clean --home —— 只清理允许名单以内

bash
# 默认是 dry-run —— 只报告会删什么,不删
$ moai clean --home

# 实际删除
$ moai clean --home --force
  • dry-run 是默认值。不显式给出 --force 就什么都不删。
  • 删除范围正是上图中允许名单的 4 类。
  • releases/ 里,当前正在运行的版本其余中最新的 3 个受保护,其他二进制及其配对的 .sha256 文件成为候选。version.jsonLATEST 永远不是候选。
  • 其余三类(debug/、根 logs/backups/removed-*)只有超过保留期的才成为候选。

state.home_retention_days

保留期从 HOME 层级的配置文件 ~/.moai/config/sections/state.yaml 读取。

yaml
state:
  home_retention_days: 30
行为
无该键 / 无该文件编译默认值 30 天
正整数只有比该天数更旧的条目才成为候选
0清理停用 —— 一个候选都不会产生
信息
这个键与项目 .moai/config/sections/state.yaml 中的 state.retention_days(项目运行产物保留)是不同的键、不同的层级。主目录只有一个而项目有多个,所以把读取位置分开,免得多个项目用不同的保留期去清理同一个主目录。

动手的顺序

flowchart TD
    A["moai doctor
查看 Home Disk Usage"] --> B{"可清理量是否
超过阈值"} B -->|否| Z["无事可做"] B -->|是| C["moai clean --home
(dry-run —— 读清单)"] C --> D{"清单是否
说得通"} D -->|否| E["调整 state.home_retention_days
后再次 dry-run"] E --> C D -->|是| F["moai clean --home --force"] F --> G["用 moai doctor 复查"]

相关文档