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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-git-tools",
|
|
3
|
-
"version": "2.1.
|
|
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": "
|
|
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}`);
|
package/src/core/ai-client.js
CHANGED
|
@@ -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
|
}
|