Goal
Sinh commit message chuẩn Conventional Commits trong 5 giây, consistent 100% across team.
Instructions
Bước 1: Nhận input
Kiểm tra loại input user cung cấp:
Nếu là Git diff output (có diff --git, index, lines với +/-):
→ Parse diff để trích xuất thông tin thay đổi
Nếu là mô tả bằng text:
→ Hỏi clarifying nếu cần:
- "Em cần biết thêm: (A) Tên files đã thay đổi, (B) Loại thay đổi chính xác, hay (C) File paths đã thay đổi?"
Nếu không rõ:
→ Hỏi: "Anh/chị cho em biết: (A) Dùng git diff, (B) Mô tả bằng tay, hay (C) File paths đã thay đổi?"
Bước 2: Xác định TYPE
Dựa trên nội dung thay đổi, chọn type phù hợp:
| Type | Khi dùng |
|---|
| feat | Tính năng mới (new feature, new capability) |
| fix |
Sửa bug (fix error, fix bug, fix issue) |
|
docs | Thay đổi documentation |
|
style | Format code, không ảnh hưởng logic (whitespace, semicolon) |
|
refactor | Refactor code, không thay đổi hành vi (rename, extract) |
|
test | Thêm, sửa, refactor test |
|
chore | Việc maintenance (update deps, build config) |
Logic quyết định:
CODEBLOCK0
Bước 3: Xác định SCOPE (tùy chọn)
Scope là phần thay đổi cụ thể, ngắn gọn:
Nếu nhiều files khác nhau:
→ Thường KHÔNG có scope (rủi ro quá dài)
Nếu 1 file hoặc 1 module:
→ Dùng file/module name kebab-case:
- auth
- user-service
- INLINECODE6
Bước 4: Viết SUBJECT (bắt buộc)
Format: INLINECODE7
Quy tắc:
- - Subject PHẢI có type (lowercase)
- Subject PHẢI có description
- Subject ≤ 50 characters (bao gồm type + scope)
- Subject KHÔNG có dấu chấm cuối
- Subject dùng imperative mood:
- ✅ "Add user authentication"
- ❌ "Added user authentication"
- ✅ "Fix null pointer error"
- ❌ "Fixed null pointer error"
Examples:
CODEBLOCK1
Bước 5: Viết BODY (tùy chọn)
Khi nào cần body:
- - Có >1 sự thay đổi khác nhau
- Cần giải thích TẠI SAO (breaking change, edge case)
- Referencing issue/PR
Format body:
CODEBLOCK2
Quy tắc body:
- - Có 1 blank line giữa subject và body
- Mỗi dòng ≤ 72 characters (để dễ đọc trên terminal)
- Dùng imperative mood giống subject
- Dùng bullet points cho multiple items
Examples body:
CODEBLOCK3
Bước 6: Xác thực OUTPUT
Kiểm tra commit message vừa tạo:
- - [ ] Type trong danh sách (feat|fix|docs|style|refactor|test|chore)
- [ ] Type là lowercase
- [ ] Subject ≤ 50 characters
- [ ] Subject có description
- [ ] Subject KHÔNG có dấu chấm cuối
- [ ] Nếu có body: có 1 blank line giữa subject/body
- [ ] Body (nếu có): mỗi dòng ≤ 72 characters
- [ ] Subject + Body dùng imperative mood
Nếu FAIL bất kỳ check → Hỏi user sửa input.
Examples
Ví dụ 1: Happy Path — Git diff từ feature branch
Context: Dev vừa hoàn thành feature login, push code lên Git, muốn commit message chuẩn.
Input (Git diff):
CODEBLOCK4
Thought Process:
- - Nhận diff: thêm
express.json() middleware → Đây là feat (thay đổi behavior) - Files: chỉ index.js → Scope không cần (quá dài nếu có)
- Description: "add express json middleware" → Imperative: "add express json middleware"
- Length: 29 chars (bao gồm "feat: ") < 50 ✅
Output:
CODEBLOCK5
Ví dụ 2: Edge Case — Mô tả text thay vì Git diff
Context: Dev sửa bug trong auth module, chỉ mô tả bằng văn bản.
Input:
"Sửa lỗi session timeout trong file auth.js, user bị logout sau 10 phút"
Thought Process:
- - Có "fix" + "error" → type: fix
- File: auth.js → scope: auth
- Description: "resolve session timeout" → Imperative ✅
- Length: 27 chars < 50 ✅
Output:
CODEBLOCK6
Ví dụ 3: Multiple Changes — Thay đổi nhiều files khác nhau
Context: Dev vừa refactor authentication + fix bug trong user service + update docs cho cả hai.
Input (Mô tả):
"Refactor auth module, fix user service validation, update docs for both"
Thought Process:
- - 3 files khác nhau → Không có scope (quá dài)
- Dominant change: refactor → type: refactor
- Description: "refactor authentication system" → Imperative ✅
Output:
CODEBLOCK7
Ví dụ 4: Breaking Change — Thay đổi không tương thích
Context: Dev thay đổi API signature, breaking change cho clients cũ.
Input (Mô tả):
"Thay đổi API /user endpoint, từ email sang userId, breaking change cho clients"
Thought Process:
- - Thay đổi behavior → type: feat
- File: user endpoint → scope: user
- Breaking change → Cần body giải thích
- Description: "change user endpoint to use userId" → Imperative ✅
Output:
CODEBLOCK8
Ví dụ 5: Style Change — Format không ảnh hưởng logic
Context: Dev chạy prettier, chỉ format code, không thay đổi logic.
Input (Git diff hoặc mô tả):
"Format tất cả files với prettier, thêm dấu chấm cuối dòng"
Thought Process:
- - Chỉ format → type: style
- Files: nhiều → Không có scope
- Description: "format code with prettier" → Imperative ✅
- Body không cần (chỉ formatting)
Output:
style: format code with prettier
Constraints
Bắt buộc (MUST)
- - 🚫 TUYỆT ĐỐI KHÔNG tạo commit type ngoài danh sách: INLINECODE9
- 🚫 TUYỆT ĐỐI KHÔNG viết type với UPPERCASE → Luôn lowercase
- 🚫 TUYỆT ĐỐI KHÔNG subject vượt 50 characters → Truncate hoặc tách commit
- 🚫 TUYỆT ĐỐI KHÔNG subject có dấu chấm cuối → Hỏi user sửa
- 🚫 TUYỆT ĐỐI KHÔNG thiếu description trong subject → Hỏi user thêm
- ✅ LUÔN LUÔN có type (bắt buộc)
- ✅ LUÔN LUÔN subject có description (bắt buộc)
Không bắt buộc (SHOULD)
- - ⚠️ NÊN có scope nếu 1 file/module duy nhất → Giúp review code dễ hơn
- ⚠️ NÊN có body nếu nhiều changes hoặc breaking change → Giải thích context
- ⚠️ NÊN body mỗi dòng ≤ 72 characters → Đọc dễ trên terminal
- ⚠️ NÊN refer issue/PR nếu có (Closes #123, Refs PR #456)
Special Cases
Nếu commit lớn (>1000 files)
→ Tách thành multiple commits, mỗi commit 1 logical change
Nếu commit revert
→ Dùng type
revert, format: INLINECODE11
Nếu commit merge
→ Không dùng skill này → Git tạo merge commit tự động
Whitelist Integration
Trạng thái: ✅ Active
File: INLINECODE12
Mô tả: File này điều khiển skill nào được phép tự động thêm vào Gateway hệ thống (auto-add). Khi Hina nhận trigger "tạo skill", "tạo skill mới", Hina sẽ kiểm tra danh sách whitelist này trước khi tự động thêm skill.
Cách hoạt động:
- 1. Hina đọc INLINECODE13
- Hina kiểm tra skill name có trong danh sách
skills_allowed_auto_add không - Nếu có → Auto-add skill KHÔNG cần hỏi lại
- Nếu không → Hina hỏi anh trước khi thêm
Các skill hiện tại trong whitelist:
- - git-commit-formatter
- skill-creator-ultra
Cập nhật whitelist:
- - Thêm skill: Thêm vào danh sách YAML ở trên
- Xóa skill: Đánh dấu
status: "disabled" hoặc xóa khỏi danh sách - Cập nhật: Sửa
last_updated timestamp
Lợi ích:
- - ✅ Tự động hóa cho skill phổ biến
- ✅ Tránh hỏi lặp lại
- ✅ Kiểm soát rủi ro (chỉ skill an toàn trong whitelist)
Reference Data
Conventional Commits Standard
Đây là danh sách types chính thức:
| Type | Description |
|---|
| feat | Tính năng mới (new feature, new capability) |
| fix |
Sửa bug (fix error, fix bug, fix issue) |
|
docs | Thay đổi documentation (README, comments, API docs) |
|
style | Format code (whitespace, semicolon, indentation) - không ảnh hưởng logic |
|
refactor | Refactor code (rename, extract) - không thay đổi behavior |
|
test | Thêm/sửa/refactor test (tests, specs) |
|
chore | Maintenance (build config, update deps, script) |
Quy tắc important:
- - Type luôn lowercase
- Format: INLINECODE17
- Body tùy chọn, dùng nếu cần giải thích
Subject Examples
| ❌ Sai | ✅ Đúng |
|---|
| Added user login | feat: add user login |
| Fixed bug |
fix: resolve authentication error |
| Update docs | docs: update README |
| Format code | style: format with prettier |
| Refactored code | refactor: extract validation logic |
目标
在5秒内生成符合Conventional Commits规范的提交信息,团队间100%保持一致。
操作说明
步骤1:接收输入
检查用户提供的输入类型:
如果是Git diff输出(包含diff --git、index、带+/-的行):
→ 解析diff以提取变更信息
如果是文本描述:
→ 必要时询问澄清信息:
- 我需要了解更多:(A) 已更改的文件名,(B) 准确的变更类型,还是(C) 已更改的文件路径?
如果不明确:
→ 询问:请告诉我:(A) 使用git diff,(B) 手动描述,还是(C) 已更改的文件路径?
步骤2:确定TYPE
根据变更内容,选择合适的类型:
| 类型 | 使用场景 |
|---|
| feat | 新功能(新特性、新能力) |
| fix |
修复bug(修复错误、修复bug、修复问题) |
|
docs | 文档变更 |
|
style | 代码格式化,不影响逻辑(空白、分号) |
|
refactor | 代码重构,不改变行为(重命名、提取) |
|
test | 添加、修改、重构测试 |
|
chore | 维护工作(更新依赖、构建配置) |
判断逻辑:
如果包含fix + bug + error → type = fix
否则如果包含add + new + create + implement → type = feat
否则如果包含doc + readme + comment → type = docs
否则如果包含format + style + indent → type = style
否则如果包含refactor + rename + extract → type = refactor
否则如果包含test + spec + assert → type = test
否则 → type = chore
步骤3:确定SCOPE(可选)
Scope是具体的变更部分,需简洁:
如果是多个不同文件:
→ 通常不使用scope(有太长风险)
如果是1个文件或1个模块:
→ 使用kebab-case格式的文件/模块名:
- auth
- user-service
- commit-formatter
步骤4:编写SUBJECT(必填)
格式:():
规则:
- - Subject 必须包含type(小写)
- Subject 必须包含description
- Subject ≤ 50个字符(包括type + scope)
- Subject 不能以句号结尾
- Subject使用祈使语气:
- ✅ Add user authentication
- ❌ Added user authentication
- ✅ Fix null pointer error
- ❌ Fixed null pointer error
示例:
feat: add user login
fix(auth): resolve session timeout
docs: update API reference
style: format code with prettier
refactor: extract validation logic
test: add unit tests for auth
chore: upgrade to Node.js v22
步骤5:编写BODY(可选)
何时需要body:
- - 有>1个不同的变更
- 需要解释原因(破坏性变更、边界情况)
- 引用issue/PR
body格式:
[空行]
<解释说明>
[可选详情]
- - Closes #123
- Refs PR #456
body规则:
- - subject和body之间要有1个空行
- 每行 ≤ 72个字符(便于在终端阅读)
- 使用与subject相同的祈使语气
- 多个项目使用项目符号
body示例:
Add email verification flow
- - Send verification link to user email
- Verify token on click
- Update user status to verified
Closes #45
步骤6:验证OUTPUT
检查刚生成的提交信息:
- - [ ] 类型在列表中(feat|fix|docs|style|refactor|test|chore)
- [ ] 类型为小写
- [ ] Subject ≤ 50个字符
- [ ] Subject包含description
- [ ] Subject不能以句号结尾
- [ ] 如果有body:subject/body之间有1个空行
- [ ] Body(如果有):每行 ≤ 72个字符
- [ ] Subject + Body使用祈使语气
如果任何检查失败 → 询问用户修改输入。
示例
示例1:正常路径 — 来自功能分支的Git diff
场景: 开发者刚完成登录功能,将代码推送到Git,需要标准提交信息。
输入(Git diff):
diff --git a/index.js b/index.js
index abc123..def456 100644
--- a/index.js
+++ b/index.js
@@ -1,5 +1,6 @@
const express = require(express);
-const app = express();
+const app = express().use(express.json());
思考过程:
- - 收到diff:添加了express.json()中间件 → 这是feat(改变了行为)
- 文件:只有index.js → 不需要scope(如果有会太长)
- 描述:add express json middleware → 祈使语气:add express json middleware
- 长度:29个字符(包括feat: )< 50 ✅
输出:
feat: add express json middleware
Adds JSON body parsing to Express app.
示例2:边界情况 — 文本描述而非Git diff
场景: 开发者修复auth模块中的bug,仅用文本描述。
输入:
修复auth.js文件中session超时错误,用户10分钟后被登出
思考过程:
- - 包含fix + error → type: fix
- 文件:auth.js → scope: auth
- 描述:resolve session timeout → 祈使语气 ✅
- 长度:27个字符 < 50 ✅
输出:
fix(auth): resolve session timeout
Set session timeout to 24 hours to prevent users
from being logged out too quickly.
Closes #789
示例3:多个变更 — 更改多个不同文件
场景: 开发者重构了身份验证模块 + 修复了用户服务中的bug + 更新了这两者的文档。
输入(描述):
重构auth模块,修复用户服务验证,更新两者的文档
思考过程:
- - 3个不同文件 → 不使用scope(太长)
- 主要变更:重构 → type: refactor
- 描述:refactor authentication system → 祈使语气 ✅
输出:
refactor: refactor authentication system
Extract user validation to separate service and improve
error handling across auth module.
Changes:
- - auth.js: extract validation logic
- user-service.js: add validation middleware
- README.md: update auth flow docs
Refs PR #123, #456
示例4:破坏性变更 — 不兼容的更改
场景: 开发者更改了API签名,对旧客户端造成破坏性变更。
输入(描述):
更改/user端点API,从email改为userId,对客户端造成破坏性变更
思考过程:
- - 改变了行为 → type: feat
- 文件:user端点 → scope: user
- 破坏性变更 → 需要body解释
- 描述:change user endpoint to use userId → 祈使语气 ✅
输出:
feat(user): change user endpoint to use userId
BREAKING CHANGE: Email parameter removed, use userId instead.
Update API clients to use new endpoint format.
- - Updated /user GET endpoint
- Removed email parameter
- Added userId parameter
Migration guide: See docs/api-migration.md
Closes #901
示例5:样式变更 — 不影响逻辑的格式化
场景: 开发者运行prettier,仅格式化代码,不改变逻辑。
输入(Git diff或描述):
用prettier格式化所有文件,添加行尾分号
思考过程:
- - 仅格式化 → type: style
- 文件:多个 → 不使用scope
- 描述:format code with prettier → 祈使语气 ✅
- 不需要body(仅格式化)
输出:
style: format code with prettier
约束条件
必须遵守(MUST)
- - 🚫 绝对不要创建列表之外的提交类型:feat|fix|docs|style|refactor|test|chore
- 🚫 绝对不要使用大写写type → 始终小写
- 🚫 绝对不要让subject超过50个字符 → 截断或拆分提交
- 🚫 绝对不要在subject末尾加句号 → 询问用户修改
- 🚫 绝对不要缺少subject中的description → 询问用户添加
- ✅ 始终包含type(必填)
- ✅ 始终