@zjex/git-workflow 0.3.0 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.husky/commit-msg +5 -0
- package/.husky/pre-commit +2 -5
- package/README.md +1 -1
- package/ROADMAP.md +356 -0
- package/dist/index.js +448 -110
- package/docs/.vitepress/cache/deps/_metadata.json +9 -9
- package/docs/.vitepress/config.ts +2 -1
- package/docs/commands/help.md +248 -0
- package/docs/commands/index.md +15 -8
- package/docs/commands/log.md +328 -0
- package/docs/features/git-wrapped.md +199 -0
- package/docs/index.md +32 -1
- package/package.json +2 -1
- package/scripts/format-commit-msg.js +258 -0
- package/scripts/release.sh +61 -1
- package/src/ai-service.ts +77 -16
- package/src/commands/commit.ts +9 -3
- package/src/commands/init.ts +23 -0
- package/src/commands/log.ts +503 -0
- package/src/commands/tag.ts +18 -10
- package/src/config.ts +1 -0
- package/src/index.ts +37 -13
- package/src/utils.ts +10 -0
- package/tests/commit-format.test.ts +535 -0
- package/tests/log.test.ts +106 -0
- package/src/commands/help.ts +0 -76
- package/tests/help.test.ts +0 -134
package/src/ai-service.ts
CHANGED
|
@@ -60,7 +60,7 @@ function getGitDiff(): string {
|
|
|
60
60
|
/**
|
|
61
61
|
* 构建 AI prompt
|
|
62
62
|
*/
|
|
63
|
-
function buildPrompt(diff: string, language: string, detailedDescription: boolean = false): string {
|
|
63
|
+
function buildPrompt(diff: string, language: string, detailedDescription: boolean = false, useEmoji: boolean = true): string {
|
|
64
64
|
const isZh = language === "zh-CN";
|
|
65
65
|
|
|
66
66
|
if (detailedDescription) {
|
|
@@ -69,7 +69,7 @@ function buildPrompt(diff: string, language: string, detailedDescription: boolea
|
|
|
69
69
|
? `你是一个专业的 Git commit message 生成助手。请根据提供的 git diff 生成符合 Conventional Commits 规范的详细 commit message。
|
|
70
70
|
|
|
71
71
|
格式要求:
|
|
72
|
-
1.
|
|
72
|
+
1. 第一行:${useEmoji ? '<emoji> ' : ''}<type>(<scope>): <subject>
|
|
73
73
|
2. 空行
|
|
74
74
|
3. 详细描述:列出主要修改点,每个修改点一行,以 "- " 开头
|
|
75
75
|
|
|
@@ -80,9 +80,22 @@ function buildPrompt(diff: string, language: string, detailedDescription: boolea
|
|
|
80
80
|
- 详细描述要列出 3-6 个主要修改点,每个修改点简洁明了
|
|
81
81
|
- 如果修改较少,可以只列出 2-3 个修改点
|
|
82
82
|
- 不要有其他解释或多余内容
|
|
83
|
+
${useEmoji ? `
|
|
84
|
+
Emoji 映射规则:
|
|
85
|
+
- feat: ✨ (新功能)
|
|
86
|
+
- fix: 🐛 (修复Bug)
|
|
87
|
+
- docs: 📝 (文档)
|
|
88
|
+
- style: 💄 (代码格式)
|
|
89
|
+
- refactor: ♻️ (重构)
|
|
90
|
+
- perf: ⚡️ (性能优化)
|
|
91
|
+
- test: ✅ (测试)
|
|
92
|
+
- build: 📦 (构建)
|
|
93
|
+
- ci: 👷 (CI/CD)
|
|
94
|
+
- chore: 🔧 (其他杂项)
|
|
95
|
+
- revert: ⏪ (回滚)` : ''}
|
|
83
96
|
|
|
84
97
|
示例:
|
|
85
|
-
feat(auth): 添加用户登录功能
|
|
98
|
+
${useEmoji ? '✨ ' : ''}feat(auth): 添加用户登录功能
|
|
86
99
|
|
|
87
100
|
- 实现用户名密码登录接口
|
|
88
101
|
- 添加登录状态验证中间件
|
|
@@ -91,7 +104,7 @@ feat(auth): 添加用户登录功能
|
|
|
91
104
|
: `You are a professional Git commit message generator. Generate a detailed commit message following Conventional Commits specification based on the provided git diff.
|
|
92
105
|
|
|
93
106
|
Format requirements:
|
|
94
|
-
1. First line: <type>(<scope>): <subject>
|
|
107
|
+
1. First line: ${useEmoji ? '<emoji> ' : ''}<type>(<scope>): <subject>
|
|
95
108
|
2. Empty line
|
|
96
109
|
3. Detailed description: List main changes, one per line, starting with "- "
|
|
97
110
|
|
|
@@ -102,9 +115,22 @@ Rules:
|
|
|
102
115
|
- Detailed description should list 3-6 main changes, each change should be concise
|
|
103
116
|
- If changes are minimal, list 2-3 changes
|
|
104
117
|
- No explanations or extra content
|
|
118
|
+
${useEmoji ? `
|
|
119
|
+
Emoji mapping rules:
|
|
120
|
+
- feat: ✨ (new feature)
|
|
121
|
+
- fix: 🐛 (bug fix)
|
|
122
|
+
- docs: 📝 (documentation)
|
|
123
|
+
- style: 💄 (code style)
|
|
124
|
+
- refactor: ♻️ (refactoring)
|
|
125
|
+
- perf: ⚡️ (performance)
|
|
126
|
+
- test: ✅ (testing)
|
|
127
|
+
- build: 📦 (build)
|
|
128
|
+
- ci: 👷 (CI/CD)
|
|
129
|
+
- chore: 🔧 (chore)
|
|
130
|
+
- revert: ⏪ (revert)` : ''}
|
|
105
131
|
|
|
106
132
|
Example:
|
|
107
|
-
feat(auth): add user login functionality
|
|
133
|
+
${useEmoji ? '✨ ' : ''}feat(auth): add user login functionality
|
|
108
134
|
|
|
109
135
|
- Implement username/password login API
|
|
110
136
|
- Add login status validation middleware
|
|
@@ -122,31 +148,57 @@ feat(auth): add user login functionality
|
|
|
122
148
|
? `你是一个专业的 Git commit message 生成助手。请根据提供的 git diff 生成符合 Conventional Commits 规范的 commit message。
|
|
123
149
|
|
|
124
150
|
规则:
|
|
125
|
-
1.
|
|
151
|
+
1. 格式:${useEmoji ? '<emoji> ' : ''}<type>(<scope>): <subject>
|
|
126
152
|
2. type 必须是以下之一:feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
|
|
127
153
|
3. scope 是可选的,表示影响范围
|
|
128
154
|
4. subject 用中文描述,简洁明了,不超过 50 字
|
|
129
155
|
5. 只返回一条 commit message,即使有多个文件改动也要总结成一条
|
|
130
156
|
6. 不要有其他解释或多余内容
|
|
157
|
+
${useEmoji ? `
|
|
158
|
+
Emoji 映射规则:
|
|
159
|
+
- feat: ✨ (新功能)
|
|
160
|
+
- fix: 🐛 (修复Bug)
|
|
161
|
+
- docs: 📝 (文档)
|
|
162
|
+
- style: 💄 (代码格式)
|
|
163
|
+
- refactor: ♻️ (重构)
|
|
164
|
+
- perf: ⚡️ (性能优化)
|
|
165
|
+
- test: ✅ (测试)
|
|
166
|
+
- build: 📦 (构建)
|
|
167
|
+
- ci: 👷 (CI/CD)
|
|
168
|
+
- chore: 🔧 (其他杂项)
|
|
169
|
+
- revert: ⏪ (回滚)` : ''}
|
|
131
170
|
|
|
132
171
|
示例:
|
|
133
|
-
- feat(auth): 添加用户登录功能
|
|
134
|
-
- fix(api): 修复数据获取失败的问题
|
|
135
|
-
- docs(readme): 更新安装说明`
|
|
172
|
+
- ${useEmoji ? '✨ ' : ''}feat(auth): 添加用户登录功能
|
|
173
|
+
- ${useEmoji ? '🐛 ' : ''}fix(api): 修复数据获取失败的问题
|
|
174
|
+
- ${useEmoji ? '📝 ' : ''}docs(readme): 更新安装说明`
|
|
136
175
|
: `You are a professional Git commit message generator. Generate a commit message following Conventional Commits specification based on the provided git diff.
|
|
137
176
|
|
|
138
177
|
Rules:
|
|
139
|
-
1. Format: <type>(<scope>): <subject>
|
|
178
|
+
1. Format: ${useEmoji ? '<emoji> ' : ''}<type>(<scope>): <subject>
|
|
140
179
|
2. type must be one of: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
|
|
141
180
|
3. scope is optional, indicates the affected area
|
|
142
181
|
4. subject should be concise, no more than 50 characters
|
|
143
182
|
5. Return only ONE commit message, even if multiple files are changed, summarize into one message
|
|
144
183
|
6. No explanations or extra content
|
|
184
|
+
${useEmoji ? `
|
|
185
|
+
Emoji mapping rules:
|
|
186
|
+
- feat: ✨ (new feature)
|
|
187
|
+
- fix: 🐛 (bug fix)
|
|
188
|
+
- docs: 📝 (documentation)
|
|
189
|
+
- style: 💄 (code style)
|
|
190
|
+
- refactor: ♻️ (refactoring)
|
|
191
|
+
- perf: ⚡️ (performance)
|
|
192
|
+
- test: ✅ (testing)
|
|
193
|
+
- build: 📦 (build)
|
|
194
|
+
- ci: 👷 (CI/CD)
|
|
195
|
+
- chore: 🔧 (chore)
|
|
196
|
+
- revert: ⏪ (revert)` : ''}
|
|
145
197
|
|
|
146
198
|
Examples:
|
|
147
|
-
- feat(auth): add user login functionality
|
|
148
|
-
- fix(api): resolve data fetching failure
|
|
149
|
-
- docs(readme): update installation guide`;
|
|
199
|
+
- ${useEmoji ? '✨ ' : ''}feat(auth): add user login functionality
|
|
200
|
+
- ${useEmoji ? '🐛 ' : ''}fix(api): resolve data fetching failure
|
|
201
|
+
- ${useEmoji ? '📝 ' : ''}docs(readme): update installation guide`;
|
|
150
202
|
|
|
151
203
|
const userPrompt = isZh
|
|
152
204
|
? `请根据以下 git diff 生成 commit message:\n\n${diff}`
|
|
@@ -291,10 +343,16 @@ async function callOllamaAPI(
|
|
|
291
343
|
|
|
292
344
|
/**
|
|
293
345
|
* 清理AI生成的commit message
|
|
294
|
-
*
|
|
346
|
+
* 移除重复行、多余的空行和开头的特殊字符
|
|
295
347
|
*/
|
|
296
348
|
function cleanAIResponse(response: string): string {
|
|
297
|
-
|
|
349
|
+
// 移除开头的特殊字符(如 ...、```、等)
|
|
350
|
+
let cleaned = response.replace(/^[.\s`~-]+/, '').trim();
|
|
351
|
+
|
|
352
|
+
// 移除结尾的特殊字符
|
|
353
|
+
cleaned = cleaned.replace(/[.\s`~-]+$/, '').trim();
|
|
354
|
+
|
|
355
|
+
const lines = cleaned.split('\n').map(line => line.trim()).filter(line => line);
|
|
298
356
|
|
|
299
357
|
// 移除重复的行
|
|
300
358
|
const uniqueLines = [];
|
|
@@ -321,6 +379,9 @@ export async function generateAICommitMessage(
|
|
|
321
379
|
const language = aiConfig.language || "zh-CN";
|
|
322
380
|
const detailedDescription = aiConfig.detailedDescription !== false; // 默认启用详细描述
|
|
323
381
|
const maxTokens = aiConfig.maxTokens || (detailedDescription ? 400 : 200);
|
|
382
|
+
|
|
383
|
+
// AI emoji配置:优先使用aiCommit.useEmoji,如果未设置则使用全局useEmoji,默认true
|
|
384
|
+
const useEmoji = aiConfig.useEmoji !== undefined ? aiConfig.useEmoji : (config.useEmoji !== false);
|
|
324
385
|
|
|
325
386
|
// 获取 git diff
|
|
326
387
|
const diff = getGitDiff();
|
|
@@ -334,7 +395,7 @@ export async function generateAICommitMessage(
|
|
|
334
395
|
diff.length > maxDiffLength ? diff.slice(0, maxDiffLength) + "\n..." : diff;
|
|
335
396
|
|
|
336
397
|
// 构建 prompt
|
|
337
|
-
const prompt = buildPrompt(truncatedDiff, language, detailedDescription);
|
|
398
|
+
const prompt = buildPrompt(truncatedDiff, language, detailedDescription, useEmoji);
|
|
338
399
|
|
|
339
400
|
// 根据提供商调用对应的 API
|
|
340
401
|
const providerInfo = AI_PROVIDERS[provider];
|
package/src/commands/commit.ts
CHANGED
|
@@ -277,14 +277,17 @@ export async function commit(): Promise<void> {
|
|
|
277
277
|
return;
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
-
//
|
|
281
|
-
|
|
282
|
-
execSync(`git commit -
|
|
280
|
+
// 处理多行消息:使用 git commit -F - 通过 stdin 传递
|
|
281
|
+
// 这样可以正确处理包含换行符的 commit message
|
|
282
|
+
execSync(`git commit -F -`, {
|
|
283
|
+
input: message,
|
|
284
|
+
});
|
|
283
285
|
spinner.succeed("提交成功");
|
|
284
286
|
|
|
285
287
|
// 显示提交信息
|
|
286
288
|
const commitHash = execOutput("git rev-parse --short HEAD");
|
|
287
289
|
console.log(colors.dim(`commit: ${commitHash}`));
|
|
290
|
+
console.log("");
|
|
288
291
|
} catch (error) {
|
|
289
292
|
spinner.fail("提交失败");
|
|
290
293
|
console.log("");
|
|
@@ -299,6 +302,9 @@ export async function commit(): Promise<void> {
|
|
|
299
302
|
console.log(colors.yellow("你可以手动执行以下命令:"));
|
|
300
303
|
console.log(colors.cyan(` git commit -m "${message}"`));
|
|
301
304
|
console.log("");
|
|
305
|
+
|
|
306
|
+
// 重新抛出错误,让调用者知道提交失败了
|
|
307
|
+
throw error;
|
|
302
308
|
}
|
|
303
309
|
}
|
|
304
310
|
|
package/src/commands/init.ts
CHANGED
|
@@ -283,12 +283,35 @@ export async function init(): Promise<void> {
|
|
|
283
283
|
theme,
|
|
284
284
|
});
|
|
285
285
|
|
|
286
|
+
const aiUseEmoji = await select({
|
|
287
|
+
message: "AI 生成的 commit message 是否包含 emoji?",
|
|
288
|
+
choices: [
|
|
289
|
+
{
|
|
290
|
+
name: "是(推荐)",
|
|
291
|
+
value: true,
|
|
292
|
+
description: "如:✨ feat(auth): 添加用户登录功能"
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
name: "否",
|
|
296
|
+
value: false,
|
|
297
|
+
description: "如:feat(auth): 添加用户登录功能"
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
name: "跟随全局设置",
|
|
301
|
+
value: undefined,
|
|
302
|
+
description: `当前全局设置:${useEmoji ? '启用' : '禁用'} emoji`
|
|
303
|
+
},
|
|
304
|
+
],
|
|
305
|
+
theme,
|
|
306
|
+
});
|
|
307
|
+
|
|
286
308
|
config.aiCommit = {
|
|
287
309
|
enabled: true,
|
|
288
310
|
provider: aiProvider as "github" | "openai" | "claude" | "ollama",
|
|
289
311
|
apiKey: apiKey || undefined,
|
|
290
312
|
language: language as "zh-CN" | "en-US",
|
|
291
313
|
detailedDescription,
|
|
314
|
+
useEmoji: aiUseEmoji,
|
|
292
315
|
};
|
|
293
316
|
|
|
294
317
|
// 根据提供商设置默认模型
|