关于 contextual-commit
contextual-commit 是面向编码 Agent 的提交信息编写技能,在 Conventional Commits 标题下用类型化正文记录意图、决策、约束与经验,并要求避免臆造缺失的上下文。
主要功能
- 01Conventional Commits 标题格式
- 02类型化且带范围的正文条目
- 03记录意图、决策与约束
- 04缺少上下文时避免推测
适用场景
- 01提交中保留实现背后的原因
- 02记录曾考虑但未采用的方案
- 03为后续会话保留实现限制
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ berserkdisruptors/ contextual-commits --skill contextual-commit安装后在 Claude Code 中输入/contextual-commit确认已加载。
详细介绍
情境化提交
编写提交信息,在正文中记录开发过程中的思考——差异本身无法体现的意图、决策、约束和经验。
你要解决的问题
标准提交会记录改了什么。差异也能展示这些内容。真正容易丢失的是为什么——用户提出了什么要求、考虑过哪些替代方案、哪些约束影响了实现,以及过程中学到了什么。会话结束后,这些背景就会消失。你要做的就是防止这种情况发生。
提交格式
主题行采用标准的 Conventional Commit 格式。这里不作任何更改:
feat(auth): implement Google OAuth providerfix(payments): handle currency rounding edge caserefactor(notifications): extract digest scheduling logic
正文包含行动行——带类型和作用域的条目,用来记录思考过程。
type(scope): subject line (standard conventional commit)
action-type(scope): description of reasoning or context
action-type(scope): another entry
主题行
严格遵循 Conventional Commits。这里不作任何更改:
feat(auth): implement Google OAuth providerfix(payments): handle currency rounding edge caserefactor(notifications): extract digest scheduling logic
行动行
正文中的每一行都遵循以下格式:action-type(scope): description
scope 是便于理解的概念标签,可以表示领域、模块或关注点。例如:auth、payment-flow、oauth-library、session-store、api-contracts。选择符合本项目用语习惯的标签。多次提交涉及同一概念时,保持作用域一致。
行动类型
只使用适用的类型。大多数提交需要 1 到 3 行行动行。不要为了凑数而添加无意义的内容。
intent(scope): ...
用户想要实现什么,以及原因。记录人的原意,而不是你的解读。
intent(auth): social login starting with Google, then GitHub and Appleintent(notifications): users want batch notifications instead of per-event emailsintent(payment-flow): must support EUR and GBP alongside USD for enterprise clients
适用情况: 大多数功能开发、有明确目的的重构,以及任何动机无法从主题行中一目了然的更改。
decision(scope): ...
存在替代方案时,记录最终选择的方案。简要说明理由。
decision(oauth-library): passport.js over auth0-sdk for multi-provider flexibilitydecision(digest-schedule): weekly on Monday 9am, not daily — matches user researchdecision(currency-handling): per-transaction currency over account-level default
适用情况: 评估过多个选项时使用。没有真正替代方案的显而易见选择,无需记录。
rejected(scope): ...
记录考虑过但明确放弃的方案及其原因。这是价值最高的行动类型,可以防止后续会话再次提出相同方案。
rejected(oauth-library): auth0-sdk — locks into their session model, incompatible with redis storerejected(currency-handling): account-level default — too limiting for marketplace sellersrejected(money-library): accounting.js — lacks support for sub-unit (cents) arithmetic
适用情况: 每当你或用户认真考虑过某个替代方案,但最终决定不采用时。务必说明原因。
constraint(scope): ...
实现过程中发现并影响方案的硬性限制、依赖或边界条件。
constraint(callback-routes): must follow /api/auth/callback/:provider pattern per existing conventionconstraint(stripe-integration): currency required at PaymentIntent creation, cannot change afterconstraint(session-store): redis 24h TTL means tokens must refresh within that window
适用情况: 非显而易见的限制影响了实现方案时使用。记录下一个接手的人需要了解的信息。
learned(scope): ...
在实现过程中发现、可为未来会话节省时间的信息。API 的特殊之处、未记录的行为、性能特征。
learned(passport-google): requires explicit offline_access scope for refresh tokens, undocumented in quickstartlearned(stripe-multicurrency): presentment currency and settlement currency are different conceptslearned(exchange-rates): Stripe handles conversion — do NOT store our own rates
适用场景:“真希望开始之前就知道这件事”的情况。库的陷阱、API 的意外之处、不明显的行为。
编写提交信息之前
确定提交范围,然后编写 action 行:
- 先检查暂存的更改 — 运行
git diff --cached --stat。- **如果有暂存的更改:**这些就是提交范围。不要考虑未暂存或未跟踪的文件——用户已经通过暂存表达了哪些内容属于此次提交。
- **如果没有暂存的更改:**将所有未暂存的修改和未跟踪文件视为候选项。根据会话上下文和差异内容,决定要暂存和提交哪些内容。
- 确定哪些更改有会话上下文 — 你在本次对话中产生、讨论过,或观察到其推理过程的更改。
- 确定哪些更改没有上下文 — 来自之前的会话、其他 Agent,或本次对话之外手动编辑的文件或更改。
- 据此编写 action 行:
- 对于有上下文的更改:根据会话中掌握的信息编写完整的 action 行。
- 对于没有上下文的更改:应用以下“缺少对话上下文时”规则——只写差异内容能够证明的事项。
提交信息必须涵盖提交范围内的所有更改,而不仅仅是你处理过的更改。忽略你未产生的更改,比为它们写简略的 action 行更糟糕。
示例
简单修复 — 无需 action 行
fix(button): correct alignment on mobile viewport
使用 conventional commit 主题即可。不必添加冗余内容。
中等规模功能
feat(notifications): add email digest for weekly summaries
intent(notifications): users want batch notifications instead of per-event emails
decision(digest-schedule): weekly on Monday 9am — matches user research feedback
constraint(email-provider): SendGrid batch API limited to 1000 recipients per call
复杂架构变更
refactor(payments): migrate from single to multi-currency support
intent(payments): enterprise customers need EUR and GBP alongside USD
intent(payment-architecture): must be backward compatible, existing USD flows unchanged
decision(currency-handling): per-transaction currency over account-level default
rejected(currency-handling): account-level default too limiting for marketplace sellers
rejected(money-library): accounting.js — lacks sub-unit arithmetic, using currency.js instead
constraint(stripe-integration): Stripe requires currency at PaymentIntent creation, cannot change after
constraint(database-migration): existing amount columns need companion currency columns, not replacement
learned(stripe-multicurrency): presentment currency vs settlement currency are different Stripe concepts
learned(exchange-rates): Stripe handles conversion, we should NOT store our own rates
实现中途调整方向
当工作意图发生变化时,应在发生调整的提交中记录:
refactor(auth): switch from session-based to JWT tokens
intent(auth): original session approach incompatible with redis cluster setup
rejected(auth-sessions): redis cluster doesn't support session stickiness needed by passport sessions
decision(auth-tokens): JWT with short expiry + refresh token pattern
learned(redis-cluster): session affinity requires sticky sessions at load balancer level — too invasive
缺少对话上下文时
有时,暂存的更改包含本次会话中并非由你产生的内容——之前会话的产出、其他 Agent 的更改、粘贴的代码、外部生成的文件或手动编辑。对于任何缺少推理过程记录的更改:
**只为差异内容明确证明的事项编写 action 行。**不要猜测无法观察到的意图或约束。
仅凭差异内容可以推断的内容:
decision(scope)— 如果能看出明确的技术选择(新增依赖、采用某种模式、更换库)。例如,decision(http-client): switched from axios to native fetch可从差异内容中看出。
无法推断的内容——不要捏造:
intent(scope)— 差异内容无法体现更改的原因。不要复述差异中已显示的内容。rejected(scope)— 已提交的内容不会显示哪些方案未被采用。constraint(scope)— 代码更改几乎从不体现硬性限制。learned(scope)— 经验来自过程,而非产出。
没有 action 行的规范 conventional commit 主题,始终胜过捏造上下文。
Git 工作流
情境化提交适用于所有标准 Git 工作流,无需特殊处理。
- **常规合并:**提交正文会完整保留。
- **压缩合并:**所有提交正文会连接到压缩提交的正文中。结果是按时间顺序排列的、带类型和作用域的 action 行记录——Agent 可以顺利解析、筛选和分组。
- **变基和 cherry-pick:**提交正文会保留。
规则
- 主题行必须符合 Conventional Commit 规范。 切勿破坏现有约定或工具链。
- 操作说明只能写在正文中。 切勿写在主题行中。
- 只写有实际信息的操作说明。 如果差异已经说明了,就不要重复。如果没有需要决定、拒绝或发现的内容,就不要写操作说明。
- 简洁但完整。 每条操作说明都应是一句清晰的陈述。没有刻意设置的长度限制,但也不要写成长篇大论。
- 在同一项目中保持范围命名一致。 如果在一条提交中用了
auth,下一条就不要改用authentication。 - 用用户自己的措辞表达其意图。 对于
intent行,要反映用户提出的要求,而不是总结你的实现方式。 rejected行必须始终说明原因。 不说明原因的拒绝毫无用处——下一个 Agent 只会再次提出该方案。- 不要为琐碎的提交编造操作说明。 修正拼写错误、升级依赖、调整格式等,使用符合规范的提交主题就足够了。
- 不要捏造自己不了解的背景。 如果你没有参与推理过程,就不要假装参与了。参见上文的“缺少对话背景时”。