关于 update-claudemd
面向 Claude 的技能,用于依据当前代码库和 Git 历史核对项目的 CLAUDE.md 与 `.claude/rules/*.md`。它同时审查顶层说明和按需加载的主题文件,并提出变更方案、检查篇幅预算与渐进式披露。
主要功能
- 01审查 CLAUDE.md 与主题文件
- 02依据代码和 Git 历史核对说明
- 03分类并提出更新或迁移内容
- 04检查篇幅预算与主题文件作用域
适用场景
- 01代码大量变更后复核项目说明
- 02查找指令文件中的过时或重复内容
- 03将通用说明调整为按需加载的主题文件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ gupsammy/ claudest --skill update-claudemd安装后在 Claude Code 中输入/update-claudemd确认已加载。
详细介绍
更新和优化 CLAUDE.md
根据代码库现状以及各文件上次提交以来的 Git 历史,协调项目 CLAUDE.md 及其主题文件。实施渐进式披露:CLAUDE.md 是顶层索引,包含项目身份、通用不变量,以及指向 .claude/rules/*.md 主题文件的链接。除非通过 paths: frontmatter 指定范围,否则 .claude/rules/ 中的文件会在 SessionStart 时自动加载——本技能编写的每个主题文件都必须带有该 frontmatter,使其仅在触及所属子系统的文件时加载,而非每次会话都加载。
协调范围包括 .claude/rules/ 中的所有文件。主题文件是一级内容——它们与 CLAUDE.md 本身一样,都面临过时、不准确和重复的风险,因此每次运行时都必须进行审查、协调,并在必要时编辑。它们不是附录。
范围边界:仅限项目 CLAUDE.md(L1)及其主题文件。用户全局的 ~/.claude/CLAUDE.md(L0)不在范围内,除非用户明确要求。
指导原则
只有当 CLAUDE.md 中的内容既会改变 Claude 在下一次会话中的行为,又适用于大多数任务时,才有理由保留——而不是仅适用于特定子系统。特定子系统的内容同样重要,但应放在主题文件中,按需加载。
只有当主题文件中的内容会改变 Claude 在其所属子系统中的行为,并且符合当前代码库现状时,才有理由保留。过时的主题文件比缺失的主题文件更糟糕,因为 Claude 会信任它们。
阶段 3 将这一原则落实为一组七项操作,让内容可以双向流动:向下(从 CLAUDE.md 下放到主题文件),向上(当某项细节变得通用时,从主题文件提升回 CLAUDE.md)。目标是建立一个持续演进的渐进式披露层级,而不是单向归档。
预算
CLAUDE.md:软性目标约为 120 行,软性上限为 150 行。超出预算的文件会被标记,但不会强制修改——尊重人工维护的 CLAUDE.md。使用 wc -l 统计行数。
主题文件:信息性软性上限约为每个文件 300 行。随着所属子系统的发展,主题文件合理增长;超过约 300 行时,在阶段 7 标记超出部分,并建议按子主题拆分。绝不阻止。CLAUDE.md 的预算是唯一的硬性约束。
扇出规则
代码库调研规模随项目大小和变更频率而变化。在阶段 1 计算一次,并在阶段 2 中应用。
指标:
churn——自上次修改 CLAUDE.md 以来的提交数:git log --since="<date>" --oneline --no-merges | wc -lfiles——受 Git 跟踪的文件数:git ls-files | wc -l
N(代码库扫描分片数):
| 变更数 | 文件数 | N |
|---|---|---|
| < 20 | < 100 | 1 |
| 20 – 59 | 100 – 499 | 2 |
| 60 – 149 | 500 – 1999 | 3 |
| ≥ 150 | ≥ 2000 | 4 |
分别计算每列对应的 N,取最大值,最高为 4。当 N > 1 时,按顶层目录簇划分(例如,plugins/ → 分片 1;scripts/ + tests/ → 分片 2)。
阶段 1——了解情况并计算扇出
在项目根目录中搜索 CLAUDE.md。如果文件不存在,请告知用户,创建该文件不在此技能的范围内,然后停止。
使用 wc -l 记录当前 CLAUDE.md 的行数。如果 .claude/rules/*.md 目录存在,则列出其中的文件,并记录每个主题文件的行数和最后提交日期(使用 git log -1 --format="%ai" -- <path>)。阶段 2 需要每个文件的日期,以便 Agent B 能分别确定每个文件的过时窗口——对所有文件都使用 CLAUDE.md 的日期,会导致在更新频率不同时算出错误的窗口。
分两步运行低成本 Git 探查。
首先,解析 CLAUDE.md 的最后提交日期(按顺序执行——后续探查依赖此日期):
git log -1 --format="%ai" -- CLAUDE.md→ 记录为<last_claudemd_date>。如果CLAUDE.md没有提交历史,则回退使用git log --reverse --format="%ai" | head -1。
然后通过并行 Bash 调用运行其余探查:
git log --since="<last_claudemd_date>" --oneline --no-merges | wc -l— 变更量git ls-files | wc -l— 已跟踪文件数git ls-files | awk -F/ 'NF>1{print $1}' | sort -u | wc -l— 顶层目录数
根据扇出规则计算 N。确定分片计划:每个代码库扫描 Agent 将负责哪些顶层目录。
退出条件:CLAUDE.md 存在;已记录基准行数;已记录每个主题文件的行数和最后提交日期;已计算 N;已确定分片计划。
阶段 2 — 并行调研
在一条消息中启动 3 + N 个 Explore Agent。所有 Agent 均使用 subagent_type: Explore。
Agent A — CLAUDE.md 和主题文件审查(subagent_type: Explore)
阅读项目的 CLAUDE.md,以及 .claude/rules/ 中的每个文件(如果存在)。对 CLAUDE.md 和每个主题文件都执行相同的 H1/H2/H3 分类检查——主题文件是一级内容,不是清单。
对于任一来源中的每个 H1/H2/H3 章节,记录:source(CLAUDE.md 路径或主题文件路径)、name、line_count 和 classification_hint(项目身份、通用不变量、子系统范围的细节、条件性指导,或可通过检查文件推导得出)。对于主题文件中的章节,还要标记其中任何已经成为通用不变量的内容——即现在会影响 Claude 在项目中几乎所有任务中的行为,而不只是在某个子系统内生效的内容;这些是值得回移到主文件的候选内容。
标记过时内容(看起来不正确的版本号、路径、命令、功能)。标记跨文件重复内容——主题文件中与 CLAUDE.md 重复的内容,或彼此重叠的主题文件。
同时检查 CLAUDE.md 与主题文件目录之间的索引偏差:
dangling_references— CLAUDE.md 的## Topic Files章节中提及、但磁盘上不存在的主题文件unreferenced_topic_files— 磁盘上存在、但 CLAUDE.md 中未提及的主题文件
返回:sections[{source, name, line_count, classification_hint, promote_back_candidate}]、stale_items[{source, item, reason}]、duplications[{items, locations}]、existing_topic_files[{path, line_count, last_touched, subject, section_count, has_paths_frontmatter}]、dangling_references[]、unreferenced_topic_files[]。
Agent B — 按文件检查 Git 历史(subagent_type: Explore)
以每个说明文件自身的最后修改日期为基准,各检查一次 Git 历史。使用第 1 阶段记录的日期:
- 对于 CLAUDE.md:在整个仓库范围内运行
git log --since="<claudemd_last_touched>" --format="%s%n%b" --no-merges。 - 对于每个主题文件:运行
git log --since="<topic_file_last_touched>" --format="%s%n%b" --no-merges -- <主题文件涵盖的目录>。根据主题文件的主题和加载触发条件推断其涵盖的目录(例如,关于 hooks 的主题文件涵盖plugins/*/hooks/)。如果主题涉及整个仓库,则使用仓库根目录。
对于没有历史记录的文件,回退使用初始提交日期:git log --reverse --format="%ai" | head -1。
按文件对每次提交进行分类:new_subsystems(新增代码区域)、architecture_changes(影响代码编写方式的决策或重构)、convention_changes(新增模式)、removed_features(已从代码库中移除的功能)、other。跳过 CI、格式调整和版本升级相关提交。
返回:per_file[{path, last_touched, changes_since{new_subsystems, architecture_changes, convention_changes, removed_features, other}}]。每个说明文件对应一条记录。
Agent C1..CN — 代码库分片扫描(subagent_type: Explore)
每个分片启动一个 Agent。每个分片涵盖分片计划中分配的顶层目录。提取:技术栈和框架、既定模式(测试风格、错误处理、模块组织)、新贡献者容易忽略的惯例、配置文件或脚本中的关键命令、注释或子目录 README 中的注意事项,以及足够聚焦于特定子系统、值得单独创建主题文件的内容集群。返回:tech_stack、patterns、conventions、commands、gotchas、topic_file_candidates[{filename, subject}]。
结束条件:所有 3 + N 个 Agent 均返回结构化笔记。如果任何 Agent 返回空内容或被截断,则使用已有结果继续,并在第 5 阶段的提案中说明此缺口。
阶段 3 — 分类
为 Agent A 的每个章节(包括 CLAUDE.md 章节和主题文件章节),以及 Agents B 和 C1..CN 的每项新发现,恰好分配一个操作。操作集是双向的——内容可以向下(降级)或向上(提升)流动:
keep— 内容留在原处,不作修改update— 内容留在原处,重写以确保准确(过时的事实、变更的路径、新约定)delete— 可通过读取package.json、执行ls或查看一个源文件推导得出;或该功能已不存在demote → <topic-file>— 将 CLAUDE.md 中限定于子系统的内容移至主题文件promote → CLAUDE.md— 将已成为通用不变量的主题文件内容移回 CLAUDE.md。仅限 Agent A 标记为promote_back_candidate的章节——其加载触发条件现在几乎适用于所有任务,而不只是某个子系统。此操作是demote的反向操作,必须谨慎使用;CLAUDE.md 的预算十分紧张move → <other-topic-file>— 将主题文件中主题归类已发生变化、现应归入其他主题文件的内容移至该文件add— 将研究中发现、应加入 CLAUDE.md 或主题文件的新内容添加进去add-paths-frontmatter → <glob>— 为缺少paths:frontmatter 的现有主题文件添加paths:frontmatter,并将其范围限定为该文件的主题。适用于 Agent A 报告has_paths_frontmatter: false的每个文件
将 Agent A 的悬空引用项作为协调操作处理:
dangling_references— 如果被引用的主题仍然有效,则创建缺失的主题文件;否则从 CLAUDE.md 中移除失效的引用unreferenced_topic_files— 从 CLAUDE.md 的## Topic Files部分添加指向该文件的引用,或删除孤立文件(由用户在阶段 5 决定)
按主题将代码库扫描分片中的降级候选项和主题文件候选项归类。在创建新的主题文件之前,先检查现有主题文件是否已涵盖该主题;如果已涵盖,则添加到现有文件中。
CLAUDE.md 中排名前 3–5 的通用不变量永不降级。反之,只有当主题文件章节明确达到“几乎每项任务都会改变 Claude 的行为”这一标准时,才将其提升回 CLAUDE.md。
退出条件:每个来源中的每个章节和每项新发现都恰好有一个操作;降级候选项按主题归入命名的主题文件集群;悬空引用和孤立主题文件均有解决方案。
阶段 4 — 预算检查
估算协调后的 CLAUDE.md 行数:current + added + promoted_in − demoted − deleted。promoted_in 项用于计入移回 CLAUDE.md 的主题文件章节;即使其他操作总体上不改变行数,大量回升内容也可能使 CLAUDE.md 超出预算。
如果估算值 ≤ 150,则停止降级。存在主题文件并不意味着可以过度降级。
如果估算值 > 150,先严格审查提升操作——回升操作必须达到很高的标准。取消任何通用性存疑的回升操作。然后按主题将优先级最低的其他 keep 项降级,直到低于 150。不得触及顶级不变量。如果经过合理降级和精简回升项后,文件仍超过 150 行(通常是因为该文件由人工维护,且有意保持高信息密度),则在阶段 5 标明超出部分,并由用户决定是否接受。
同时检查每个有改动的主题文件是否超过约 300 行的信息性上限。在阶段 5 中标明任何超出部分,但不要强制降级或拆分——主题文件内容较多可能完全合理。只有 CLAUDE.md 的预算是硬性约束。
退出条件:最终操作清单已就绪,并包含调整前后的行数估算、CLAUDE.md 预算状态(under、over (user override)),以及超过信息性上限的主题文件列表。
第 5 阶段 — 提议
以结构化摘要的形式呈现计划。每个指令文件——CLAUDE.md 以及每个将要修改的主题文件——都要展示相同详细程度,而不只是列出文件名。
CLAUDE.md
- 行数:
<current> → <estimated>(预算:<status>) - 保留:节数
- 更新:列表,每项附一行理由(哪些内容已过时、将如何修正)
- 删除:列表,每项附一行理由(例如“可从
package.json推导”) - 降级:按目标主题文件分组,列出各文件接收的章节
- 提升回主文件:列出因现已成为通用不变量而从主题文件移回的章节
- 添加:列出新增内容及其来源(由哪个研究 Agent 找到)
主题文件
对每个要创建的主题文件:
- 文件名、预计行数、作为其内容基础的章节(来自降级内容或研究发现)
对每个要更新的主题文件:
- 路径、行数:
<current> → <estimated> - 保留/更新/删除/提升移出/移入——采用与 CLAUDE.md 相同的结构化分类
- Paths frontmatter:新增(当向缺少
paths:的文件前置paths:时) - 超过约 300 行时标记预算
对每个保持不变的主题文件:路径及一行理由(未发现内容偏差)。
索引核对
- 已解决的悬空引用(列表)
- 已解决的孤立主题文件(列表)
使用 AskUserQuestion 提供三个选项:全部批准、选择性批准、拒绝。
退出条件:用户已明确批准一组操作。
第 6 阶段 — 写入
按以下顺序执行,以确保主题文件指针能够解析:
- 在任何写入操作之前,通过 Bash 运行
cp CLAUDE.md CLAUDE.md.bak创建备份 - 如果
.claude/rules/不存在,则运行mkdir -p创建 - 按以下子顺序处理主题文件操作:
- 删除用户批准移除的孤立主题文件
- 写入新的主题文件;每个文件都必须包含
paths:YAML frontmatter,其范围限定为该主题涵盖的 glob,并采用块序列形式(下方的完整示例展示了格式) - 编辑现有主题文件(应用保留/更新/删除/提升移出/移入操作);在此处移出的提升章节将在第 4 步重新出现在 CLAUDE.md 中
- 为 Agent A 报告缺少
paths:frontmatter 的任何现有主题文件补上paths:frontmatter——否则该文件会在每次 SessionStart 时自动加载,违背渐进式披露的目的
- 写入 CLAUDE.md,并在末尾重新生成
## Topic Files部分,排除指向已删除主题文件的指针。第 3 步中提升回主文件的章节应作为新的 H2 章节写入 CLAUDE.md 正文(而非## Topic Files索引块内)
## Topic Files 部分应在第 2 步之后根据实际磁盘状态重新生成,而非手动维护。每个条目都是加载触发词,而非描述性链接:
## Topic Files
Read on demand — do not load preemptively.
- `.claude/rules/testing.md` — before writing or modifying tests
- `.claude/rules/hooks.md` — before editing anything in plugins/*/hooks/
加载触发词应根据主题文件的主题生成,而不是直接复制标题。同一触发词也用于该主题文件自身的 paths: frontmatter——glob 与指针短语必须一致:
---
paths:
- "plugins/*/hooks/**"
---
# Hooks
没有 paths: frontmatter 的主题文件会在每次 SessionStart 时以与 CLAUDE.md 相同的优先级加载——这与按需加载正好相反。必须限定路径范围。
如果 CLAUDE.md 大部分内容保持不变,则使用 Edit 进行定向修改。只有当文件超过 60% 的内容发生变化时才使用 Write——此时文档实际上是在重新生成,而不是更新。
退出条件:所有文件均已写入,且 ## Topic Files 部分反映实际磁盘状态。
阶段 7 — 报告
输出差异摘要,列出每个已修改指令文件的变更:
CLAUDE.md
<before> → <after>行(<budget status>)- 删除内容:列出并说明原因
- 新增内容:列出并注明来源
- 提升至主文件的内容:从主题文件中移入 CLAUDE.md 的章节列表(如有)
- 保留的不变量:逐字引用排名前 3–5 项,供用户核验其是否保留
已创建的主题文件 — 每个文件注明:路径、行数、来源
已更新的主题文件 — 每个文件注明:路径、<before> → <after> 行、一行变更摘要(例如:“修正 2 个过时路径、将 1 个章节提升至 CLAUDE.md、根据 Agent C2 的发现新增 1 个章节”)。标记任何超过约 300 行信息上限的主题文件。
未更改的主题文件 — 仅列出文件名(未检测到偏移)。
索引核对 — 解决悬空引用,处理或链接孤立主题文件。
备份:已在阶段 6 步骤 1 中创建 CLAUDE.md.bak。告知用户可使用 diff CLAUDE.md.bak CLAUDE.md 进行比较,并在确认满意后自行删除;此技能不会删除备份。
完成条件:交付报告,并建议用户在审核后删除 CLAUDE.md.bak。