@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/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. 第一行:<type>(<scope>): <subject>
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. 格式:<type>(<scope>): <subject>
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
- const lines = response.split('\n').map(line => line.trim()).filter(line => line);
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];
@@ -277,14 +277,17 @@ export async function commit(): Promise<void> {
277
277
  return;
278
278
  }
279
279
 
280
- // 使用 -m 参数,需要转义引号
281
- const escapedMessage = message.replace(/"/g, '\\"');
282
- execSync(`git commit -m "${escapedMessage}"`, { stdio: "pipe" });
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
 
@@ -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
  // 根据提供商设置默认模型