ai-git-tools 1.0.4 → 1.0.5
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/bin/cli.js +1 -1
- package/package.json +1 -1
- package/src/commands/commit-all.js +14 -4
- package/src/commands/pr.js +2 -2
- package/src/core/git-operations.js +32 -1
package/bin/cli.js
CHANGED
package/package.json
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import chalk from 'chalk';
|
|
8
|
+
import { existsSync } from 'fs';
|
|
8
9
|
import { loadConfig } from '../core/config-loader.js';
|
|
9
10
|
import { AIClient } from '../core/ai-client.js';
|
|
10
11
|
import { GitOperations } from '../core/git-operations.js';
|
|
@@ -42,6 +43,11 @@ async function analyzeAndGroupChanges(changes, config, logger) {
|
|
|
42
43
|
|
|
43
44
|
請分析以下的檔案變更,並將它們按照功能/目的分組。
|
|
44
45
|
|
|
46
|
+
**重要提醒**:
|
|
47
|
+
- 每個檔案都有一個 [檔案 X] 的標記,X 是索引號碼
|
|
48
|
+
- 你**必須**使用這些索引號碼,**不要**自行推測或修改檔案名稱
|
|
49
|
+
- file_indices 中只能包含上面提供的有效索引 (0 到 ${changes.length - 1})
|
|
50
|
+
|
|
45
51
|
**分組規則**:
|
|
46
52
|
1. 將相關功能的變更歸類在同一組(例如:同一個功能開發、同一個 bug 修復、相關的重構等)
|
|
47
53
|
2. 每組應該要有明確的主題
|
|
@@ -51,7 +57,7 @@ async function analyzeAndGroupChanges(changes, config, logger) {
|
|
|
51
57
|
- group_name: 群組名稱(簡短描述,繁體中文)
|
|
52
58
|
- commit_type: commit 類型(feat/fix/docs/style/refactor/test/chore/perf)
|
|
53
59
|
- commit_scope: commit 影響範圍(如 api、ui、config、auth 等,選填)
|
|
54
|
-
- file_indices:
|
|
60
|
+
- file_indices: 屬於這組的檔案索引陣列(**只能使用上面 [檔案 X] 的 X 值**)
|
|
55
61
|
- description: 這組變更的詳細說明(繁體中文)
|
|
56
62
|
|
|
57
63
|
範例輸出:
|
|
@@ -258,8 +264,8 @@ export async function commitAllCommand(options) {
|
|
|
258
264
|
// 驗證並過濾有效的檔案索引
|
|
259
265
|
const validFiles = group.file_indices
|
|
260
266
|
.filter(index => {
|
|
261
|
-
if (index < 0 || index >= changes.length) {
|
|
262
|
-
logger.warn(
|
|
267
|
+
if (typeof index !== 'number' || index < 0 || index >= changes.length) {
|
|
268
|
+
logger.warn(`群組 "${group.group_name}" 包含無效的檔案索引: ${index} (有效範圍: 0-${changes.length - 1})`);
|
|
263
269
|
return false;
|
|
264
270
|
}
|
|
265
271
|
return true;
|
|
@@ -267,7 +273,11 @@ export async function commitAllCommand(options) {
|
|
|
267
273
|
.map(index => changes[index])
|
|
268
274
|
.filter(file => {
|
|
269
275
|
if (!file || !file.filePath) {
|
|
270
|
-
logger.warn(
|
|
276
|
+
logger.warn(`檔案資訊不完整,已跳過`);
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
if (!existsSync(file.filePath)) {
|
|
280
|
+
logger.warn(`檔案不存在:${file.filePath},已跳過`);
|
|
271
281
|
return false;
|
|
272
282
|
}
|
|
273
283
|
return true;
|
package/src/commands/pr.js
CHANGED
|
@@ -13,7 +13,6 @@ import { GitHubAPI } from '../core/github-api.js';
|
|
|
13
13
|
import { Logger } from '../utils/logger.js';
|
|
14
14
|
import {
|
|
15
15
|
handleError,
|
|
16
|
-
truncateText,
|
|
17
16
|
getProjectTypePrompt,
|
|
18
17
|
} from '../utils/helpers.js';
|
|
19
18
|
|
|
@@ -50,7 +49,8 @@ async function generatePRContent(baseBranch, headBranch, config, logger) {
|
|
|
50
49
|
const diff = GitOperations.getDiffBetweenBranches(baseBranch, headBranch);
|
|
51
50
|
const commits = GitOperations.getCommitsBetweenBranches(baseBranch, headBranch);
|
|
52
51
|
|
|
53
|
-
|
|
52
|
+
// 使用智能截斷,保留前後各 50 行
|
|
53
|
+
const truncatedDiff = GitOperations.truncateDiff(diff, config.ai.maxDiffLength);
|
|
54
54
|
|
|
55
55
|
const aiClient = new AIClient(config);
|
|
56
56
|
|
|
@@ -16,6 +16,7 @@ export class GitOperations {
|
|
|
16
16
|
const result = execSync(command, {
|
|
17
17
|
encoding: 'utf-8',
|
|
18
18
|
stdio: options.silent ? 'pipe' : 'inherit',
|
|
19
|
+
maxBuffer: 50 * 1024 * 1024, // 50MB buffer 避免 ENOBUFS 錯誤
|
|
19
20
|
...options,
|
|
20
21
|
});
|
|
21
22
|
return result ? result.toString().trim() : '';
|
|
@@ -232,7 +233,37 @@ export class GitOperations {
|
|
|
232
233
|
* 獲取兩個分支之間的 diff
|
|
233
234
|
*/
|
|
234
235
|
static getDiffBetweenBranches(base, head) {
|
|
235
|
-
|
|
236
|
+
try {
|
|
237
|
+
return GitOperations.exec(`git diff ${base}...${head}`, { silent: true });
|
|
238
|
+
} catch (error) {
|
|
239
|
+
// 嘗試替代方案
|
|
240
|
+
try {
|
|
241
|
+
return GitOperations.exec(`git diff ${base}..${head}`, { silent: true });
|
|
242
|
+
} catch (fallbackError) {
|
|
243
|
+
throw new Error(`無法獲取分支差異: ${error.message}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* 智能截斷 diff
|
|
250
|
+
* 保留前後各 50 行,中間用省略標記
|
|
251
|
+
*/
|
|
252
|
+
static truncateDiff(diff, maxLength = 8000) {
|
|
253
|
+
if (diff.length <= maxLength) return diff;
|
|
254
|
+
|
|
255
|
+
const lines = diff.split('\n');
|
|
256
|
+
const contextLines = 50;
|
|
257
|
+
|
|
258
|
+
if (lines.length <= contextLines * 2) {
|
|
259
|
+
return diff;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const header = lines.slice(0, contextLines).join('\n');
|
|
263
|
+
const footer = lines.slice(-contextLines).join('\n');
|
|
264
|
+
const omittedLines = lines.length - (contextLines * 2);
|
|
265
|
+
|
|
266
|
+
return `${header}\n\n... [已省略 ${omittedLines} 行變更] ...\n\n${footer}`;
|
|
236
267
|
}
|
|
237
268
|
|
|
238
269
|
/**
|