oh-my-pi 提交规范工程化:conventional commit 类型体系与提示词契约的完整实现
oh-my-pi(omp)coding-agent 的提交(commit)工作流中有一份只有两行的提示词契约文件 types-description.md,它定义了提交信息的类型枚举与行格式规范,是 agentic 与 conventional 两条提交流水线共享的“词汇表”。本文围绕这份契约展开:先逐字解读其语义,再结合仓库源码剖析完整类型词汇表(22 种类型)、类型描述注入 LLM 提示词的实现路径,以及格式契约(过去式 summary、scope 规则、长度限制)的程序化校验。读完你将掌握 omp 提交信息生成从“提示词定义 → 动态渲染 → 结构化解析 → 规则校验”的完整工程链路,可直接迁移到自建 Agent 工具或 CI 校验脚本中。
一、一份两行的提示词契约:文档原貌与定位
types-description.md 全文仅两行,却是整个提交工作流的语义核心:
Types: feat, fix, refactor, perf, docs, test, build, ci, chore, style, revert.
Format: <type>(<scope>): <summary> with past-tense summary.
第一行声明了 11 个基础提交类型(feat / fix / refactor / perf / docs / test / build / ci / chore / style / revert),第二行声明了提交行格式 <type>(<scope>): <summary>,并强制要求 summary 使用过去式。
需要特别说明的是,这份文件只是最小契约:它以一个紧凑的文本片段形式被渲染进系统提示词,供模型快速理解提交分类的口径;而完整的类型描述、判别规则与别名体系则存放在资源文件 commit_types.json 中,由代码动态生成。文档中的两行与资源文件之间是“静态摘要”与“完整定义”的关系,下文会逐一展开。
二、类型词汇表的完整定义:从 11 种到 22 种
文档给出了 11 种类型的最小集合,而仓库实际支持的分类词汇在 commit-types.ts 中通过 COMMIT_TYPE_ORDER 声明为 22 种,并按注释所说明的“llm-git 规范分类顺序”排列:
feat, fix, refactor, docs, test, chore, style, perf,
build, ci, revert, deps, security, config, ux, release,
hotfix, infra, init, merge, hack, wip
每种类型在 commit_types.json 中都有结构化定义,字段包括:
name:类型名;description:一句话语义描述;hint:判别提示(渲染时以括号附加在描述后);aliases:别名列表,用于把模型输出(如bug、feature、cleanup)归一化到规范类型;diff_indicators:diff 中出现的典型代码模式(如pub fn、#[test]、unwrap() → ?);examples:正例说明;file_patterns:与该类型强相关的文件路径模式(如*.md、tests/、.gitignore)。
以文档中列出的基础类型为例,资源文件中的核心语义是:
- feat:新增公共 API 或用户可观察的行为/能力变化。判别上“任何可观察行为变化都可算 feat”,当 feat 与 refactor 拿不准时优先 feat(
hint明确要求)。 - fix:修复错误行为(bug、崩溃、错误输出、竞态条件)。安全动机的修复归
security,生产环境紧急修复归hotfix。 - refactor:行为可证明不变(同一测试、同一 API)的内部重构;若行为发生变化则应使用 feat。
- docs:纯文档变更。注意提示词模板文件(
prompts/*.md)不属于 docs——提示词改动是功能性变更,应归 feat/fix/refactor。 - test:仅测试相关的改动;若生产代码与测试同时改动,则按生产代码的类型归类。
- chore:工具脚本、编辑器配置等不归其他类型的杂务;依赖版本升级归
deps,应用/运行配置归config。 - style:仅格式化、空白、缩进等无逻辑改动(变量/函数重命名属于 refactor 而非 style)。
此外,commit_types.json 顶部的 classifier_hint 集中给出了易混淆类型的判别规则,例如:fix 与 hotfix(hotfix=关键生产事故,fix=普通 bug)、fix 与 security(security=主动加固/CVE/认证加固)、deps 与 build(deps=清单中的库版本升级,build=构建脚本/配置)、config 与 chore、ux 与 feat(ux=既有功能更易用,feat=新能力),以及 init(项目或主子系统的一次性引导提交)、wip(进行中的保存点,完成态提交应优先真实类型)、hack(有意的临时 workaround,正文须注明回访意图)、merge(无独立逻辑变更的合并提交)等特例。
当模型输出的类型既不在集合中、也不匹配任何别名时,coerceCommitType(commit-types.ts)会兜底为 chore,保证下游解析永不因未知类型而中断。
三、类型描述如何进入提示词:两条注入路径
类型描述不是写死在某个模板里的常量,而是由 formatTypesDescription()(commit-types.ts)从资源文件动态生成:对每个规范类型输出 - name: description (hint) 一行,最后追加 classifier_hint 的判别规则,整体以文本形式注入提示词。仓库中存在两条注入路径:
1. Agentic(代理式)提交流水线:agent.ts 以 import typesDescriptionPrompt from "../../commit/prompts/types-description.md" 的方式把本契约文件作为文本资源导入,经 prompt.render 渲染后作为 types_description 变量注入 system.md 模板的 {{types_description}} 位置。系统提示词随后明确要求模型在最终输出前必须调用 propose_commit 或 split_commit 之一完成提交提案。
2. Conventional(传统 map-reduce 分析)流水线:generate.ts 与 map-reduce.ts 通过 formatTypesDescription() 生成 types_description 后,将其填入三套分析模板:
- analysis.md:单次分析,类型描述放在
<commit_types>区块; - fast.md:快速模式,同样放在
<commit_types>区块,并注明“当提供了<commit_types>指引时,它覆盖模型先验——例如prompts/下的提示词模板文件属于功能性变更而非 docs”; - reduce.md:map 阶段观测合并为统一分析,类型描述放在
<type_definitions>区块。
两条路径共享同一份词汇语义,但 agentic 路径以静态文件为唯一来源,conventional 路径以资源文件动态生成为来源——这正是前文所说的“静态摘要”与“完整定义”的并存关系:静态契约文件保证基础口径恒定,动态生成保证新增类型无需改模板。
四、格式契约:<type>(<scope>): <summary> 的解析与校验
文档第二行声明了提交行的结构,仓库对它的处理分为“解析”与“校验”两个阶段。
4.1 结构化解析
conventionalCommit()(commit-types.ts)把 type、scope、summary、body、footers 组装为规范结构。其中 coerceOptionalScope() 对模型输出的 scope 做“有损两段归一化”:统一转小写、以 / 分段、每段经 sanitizeScopeSegment() 清洗(仅保留小写字母与数字,-/_ 作为连接符,空格与 . 转换为 -),且最多保留两段;空串、null、none、n/a 等标记会被视为无 scope。
4.2 过去式 summary 校验
validation.ts 的 validateSummaryQuality() 与 validateCommitMessage() 实现了文档中 “past-tense summary” 的可执行化:
- 首词必须为过去式:
isPastTenseFirstWord()(validation.ts)内置规则动词表(来自validation_data.json的past_tense词对与irregular_past集合),支持-ed结尾、-d结尾(并有ed_blocklist/d_blocklist排除误判词,如以-ed结尾的名词/形容词)以及不规则动词;repairSummaryTense()(validation.ts)还能把开头的现在式动词自动改写为过去式。 - 不得以句号结尾、首词不得重复类型名(如
fix fixed ...会报type_word_repetition)。 - 长度分层限制:首行(
type+ 可选(scope)+ 分隔符 + summary)按字节计算,超过summaryHardLimit报 error,超过summarySoftLimit报 warning,超过summaryGuideline也报 warning(validation.ts);各阈值在生成配置中设置,模板层则统一遵循“通常 ≤72 字符”的口径(见 system.md 与 fast.md)。 - 禁词检查:
filler_words(如 comprehensive、various、several、improved、enhanced、better)与meta_phrases(如 “this commit”“this change”“updated code”“modified files”)会触发 warning。
4.3 类型与文件统计的一致性检查
typeScopeConsistency()(validation.ts)会把提交类型与实际改动的文件路径交叉验证:docs 类型须有文档文件,test 须有测试文件,ci 须有 CI 配置(如 .github/workflows、.gitlab-ci、Jenkinsfile),build 须有构建清单(Cargo.toml / package.json / Makefile / build.*),refactor 若新建文件会提示确认是否引入了新能力,perf 若无基准/性能关键词则告警;同时 summaryFileMismatch() 还会检测“大量 .md 文件却标了非 docs 类型”“无代码文件却标 feat/fix”等错配。
4.4 校验结果如何驱动工作流
校验产出结构化 ValidationReport(errors/warnings/ok),error 会阻断提交提案。在 agentic 流水线中,agent.ts 以最多 3 次重试的方式检查 proposal/splitProposal/changelogProposal 是否齐备,缺失时通过 <system-reminder> 提醒模型补调对应工具,确保输出的提交提案既符合类型契约、又满足 changelog 要求。
五、scope 规则实战
文档的 <scope> 是可选段,仓库把“何时省略”也写进了提示词与校验:
- 作用域判定:仅当某个组件在语义上主导变更(如约 60%+ 的行改动集中在单一组件)时才填 scope;跨多个组件、改动均匀分散、项目级或含糊时一律省略(见 analysis.md)。
- 格式限制:scope 必须短小,理想为单个词、最多两个由
-连接的段;超长候选取最具区分度的段(如coding-agent-chunk-edit-protocol→chunk-edit),绝不虚构缩写;仅允许小写字母、数字、-、_。 - 禁用名单:
src、lib、include、tests、benches、examples、docs、项目名、app、main、entire、all、misc均为禁用 scope;validateScope()还会把“scope 等于项目名”判为 error(项目级改动应省略 scope)。 - 落地示例:150 行在
src/api/、30 行在src/lib.rs→api;50 行在src/api/、50 行在src/types/→ 不填 scope。
六、从契约到自动化:提交与 changelog 的联动
这份两行契约的价值不止于“生成一行提交信息”。在 agentic 流水线中,system.md 要求模型先通过 git_overview 获取暂存文件与统计,再决定调用 propose_commit(单提交)还是 split_commit(把无关变更拆成多个互不重叠文件组的提交计划);若配置了 changelog 目标,还必须调用 propose_changelog 产出 Keep a Changelog 风格的条目,且拆提交时要确保 changelog 目标文件归入相关提交。类型与格式契约由此向上游贯通到 changelog 分类(Added / Changed / Deprecated / Removed / Fixed / Security)与下游的提交信息落盘,形成“diff → 分类 → 提交信息 → changelog”的完整链路,相关工具定义可见 agentic/tools。
七、总结
types-description.md 用两行文字锁定了 omp 提交工作流的两个核心契约:类型枚举(11 种基础类型,资源层扩展至 22 种并含别名与判别规则)与行格式(<type>(<scope>): <summary> 且 summary 为过去式)。围绕这两行契约,仓库实现了动态提示词渲染(formatTypesDescription + 三套 conventional 模板 + agentic 系统提示词)、结构化解析(coerceOptionalScope / conventionalCommit)与可执行校验(过去式检测、长度分层、禁词、类型-文件一致性),最终与 changelog 生成联动。对开发者而言,这份契约展示了如何把“风格规范”变成“可注入、可解析、可校验”的工程约束——无论是自建 Agent 的提交工具、还是 CI 中的 commitlint 类检查,这套“静态契约 + 动态词汇表 + 规则校验”的分层设计都值得直接借鉴。
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 StartedRust4.21 K635- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python30
jforgamejforgame是一个一站式游戏服务器开发框架。包含游戏服务器开发所需要的各种组件,比如网关,socket服务端与客户端,自定义高效消息编解码,游戏热更新,游戏通用工具等等。包含游戏服,跨服,匹配服,后台管理系统等实现,同时提供大量业务案例以供学习。亦可用于其他socket应用,例如及时聊天等。Java131
fizz-gateway-nodeAn Aggregation API Gateway in Java . FizzGate 是一个基于 Java开发的微服务聚合网关,是拥有自主知识产权的应用网关国产化替代方案,能够实现热服务编排聚合、自动授权选择、线上服务脚本编码、在线测试、高性能路由、API审核管理、回调管理等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行API服务治理、减少中间层胶水代码以及降低编码投入、提高 API 服务的稳定性和安全性。Java70
certd开源SSL证书管理工具;全自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔;https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署JavaScript80
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python290