caveman caveman-commit:只写意图的 Conventional Commits 技能全解
caveman-commit 是 caveman 仓库中专职生成提交信息的技能:它把 Conventional Commits 规则压缩成一套“只写 why、不写 what”的最小规则集,并以 slash 命令、自然语言短语两种入口驱动 Agent 产出即贴即用的 commit message。读完本文,你将掌握该技能的完整规则体系(subject/body/禁写清单)、Auto-Clarity 强制场景、边界行为(绝不代你执行 git commit),以及它在仓库中如何被注册为 /caveman-commit 命令、被 UserPromptSubmit hook 拦截并切换 commit 模式的完整链路。
技能定位:一条规则集,不碰 git 状态
技能的 canonical 定义位于 skills/caveman-commit/SKILL.md,配套的人类可读说明在 skills/caveman-commit/README.md。SKILL.md 以 YAML frontmatter 声明身份与触发条件:
name: caveman-commit
description: >
Write a Conventional Commits message compressed to intent only. Use for
"write a commit", "commit message", /commit or /caveman-commit.
frontmatter 之后的第一行是全部指令的纲领:
Write commit messages terse and exact. Conventional Commits format. No fluff. Why over what.
即:简洁、精确、Conventional Commits 格式、不灌水、意图优先于描述。技能在 docs/technical/skills-hooks-and-plugins.md 的能力总表中被登记为“Terse Conventional Commit message”,并明确标注其边界:Does not stage, commit, or amend(不暂存、不提交、不 amend)。
Subject line 规则:逐条完整继承
SKILL.md 的 Rules 一节对 subject 行给出六条硬性约束,是技能的核心产出契约:
- 格式:
<type>(<scope>): <imperative summary>,其中<scope>可选; - type 白名单:
feat、fix、refactor、perf、docs、test、chore、build、ci、style、revert,共 11 种; - 祈使语气:用 "add"、"fix"、"remove",禁止 "added"、"adds"、"adding";
- 长度:尽量 ≤50 字符,硬上限 72 字符;
- 句尾不加句号;
- 冒号后的大小写跟随项目既有约定(match project convention for capitalization after the colon)。
第 6 条值得注意:技能并不强制某一种大小写风格,而是要求先观察项目已有提交再对齐——这让生成的 message 在历史中不突兀。仓库为 Gemini CLI 准备的等价压缩版 prompt 同样内嵌了这些约束,见 commands/caveman-commit.toml:
description = "Generate terse caveman-style commit message"
prompt = "Generate a terse commit message for the current staged changes. Conventional Commits format. Subject: ≤50 chars, imperative, lowercase after type. Body: only when 'why' isn't obvious from subject. Why over what. No period on subject."
注意 TOML 版的 prompt 把作用对象明确为 current staged changes(当前暂存改动),与 SKILL.md 的 Boundaries 一节呼应:技能只读暂存区来写 message,绝不主动 stage。
Body 规则:默认不写,四类情况必写
Body 的默认策略是跳过:
- Subject 自明时(self-explanatory)完全不加 body;
- 仅当存在以下四类内容时才添加 body:非显然的 why(non-obvious why)、破坏性变更(breaking changes)、迁移说明(migration notes)、关联 issue(linked issues);
- body 按 72 字符折行;
- 列表用
-而不是*; - issue/PR 引用放在结尾,格式为
Closes #42、Refs #17。
禁写清单:这些内容永远不出现在 message 里
SKILL.md 的 "What NEVER goes in" 一节定义了一条负面清单,这是该技能与普通 commit message 生成器拉开差距的地方:
| 禁写内容 | 替代方案 |
|---|---|
| "This commit does X"、"I"、"we"、"now"、"currently" | 删掉——diff 已经说明了 what |
| "As requested by ..." | 使用 Co-authored-by trailer |
| "Generated with Claude Code" 或任何 AI 署名 | 不加;除非用户自己的规则要求 Assisted-by/AI 署名 trailer,此时以 trailer 形式追加 |
| Emoji | 不加(除非项目约定要求) |
| 复述 scope 已经表达过的文件名 | 删掉,scope 已承载该信息 |
其中 AI 署名条款值得单独说明:默认零署名,但给用户规则留了后路——若用户项目规范本身要求 AI 署名,则以 trailer 而非 body 叙述的形式出现,避免污染意图正文。
两个完整示例:为什么比怎么写更重要
SKILL.md 给出两段带 diff 语境的对照示例,完整保留如下。
示例一:diff 是“新增用户 profile 端点,且 body 解释 why”。
- ❌ 反例:
feat: add a new endpoint to get user profile information from the database - ✅ 正例:
feat(api): add GET /users/:id/profile
Mobile client needs profile data without the full user payload
to reduce LTE bandwidth on cold-launch screens.
Closes #128
subject 只说“加了什么端点”,body 回答“为什么要单独拆一个端点”(移动端冷启动场景下省流量),结尾挂 issue 引用。反例的问题在于它把 diff 里已经可见的 what 又复述了一遍。
示例二:diff 是破坏性 API 重命名。
feat(api)!: rename /v1/orders to /v1/checkout
BREAKING CHANGE: clients on /v1/orders must migrate to /v1/checkout
before 2026-06-01. Old route returns 410 after that date.
要点:! 标记破坏性变更;BREAKING CHANGE: footer 给出迁移截止日和旧路由的失效行为(410 Gone)。
Auto-Clarity:四类变更禁止压缩成单行 subject
SKILL.md 的 Auto-Clarity 一节是一条覆盖性规则:
Always include body for: breaking changes, security fixes, data migrations, anything reverting a prior commit. Never compress these into subject-only — future debuggers need the context.
即以下四类变更永远必须带 body,不允许压成 subject-only:
- 破坏性变更(breaking changes)
- 安全修复(security fixes)
- 数据迁移(data migrations)
- 对先前提交的回滚(revert)
其理由写得很直白:未来的排障者需要上下文。这与 Body 规则中“默认跳过”形成互补——常规改动享受极简,高风险改动强制保留推理链。
边界与退出:只产出文本,随时可退回详细模式
SKILL.md 的 Boundaries 一节划定了技能的行为边界:
- 只生成 commit message:不执行
git commit、不 stage 文件、不 amend; - 输出形态:以代码块形式输出,可直接复制粘贴;
- 退出机制:说 "stop caveman-commit" 或 "normal mode" 即退回冗长(verbose)提交风格。
README.md 对同一边界做了复述:Outputs only the message. Does not stage, commit, or amend. 这意味着该技能可以安全地放进任何提交流程——它没有 git 副作用,唯一产出物是待粘贴的文本。
注册链路:/caveman-commit 如何恰好注册一次
技能被声明为可由 /caveman-commit slash 命令触发,但“slash 命令能解析”本身在这个仓库里是被测试守护的契约。tests/installer/slash-commands.test.mjs 针对 issue #470 与 #571 断言每个对外文档化的命令都必须满足双通道注册:
- Gemini 通道:
commands/<name>.toml必须存在(Gemini CLI 扩展只读 TOML 命令)——对应 commands/caveman-commit.toml; - Claude Code 通道:
skills/<name>/SKILL.md或commands/<name>.md二者恰好其一。Claude Code 会把commands/*.md当作与skills/*/SKILL.md同一命名空间的扁平技能加载,两者同时存在会让同一 slash 命令注册两次,3 行 stub 与真正的规则集竞争(测试注释中记录了claude plugin details曾列出重复项的现场)。
对 caveman-commit 而言,Claude Code 侧的唯一提供方就是 skills/caveman-commit/SKILL.md,测试中 DOCUMENTED_COMMANDS 白名单包含它,保证这条命令在 Claude Code 里不会被解析成 "Unknown command"。
另外从 skills/registry.json 的 preserved_skill_ids 列表(含 caveman-commit)与 skills/compile.mjs 的校验逻辑看:caveman-commit 属于“保留技能”——它不进入编译器的 skills 数组(不注入 native pack / CLI 生成物),而是以独立的 skills/caveman-commit/ 目录形式随插件分发,由宿主(Claude Code 等)直接发现;compile.mjs 在比对 canonical 技能目录时会显式豁免这些保留 id。这解释了为什么它没有出现在 registry 的 skills 数组里却仍然是可安装、可触发的正式技能。
拦截与模式状态:从输入框到 [CAVEMAN:COMMIT] 徽章
输入 /caveman-commit 后,仓库的 hook 链路会把它识别为一个“独立一次性模式”。关键证据在 src/hooks/caveman-parse.js:
// Modes handled by their own slash commands (/caveman-commit, etc.) — not
// selectable via /caveman <arg>.
const INDEPENDENT_MODES = new Set(['commit', 'review', 'compress']);
commit 是独立模式:不能通过 /caveman commit 选择,只能经由它自己的 slash 命令进入;用户在自然语言路径误触时会被明确告知而非静默切换。解析主体在 src/hooks/caveman-parse.js:
if (prompt.startsWith('/caveman')) {
const parts = prompt.split(/\s+/);
const cmd = parts[0]; // /caveman, /caveman-commit, /caveman-review, etc.
...
if (cmd === '/caveman-commit' || cmd === '/caveman:caveman-commit') {
return { action: 'set', mode: 'commit' };
}
注意它同时接受 /caveman-commit 与插件命名空间形式 /caveman:caveman-commit(marketplace 插件安装下的呈现形态)。模式判定后,UserPromptSubmit hook src/hooks/caveman-mode-tracker.js 把 commit 写入模式标志文件;src/hooks/README.md 记录了该模式的 statusline 徽章:
/caveman-commit→[CAVEMAN:COMMIT]
mode tracker 还维护了一个 .caveman-active.prev 标志:commit 这类独立模式是 one-shot 的,它记住被顶替掉的原生话风模式,下一个普通 prompt 到来时恢复,且恢复逻辑按会话隔离——两个窗口各自运行 /caveman-commit,退出时各回各的话风等级。这与 SKILL.md 中 "stop caveman-commit" / "normal mode" 的退出条款在实现层面对应:退出后 Agent 恢复常规(verbose)提交风格。
实战使用方式
在已安装 caveman 的 Claude Code 会话中:
- 暂存你要提交的改动(
git add由你执行——技能本身不 stage); - 输入
/caveman-commit,或用自然语言触发("write a commit"、"commit message"、"/commit" 均在 frontmatter 声明的触发短语内); - Agent 按本文前述规则集产出 message 代码块,复制粘贴后自行执行
git commit并填入。
需要退回详细提交风格时,说 "stop caveman-commit" 或 "normal mode" 即可。技能的全部行为约束——规则集在 skills/caveman-commit/SKILL.md,注册契约在 tests/installer/slash-commands.test.mjs,模式解析在 src/hooks/caveman-parse.js——都在这三处可以复核。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00