ai-git-tools 2.0.18 → 2.0.20

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
@@ -158,7 +158,6 @@ npx ai-git-tools pr [選項]
158
158
 
159
159
  選項:
160
160
  -b, --base <branch> 目標分支 (預設: 配置檔的 defaultBase 或自動偵測)
161
- -h, --head <branch> 來源分支 (預設: 當前分支,通常不需指定)
162
161
  -m, --model <model> 指定 AI 模型
163
162
  --preview 僅預覽,不創建 PR
164
163
  --no-confirm 跳過確認直接創建
@@ -212,16 +211,16 @@ export default {
212
211
 
213
212
  // GitHub 設定
214
213
  github: {
215
- defaultBase: 'release', // 預設目標分支
214
+ defaultBase: 'release', // 預設目標分支:'release'=自動查找最新,或指定具體分支名
216
215
  autoLabels: true, // 自動添加 Labels
217
216
  },
218
217
 
219
218
  // Reviewer 設定
220
219
  reviewers: {
221
- interactiveReviewers: false, // 啟用 reviewer 選擇
220
+ interactiveReviewers: true, // true=啟用互動式選擇,false=不添加任何 reviewers
222
221
  maxSuggested: 5, // 最多建議人數
223
222
  gitHistoryDepth: 20, // Git 歷史分析深度
224
- excludeAuthors: [], // 排除特定作者
223
+ excludeAuthors: [], // 排除特定作者(最高優先順序,即使手動選擇也會被過濾)
225
224
  },
226
225
 
227
226
  // 輸出設定
@@ -232,6 +231,44 @@ export default {
232
231
  };
233
232
  \`\`\`
234
233
 
234
+ ### defaultBase 配置說明
235
+
236
+ \`defaultBase\` 支援兩種模式:
237
+
238
+ #### 1. 自動模式(推薦)
239
+ ```javascript
240
+ github: {
241
+ defaultBase: 'release', // 自動查找最新的 release 分支
242
+ }
243
+ ```
244
+ - 工具會自動偵測所有 \`release-*\` 或 \`release/*\` 格式的分支
245
+ - 自動選擇最新版本(優先選擇月度分支,如 release-2025-m12.1)
246
+ - 適合經常更新 release 版本的專案
247
+
248
+ #### 2. 具體分支模式
249
+ ```javascript
250
+ github: {
251
+ defaultBase: 'release-2025-m12.1', // 固定使用此分支
252
+ }
253
+ ```
254
+ - 直接使用指定的分支名稱
255
+ - 適合需要固定某個版本的情況
256
+ - 或使用 \`main\`、\`develop\` 等標準分支
257
+
258
+ **範例輸出**:
259
+ ```bash
260
+ # 使用 defaultBase: 'release'
261
+ 配置檔指定使用 release 分支,正在偵測最新版本...
262
+ 📋 偵測到的 release 分支:
263
+ 月度分支 (優先):
264
+ 1. release-2025-m12.1 ← 最新
265
+ 2. release-2025-m11.1
266
+ ✅ 自動選擇最新 release 分支: release-2025-m12.1
267
+
268
+ # 使用 defaultBase: 'release-2025-m12.1'
269
+ ✅ 使用配置檔指定的分支: release-2025-m12.1
270
+ ```
271
+
235
272
  ## 🔧 環境需求
236
273
 
237
274
  - **Node.js** >= 18.0.0
@@ -267,7 +304,7 @@ npx ai-git-tools commit-all
267
304
  ### 場景 3:快速發 PR
268
305
 
269
306
  \`\`\`bash
270
- npx ai-git-tools pr --auto-reviewers --auto-labels
307
+ npx ai-git-tools pr --auto-labels
271
308
  # ✅ 自動生成完整的 PR 標題和描述
272
309
  # ✅ 建議合適的 reviewers
273
310
  # ✅ 添加相關的 labels
package/bin/cli.js CHANGED
@@ -51,13 +51,10 @@ program
51
51
  .command('pr')
52
52
  .description('AI 自動生成 PR 並創建 Pull Request')
53
53
  .option('--base <branch>', '指定目標分支')
54
- .option('--head <branch>', '指定來源分支')
55
54
  .option('--model <model>', '指定 AI 模型')
56
55
  .option('--org <org-name>', '指定 GitHub 組織名稱')
57
- .option('--draft', '創建草稿 PR')
58
56
  .option('--preview', '僅預覽 PR 內容,不實際創建')
59
57
  .option('--no-confirm', '跳過確認直接創建')
60
- .option('--auto-reviewers', '自動選擇 reviewers')
61
58
  .option('--auto-labels', '自動添加 Labels')
62
59
  .option('--no-labels', '不添加 Labels')
63
60
  .action(prCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-git-tools",
3
- "version": "2.0.18",
3
+ "version": "2.0.20",
4
4
  "description": "AI-powered Git automation tools for commit messages and PR generation",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -119,27 +119,18 @@ export function parsePRCliArgs() {
119
119
  case '--base':
120
120
  config.baseBranch = args[++i];
121
121
  break;
122
- case '--head':
123
- config.headBranch = args[++i];
124
- break;
125
122
  case '--model':
126
123
  config.model = args[++i];
127
124
  break;
128
125
  case '--org':
129
126
  config.orgName = args[++i];
130
127
  break;
131
- case '--draft':
132
- config.draft = true;
133
- break;
134
128
  case '--preview':
135
129
  config.preview = true;
136
130
  break;
137
131
  case '--no-confirm':
138
132
  config.noConfirm = true;
139
133
  break;
140
- case '--auto-reviewers':
141
- config.autoReviewers = true;
142
- break;
143
134
  case '--auto-labels':
144
135
  config.autoLabels = true;
145
136
  break;
@@ -100,7 +100,6 @@ function showHelp() {
100
100
 
101
101
  選項:
102
102
  --base <branch> 指定目標分支 (預設: 使用配置檔的 defaultBase 或自動偵測)
103
- --head <branch> 指定來源分支 (預設: 當前分支,通常不需要指定)
104
103
  --model <model> 指定 AI 模型 (預設: gpt-4.1)
105
104
  --preview 僅預覽 PR 內容,不實際創建
106
105
  --no-confirm 跳過確認直接創建
@@ -101,8 +101,31 @@ export class PRWorkflow {
101
101
  if (!baseBranch) {
102
102
  // 優先使用配置檔中的 defaultBase
103
103
  if (this.config.github?.defaultBase) {
104
- baseBranch = this.config.github.defaultBase;
105
- log.success(`使用配置檔指定的分支: ${baseBranch}\n`);
104
+ const defaultBase = this.config.github.defaultBase;
105
+
106
+ // 如果 defaultBase 是 'release',則自動查找最新的 release 分支
107
+ if (defaultBase === 'release' || defaultBase.match(/^release$/i)) {
108
+ log.step('配置檔指定使用 release 分支,正在偵測最新版本...\n');
109
+ const allBranches = this.git.detectReleaseBranches();
110
+ const latestRelease = this.git.findLatestReleaseBranch();
111
+
112
+ if (latestRelease) {
113
+ baseBranch = latestRelease;
114
+ this.displayDetectedBranches(allBranches, latestRelease);
115
+ log.success(`自動選擇最新 release 分支: ${baseBranch}`);
116
+ log.info(`提示: 使用 --base <分支名> 指定其他分支\n`);
117
+ } else {
118
+ throw new PRError('未偵測到任何 release 分支', 'NO_RELEASE_BRANCH', [
119
+ '使用 --base 參數指定目標分支',
120
+ '或在 .ai-git-config.js 中設置具體的分支名(如 release-2025-m12.1)',
121
+ '確認遠端分支存在: git branch -r | grep release',
122
+ ]);
123
+ }
124
+ } else {
125
+ // 使用配置檔中指定的具體分支名
126
+ baseBranch = defaultBase;
127
+ log.success(`使用配置檔指定的分支: ${baseBranch}\n`);
128
+ }
106
129
  } else {
107
130
  // 如果沒有配置,則自動偵測最新的 release 分支
108
131
  log.step('正在偵測 release 分支...\n');
@@ -324,6 +347,13 @@ export class PRWorkflow {
324
347
  return null;
325
348
  }
326
349
 
350
+ // 如果禁用互動式選擇,不添加任何 reviewers
351
+ if (!this.config.reviewers.interactiveReviewers) {
352
+ console.log('ℹ️ 已禁用 reviewer 選擇(interactiveReviewers: false)\n');
353
+ log.info('提示: 你可以在創建 PR 後手動添加 reviewers\n');
354
+ return null;
355
+ }
356
+
327
357
  // 獲取當前用戶
328
358
  const currentUser = this.git.getCurrentUser();
329
359
 
@@ -332,12 +362,6 @@ export class PRWorkflow {
332
362
  changeData.changedFiles
333
363
  );
334
364
 
335
- // 如果禁用互動式選擇,直接自動選擇
336
- if (!this.config.reviewers.interactiveReviewers) {
337
- console.log('🤖 自動選擇 reviewers(基於 Git 歷史)\n');
338
- return this.reviewerSelector.autoSelectReviewers(suggestedReviewers, currentUser);
339
- }
340
-
341
365
  // 抓取 GitHub 團隊資訊(只在互動模式需要)
342
366
  const teams = await this.github.fetchTeams();
343
367
 
@@ -178,16 +178,30 @@ export class ReviewerSelector {
178
178
  }
179
179
  });
180
180
 
181
+ // 應用 excludeAuthors 過濾(優先順序最高)
182
+ const filteredIndividuals = selectedIndividuals.filter((login) => {
183
+ const shouldExclude = this.excludeAuthors.some((excluded) => {
184
+ const normalizedExcluded = excluded.toLowerCase();
185
+ return login.toLowerCase().includes(normalizedExcluded);
186
+ });
187
+
188
+ if (shouldExclude) {
189
+ log.warning(`已排除 @${login}(在 excludeAuthors 列表中)`);
190
+ }
191
+
192
+ return !shouldExclude;
193
+ });
194
+
181
195
  console.log('');
182
196
  if (selectedTeams.length > 0) {
183
197
  log.success(`已選擇團隊: ${selectedTeams.join(', ')}`);
184
198
  }
185
- if (selectedIndividuals.length > 0) {
186
- log.success(`已選擇個人: ${selectedIndividuals.map((u) => `@${u}`).join(', ')}`);
199
+ if (filteredIndividuals.length > 0) {
200
+ log.success(`已選擇個人: ${filteredIndividuals.map((u) => `@${u}`).join(', ')}`);
187
201
  }
188
202
  console.log('');
189
203
 
190
- return { teams: selectedTeams, individuals: selectedIndividuals };
204
+ return { teams: selectedTeams, individuals: filteredIndividuals };
191
205
  }
192
206
 
193
207
  /**
@@ -217,16 +231,10 @@ export class ReviewerSelector {
217
231
  }
218
232
 
219
233
  /**
220
- * 選擇 Reviewers(根據模式)
234
+ * 選擇 Reviewers(互動模式)
221
235
  */
222
236
  async select(teamsData, suggestedReviewers, currentUser) {
223
- if (this.interactiveReviewers) {
224
- // interactiveReviewers: true 表示啟用互動式選擇(手動選擇)
225
- return this.selectInteractive(teamsData, suggestedReviewers, currentUser);
226
- } else {
227
- // interactiveReviewers: false 表示自動選擇(基於 Git 歷史)
228
- console.log('🤖 自動選擇 reviewers(基於 Git 歷史)\n');
229
- return this.autoSelectReviewers(suggestedReviewers, currentUser);
230
- }
237
+ // 此方法現在只在 interactiveReviewers: true 時被調用
238
+ return this.selectInteractive(teamsData, suggestedReviewers, currentUser);
231
239
  }
232
240
  }