ai-git-tools 2.1.2 → 2.1.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/README.md CHANGED
@@ -440,7 +440,7 @@ github: {
440
440
 
441
441
  ## 🔧 環境需求
442
442
 
443
- - **Node.js** >= 18.0.0
443
+ - **Node.js** >= 20.19.0(或 >= 22.12.0
444
444
  - **Git** 已安裝並設定
445
445
  - **GitHub CLI** (用於 PR 功能)
446
446
  \`\`\`bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-git-tools",
3
- "version": "2.1.2",
3
+ "version": "2.1.3",
4
4
  "description": "AI-powered Git automation tools for commit messages and PR generation",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -27,7 +27,7 @@
27
27
  "author": "Yiso Tsao <yiso05255@gmail.com>",
28
28
  "license": "MIT",
29
29
  "engines": {
30
- "node": ">=18.0.0"
30
+ "node": "^20.19.0 || >=22.12.0"
31
31
  },
32
32
  "files": [
33
33
  "bin/",
@@ -63,6 +63,19 @@ export function hasApplyFailures(results = []) {
63
63
  return results.some(result => result.applied === false && !result.skipped);
64
64
  }
65
65
 
66
+ /**
67
+ * 確認 preview 至少產生一筆可套用草稿
68
+ * @param {object} draft
69
+ */
70
+ export function validateGeneratedDraft(draft = {}) {
71
+ if (!Array.isArray(draft.drafts) || draft.drafts.length === 0) {
72
+ const details = draft.failures?.map(failure => `#${failure.issueId}: ${failure.error}`).join(';');
73
+ throw new Error(
74
+ `沒有成功產生任何 Issue 更新草稿${details ? `。失敗原因:${details}` : ''}`
75
+ );
76
+ }
77
+ }
78
+
66
79
  /**
67
80
  * 執行 Redmine Issue preview 或 apply
68
81
  * @param {object} options
@@ -94,6 +107,7 @@ export async function redmineUpdateCommand(options = {}) {
94
107
  maxRetries: config.ai.maxRetries,
95
108
  });
96
109
 
110
+ validateGeneratedDraft(draft);
97
111
  console.log(renderPreview(draft.drafts));
98
112
  for (const failure of draft.failures) {
99
113
  console.log(`❌ Issue #${failure.issueId} 無法產生更新:${failure.error}`);
@@ -6,6 +6,31 @@
6
6
  import { CopilotClient, approveAll } from '@github/copilot-sdk';
7
7
 
8
8
  export class AIClient {
9
+ /**
10
+ * 判斷 Node.js 是否符合 Copilot SDK 的版本需求
11
+ * @param {string} version
12
+ * @returns {boolean}
13
+ */
14
+ static isSupportedNodeVersion(version = process.versions.node) {
15
+ const match = String(version).match(/^(\d+)\.(\d+)\.(\d+)/);
16
+ if (!match) return false;
17
+
18
+ const major = Number(match[1]);
19
+ const minor = Number(match[2]);
20
+ return (major === 20 && minor >= 19) || (major >= 22 && (major > 22 || minor >= 12));
21
+ }
22
+
23
+ /**
24
+ * 確認 Node.js 符合 Copilot SDK 的版本需求
25
+ */
26
+ static assertSupportedNodeVersion() {
27
+ if (!AIClient.isSupportedNodeVersion()) {
28
+ throw new Error(
29
+ `目前 Node.js ${process.versions.node} 不符合 Copilot SDK 需求。請升級至 Node.js 20.19+ 或 22.12+。`
30
+ );
31
+ }
32
+ }
33
+
9
34
  /**
10
35
  * 檢測是否為 Copilot 授權相關的錯誤
11
36
  */
@@ -30,6 +55,7 @@ export class AIClient {
30
55
  * 發送 prompt 並等待回應(帶重試機制和超時保護)
31
56
  */
32
57
  static async sendAndWait(prompt, model = 'claude-haiku-4.5', maxRetries = 3, timeout = 150000) {
58
+ AIClient.assertSupportedNodeVersion();
33
59
  let lastError = null;
34
60
 
35
61
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
@@ -1,4 +1,5 @@
1
1
  import { CopilotClient, approveAll } from '@github/copilot-sdk';
2
+ import { AIClient } from '../../core/ai-client.js';
2
3
  import { CONSTANTS } from '../../utils/constants.js';
3
4
  import { log } from '../../utils/logger.js';
4
5
  import { isCopilotAuthError } from '../../utils/helpers.js';
@@ -26,6 +27,7 @@ export class AIAnalyzer {
26
27
  * 取得(或建立)共用的 CopilotClient
27
28
  */
28
29
  async _getOrCreateClient() {
30
+ AIClient.assertSupportedNodeVersion();
29
31
  if (!this._client) {
30
32
  this._client = new CopilotClient();
31
33
  }