ai-git-tools 2.0.20 → 2.0.22

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/README.md CHANGED
@@ -163,6 +163,7 @@ npx ai-git-tools pr [選項]
163
163
  --no-confirm 跳過確認直接創建
164
164
  --interactive-reviewers 啟用互動式 reviewer 選擇 (預設啟用)
165
165
  --auto-labels 自動添加 Labels (預設啟用)
166
+ --include-impact 在 PR 中包含影響範圍分析和注意事項 (預設關閉)
166
167
  \`\`\`
167
168
 
168
169
  **範例:**
@@ -213,6 +214,7 @@ export default {
213
214
  github: {
214
215
  defaultBase: 'release', // 預設目標分支:'release'=自動查找最新,或指定具體分支名
215
216
  autoLabels: true, // 自動添加 Labels
217
+ includeImpactAnalysis: false, // 是否在 PR 中包含影響範圍分析和注意事項 (使用 --include-impact 啟用)
216
218
  },
217
219
 
218
220
  // Reviewer 設定
package/bin/cli.js CHANGED
@@ -52,11 +52,10 @@ program
52
52
  .description('AI 自動生成 PR 並創建 Pull Request')
53
53
  .option('--base <branch>', '指定目標分支')
54
54
  .option('--model <model>', '指定 AI 模型')
55
- .option('--org <org-name>', '指定 GitHub 組織名稱')
56
55
  .option('--preview', '僅預覽 PR 內容,不實際創建')
57
56
  .option('--no-confirm', '跳過確認直接創建')
58
- .option('--auto-labels', '自動添加 Labels')
59
- .option('--no-labels', '不添加 Labels')
57
+ .option('--auto-labels', '自動添加 Labels (預設啟用)')
58
+ .option('--include-impact', ' PR 中包含影響範圍分析和注意事項 (預設關閉)')
60
59
  .action(prCommand);
61
60
 
62
61
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-git-tools",
3
- "version": "2.0.20",
3
+ "version": "2.0.22",
4
4
  "description": "AI-powered Git automation tools for commit messages and PR generation",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -23,9 +23,9 @@ export default {
23
23
 
24
24
  // GitHub 相關配置
25
25
  github: {
26
- orgName: '', // GitHub 組織名稱(留空則自動從 git remote 取得)
27
- defaultBase: 'release', // PR分支(使用 'release' 自動偵測最新 release 分支,如 release-2025-m11.1)
26
+ defaultBase: 'release', // PR 預設目標分支(使用 'release' 自動偵測最新 release 分支,如 release-2025-m11.1)
28
27
  autoLabels: true, // 自動新增 Labels
28
+ includeImpactAnalysis: false, // 是否在 PR 中包含影響範圍分析和注意事項(使用 --include-impact 啟用)
29
29
  },
30
30
 
31
31
  // Reviewers 相關配置
@@ -38,7 +38,7 @@ export default {
38
38
 
39
39
  // 輸出相關配置
40
40
  output: {
41
- verbose: false, // 詳細輸出
41
+ verbose: true, // 詳細輸出
42
42
  },
43
43
  };
44
44
  `;
@@ -4,7 +4,6 @@
4
4
  * 支援從任何目錄下的 .ai-git-config.mjs 載入配置
5
5
  */
6
6
 
7
- import { execSync } from 'child_process';
8
7
  import { existsSync } from 'fs';
9
8
  import { resolve } from 'path';
10
9
 
@@ -111,7 +110,6 @@ export function parsePRCliArgs() {
111
110
  noConfirm: false,
112
111
  autoReviewers: false,
113
112
  autoLabels: null,
114
- orgName: null,
115
113
  };
116
114
 
117
115
  for (let i = 0; i < args.length; i++) {
@@ -122,9 +120,6 @@ export function parsePRCliArgs() {
122
120
  case '--model':
123
121
  config.model = args[++i];
124
122
  break;
125
- case '--org':
126
- config.orgName = args[++i];
127
- break;
128
123
  case '--preview':
129
124
  config.preview = true;
130
125
  break;
@@ -134,9 +129,6 @@ export function parsePRCliArgs() {
134
129
  case '--auto-labels':
135
130
  config.autoLabels = true;
136
131
  break;
137
- case '--no-labels':
138
- config.autoLabels = false;
139
- break;
140
132
  default:
141
133
  break;
142
134
  }
@@ -166,31 +158,20 @@ export async function loadPRConfig() {
166
158
  if (!config) {
167
159
  config = {
168
160
  ai: { model: 'gpt-4.1', maxDiffLength: 8000, maxRetries: 3 },
169
- github: { orgName: '', defaultBase: 'release', autoLabels: true },
161
+ github: { defaultBase: 'release', autoLabels: true },
170
162
  reviewers: { autoSelect: true, maxSuggested: 5, gitHistoryDepth: 20, excludeAuthors: [] },
171
163
  output: { verbose: false, saveHistory: false },
172
164
  };
173
165
  }
174
166
 
175
- // 如果 orgName 為空,嘗試從 git remote 取得,否則使用 'kingsinfo-project'
176
- if (!config.github.orgName) {
177
- try {
178
- const remoteUrl = execSync('git config --get remote.origin.url', { encoding: 'utf-8' }).trim();
179
- const match = remoteUrl.match(/github\.com[:/]([^/]+)\//);
180
- config.github.orgName = match ? match[1] : 'kingsinfo-project';
181
- } catch (error) {
182
- config.github.orgName = 'kingsinfo-project';
183
- }
167
+ // 確保 github 物件存在
168
+ if (!config.github) {
169
+ config.github = {};
184
170
  }
185
171
 
186
172
  // 合併命令行參數
187
173
  const cliConfig = parsePRCliArgs();
188
174
  if (cliConfig.model) config.ai.model = cliConfig.model;
189
- if (cliConfig.orgName) config.github.orgName = cliConfig.orgName;
190
- if (cliConfig.autoReviewers) config.reviewers.autoSelect = cliConfig.autoReviewers;
191
- if (cliConfig.autoLabels !== null) config.github.autoLabels = cliConfig.autoLabels;
192
-
193
- config.baseBranch = cliConfig.baseBranch;
194
175
  config.headBranch = cliConfig.headBranch;
195
176
  config.draft = cliConfig.draft;
196
177
  config.preview = cliConfig.preview;
@@ -105,6 +105,7 @@ ${skillsSummary}
105
105
  # [type]: [PR 標題]
106
106
 
107
107
  > type 必須是以下之一:feat / fix / refactor / style / docs / test / chore / perf
108
+ > **重要**:如果有新增任何功能、新增檔案、新增 API、新增組件,優先使用 **feat**
108
109
 
109
110
  ## 📝 變更摘要
110
111
  [簡述這個 PR 的主要目的和影響範圍,2-3 句話]
@@ -123,7 +124,18 @@ ${skillsSummary}
123
124
  - [ ] ⚡ 效能改進 (perf)
124
125
  - [ ] 🔧 其他 (chore)
125
126
 
126
- > 請根據實際變更勾選對應的類型(可複選)
127
+ > **重要**: 請仔細分析 diff 和 commit 訊息,**自動勾選**對應的類型(可複選),將 [ ] 改為 [x]
128
+ >
129
+ > **判斷準則**:
130
+ > - ✨ **新功能 (feat)**: 新增檔案、新增 API、新增組件、新增功能邏輯、新增配置選項
131
+ > - 🐛 **Bug 修復 (fix)**: 修復錯誤、修正邏輯問題
132
+ > - ♻️ **重構 (refactor)**: 重組程式碼結構但不改變功能
133
+ > - 💄 **樣式調整 (style)**: UI/CSS 調整、格式化
134
+ > - 📝 **文件更新 (docs)**: README、註解、文檔變更
135
+ > - ⚡ **效能改進 (perf)**: 優化效能
136
+ > - 🔧 **其他 (chore)**: 建構工具、依賴更新、配置調整
137
+ >
138
+ > **特別注意**: 如果 diff 中有「新增檔案」或「新增功能」,**務必勾選** ✨ 新功能 (feat)
127
139
 
128
140
  ## 🧪 測試方法
129
141
  1. [具體的測試步驟 1]
@@ -166,6 +178,12 @@ ${skillsSummary}
166
178
  4. 全部使用繁體中文(台灣正體)
167
179
  5. 不要在開頭加引導語句
168
180
  6. 直接開始輸出 # [type]: [標題]
181
+ 7. **變更類型判斷必須準確**:
182
+ - 檢查 diff 中是否有 "new file mode" 或大量 "+++" 行(表示新增檔案)
183
+ - 檢查 commit 訊息是否包含「新增」、「add」、「feat」等關鍵字
184
+ - 檢查主要變更列表,如果提到「新增 xxx」就必須勾選 ✨ 新功能 (feat)
185
+ - 新增配置檔、新增組件、新增 API、新增功能都算 feat
186
+ - 一個 PR 可以同時是多種類型(如:feat + refactor + chore)
169
187
 
170
188
  ---
171
189
 
@@ -14,6 +14,7 @@ export function parseCliArgs() {
14
14
  noConfirm: false,
15
15
  interactiveReviewers: undefined,
16
16
  autoLabels: null,
17
+ includeImpactAnalysis: null,
17
18
  };
18
19
 
19
20
  for (let i = 0; i < args.length; i++) {
@@ -39,6 +40,9 @@ export function parseCliArgs() {
39
40
  case '--auto-labels':
40
41
  config.autoLabels = true;
41
42
  break;
43
+ case '--include-impact':
44
+ config.includeImpactAnalysis = true;
45
+ break;
42
46
  case '--help':
43
47
  showHelp();
44
48
  process.exit(0);
@@ -67,7 +71,7 @@ export async function loadConfig() {
67
71
  // 使用內建預設值
68
72
  config = {
69
73
  ai: { model: 'gpt-4.1', maxDiffLength: 8000, maxRetries: 3 },
70
- github: { defaultBase: 'release', autoLabels: true },
74
+ github: { defaultBase: 'release', autoLabels: true, includeImpactAnalysis: false },
71
75
  reviewers: { interactiveReviewers: true, maxSuggested: 5, gitHistoryDepth: 20, excludeAuthors: [] },
72
76
  output: { verbose: false, saveHistory: false },
73
77
  };
@@ -80,6 +84,7 @@ export async function loadConfig() {
80
84
  if (cliConfig.model) config.ai.model = cliConfig.model;
81
85
  if (cliConfig.interactiveReviewers !== undefined) config.reviewers.interactiveReviewers = cliConfig.interactiveReviewers;
82
86
  if (cliConfig.autoLabels !== null) config.github.autoLabels = cliConfig.autoLabels;
87
+ if (cliConfig.includeImpactAnalysis !== null) config.github.includeImpactAnalysis = cliConfig.includeImpactAnalysis;
83
88
 
84
89
  // 其他 CLI 參數直接加入 config
85
90
  config.baseBranch = cliConfig.baseBranch;
@@ -113,13 +113,6 @@ export class GitHubAPI {
113
113
  * 從 GitHub 抓取組織的團隊列表
114
114
  */
115
115
  async fetchTeams(orgName = this.orgName) {
116
- // 如果沒有 orgName,直接返回空結果
117
- if (!orgName || orgName.trim() === '') {
118
- log.warning('未設置 GitHub 組織名稱,且無法自動偵測');
119
- log.info('請在 .ai-pr-config.js 中設置 github.orgName 或使用 --org 參數\n');
120
- return { teams: {}, members: [] };
121
- }
122
-
123
116
  try {
124
117
  // 先檢查認證狀態
125
118
  const authStatus = this.checkAuth();
@@ -198,8 +191,7 @@ export class GitHubAPI {
198
191
  console.log(' 1. 已安裝 GitHub CLI: brew install gh');
199
192
  console.log(' 2. 已執行認證: gh auth login');
200
193
  console.log(' 3. 選擇正確的認證範圍(需要 read:org 權限)');
201
- console.log(` 4. 有權限存取 ${orgName} 組織`);
202
- console.log(' 5. 組織名稱正確(可用 --org 參數指定)\n');
194
+ console.log(` 4. 有權限存取 ${orgName} 組織\n`);
203
195
 
204
196
  log.info('提示: 你仍可以手動輸入 reviewer 的 GitHub username\n');
205
197
 
@@ -286,19 +286,27 @@ export class PRWorkflow {
286
286
  // 生成 PR 標題和描述
287
287
  const { title, body } = await this.ai.generatePRContent(changeData.commits, changeData.diff);
288
288
 
289
- // 分析影響範圍
290
- log.step('正在使用 AI 深度分析影響範圍和潛在問題...\n');
291
- const { blastRadius, warnings } = await this.ai.analyzeImpact(
292
- changeData.changedFiles,
293
- changeData.diff,
294
- changeData.commits
295
- );
289
+ let enhancedBody = body;
290
+ let blastRadius = null;
291
+ let warnings = [];
292
+
293
+ // 根據配置決定是否進行影響範圍分析
294
+ if (this.config.github.includeImpactAnalysis === true) {
295
+ log.step('正在使用 AI 深度分析影響範圍和潛在問題...\n');
296
+ const analysis = await this.ai.analyzeImpact(
297
+ changeData.changedFiles,
298
+ changeData.diff,
299
+ changeData.commits
300
+ );
301
+ blastRadius = analysis.blastRadius;
302
+ warnings = analysis.warnings;
296
303
 
297
- // 顯示分析結果摘要
298
- this.displayAnalysisSummary(blastRadius, warnings);
304
+ // 顯示分析結果摘要
305
+ this.displayAnalysisSummary(blastRadius, warnings);
299
306
 
300
- // 將分析結果附加到 body
301
- const enhancedBody = this.ai.appendAnalysisToBody(body, blastRadius, warnings);
307
+ // 將分析結果附加到 body
308
+ enhancedBody = this.ai.appendAnalysisToBody(body, blastRadius, warnings);
309
+ }
302
310
 
303
311
  return { title, body: enhancedBody, blastRadius, warnings };
304
312
  }