@yeepay/coderocket-mcp 1.2.3 → 1.2.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/CHANGELOG.md +44 -1
- package/README.md +39 -6
- package/bin/coderocket-mcp +124 -6
- package/dist/banner.js +2 -2
- package/dist/coderocket.d.ts.map +1 -1
- package/dist/coderocket.js +42 -78
- package/dist/coderocket.js.map +1 -1
- package/dist/index.js +21 -286
- package/dist/index.js.map +1 -1
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +38 -6
- package/dist/test.js.map +1 -1
- package/dist/toolDefinitions.d.ts +8 -0
- package/dist/toolDefinitions.d.ts.map +1 -0
- package/dist/toolDefinitions.js +141 -0
- package/dist/toolDefinitions.js.map +1 -0
- package/package.json +3 -3
- package/review_logs/review-2eacf48a.md +69 -0
- package/review_logs/review-d3bd2f0.md +35 -0
- package/review_logs/review-d6c54600.md +28 -0
package/CHANGELOG.md
CHANGED
@@ -5,6 +5,50 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [1.2.5] - 2025-08-01
|
9
|
+
|
10
|
+
### ✨ 统一提示词系统
|
11
|
+
|
12
|
+
#### Added
|
13
|
+
- **统一提示词系统**:所有代码审查功能现在使用统一的 `git-commit-review-prompt.md` 提示词
|
14
|
+
- **提示词自定义文档**:添加了完整的提示词自定义指南和使用说明
|
15
|
+
- **统一性测试**:新增专门的测试用例验证统一提示词的使用
|
16
|
+
|
17
|
+
#### Changed
|
18
|
+
- 移除了不再使用的 `code-review-prompt` 提示词,简化了提示词管理
|
19
|
+
- 更新了内置默认提示词,适配所有审查场景
|
20
|
+
- 优化了 PromptManager 的预加载逻辑,只加载必要的提示词
|
21
|
+
|
22
|
+
#### Documentation
|
23
|
+
- 更新了 README.md,添加了提示词自定义章节
|
24
|
+
- 说明了统一提示词的优势:一致性、维护性、可预测性
|
25
|
+
- 提供了项目级和全局级提示词自定义示例
|
26
|
+
|
27
|
+
## [1.2.4] - 2025-08-01
|
28
|
+
|
29
|
+
### 🎨 Enhanced User Experience: Banner Integration
|
30
|
+
|
31
|
+
#### ✨ Added
|
32
|
+
- **Banner in Version Command**: Added beautiful ASCII Art banner to `version` command output
|
33
|
+
- **Banner in Help Command**: Added banner display to `help` command for consistent branding
|
34
|
+
- **Enhanced Version Info**: Version command now shows detailed package information including:
|
35
|
+
- Package version with emoji indicators
|
36
|
+
- Installation path for debugging
|
37
|
+
- NPM package name for reference
|
38
|
+
- Documentation link for easy access
|
39
|
+
|
40
|
+
#### 🔧 Fixed
|
41
|
+
- **Duplicate Help Text**: Removed duplicate "用法" (Usage) line in help command output
|
42
|
+
- **Consistent Branding**: All user-facing commands now display the professional banner
|
43
|
+
- **Better User Experience**: Commands provide more informative and visually appealing output
|
44
|
+
|
45
|
+
#### 🧪 Quality Assurance
|
46
|
+
- **Tested All Commands**: Verified banner display in `version`, `help`, and startup commands
|
47
|
+
- **Error Handling**: Added fallback behavior if banner module fails to load
|
48
|
+
- **No Breaking Changes**: All existing functionality preserved with enhanced presentation
|
49
|
+
|
50
|
+
---
|
51
|
+
|
8
52
|
## [1.2.3] - 2025-08-01
|
9
53
|
|
10
54
|
### 🔧 Critical Dependency Fix: Complete Independence
|
@@ -118,7 +162,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
118
162
|
#### 🔧 Enhanced
|
119
163
|
- **Prompt Enhancement**: All prompts now explicitly request Chinese responses
|
120
164
|
- Added language instructions to `git-commit-review-prompt`
|
121
|
-
- Added language instructions to `code-review-prompt`
|
122
165
|
- Enhanced `executeAIReview` method to dynamically add language requirements
|
123
166
|
|
124
167
|
#### 📝 Configuration Updates
|
package/README.md
CHANGED
@@ -27,6 +27,7 @@
|
|
27
27
|
- [MCP工具](#-mcp工具)
|
28
28
|
- [配置说明](#️-配置说明)
|
29
29
|
- [使用示例](#-使用示例)
|
30
|
+
- [提示词自定义](#-提示词自定义)
|
30
31
|
- [故障排除](#-故障排除)
|
31
32
|
- [开发指南](#-开发指南)
|
32
33
|
|
@@ -109,9 +110,6 @@ npx @yeepay/coderocket-mcp review_changes
|
|
109
110
|
# 配置Gemini(推荐)
|
110
111
|
export GEMINI_API_KEY="your_gemini_api_key"
|
111
112
|
|
112
|
-
# 或配置OpenCode
|
113
|
-
export OPENCODE_API_KEY="your_opencode_api_key"
|
114
|
-
|
115
113
|
# 或配置ClaudeCode
|
116
114
|
export CLAUDECODE_API_KEY="your_claudecode_api_key"
|
117
115
|
```
|
@@ -198,7 +196,7 @@ CodeRocket MCP 提供以下工具:
|
|
198
196
|
配置AI服务设置,包括服务选择、API密钥等。
|
199
197
|
|
200
198
|
**参数:**
|
201
|
-
- `service` (string): AI服务名称 (gemini/
|
199
|
+
- `service` (string): AI服务名称 (gemini/claudecode)
|
202
200
|
- `scope` (string, 可选): 配置范围 (project/global)
|
203
201
|
- `api_key` (string, 可选): API密钥
|
204
202
|
- `timeout` (number, 可选): 超时时间
|
@@ -222,7 +220,6 @@ AI_MAX_RETRIES=3 # 最大重试次数
|
|
222
220
|
|
223
221
|
# API密钥
|
224
222
|
GEMINI_API_KEY=your_gemini_key
|
225
|
-
OPENCODE_API_KEY=your_opencode_key
|
226
223
|
CLAUDECODE_API_KEY=your_claudecode_key
|
227
224
|
|
228
225
|
# 日志配置
|
@@ -285,6 +282,43 @@ NODE_ENV=development # 开发模式启用详细日志
|
|
285
282
|
}
|
286
283
|
```
|
287
284
|
|
285
|
+
## 🎨 提示词自定义
|
286
|
+
|
287
|
+
CodeRocket MCP 使用统一的提示词系统,所有代码审查功能都使用同一个提示词模板:
|
288
|
+
|
289
|
+
### 统一提示词
|
290
|
+
|
291
|
+
- **统一模板**:`git-commit-review-prompt.md` - 适用于所有代码审查场景
|
292
|
+
- **功能覆盖**:Git 提交审查、代码片段审查、文件审查、变更审查
|
293
|
+
|
294
|
+
### 提示词优先级
|
295
|
+
|
296
|
+
1. **项目级提示词**(最高优先级):`./prompts/git-commit-review-prompt.md`
|
297
|
+
2. **全局提示词**:`~/.coderocket/prompts/git-commit-review-prompt.md`
|
298
|
+
3. **内置默认提示词**(最低优先级)
|
299
|
+
|
300
|
+
### 自定义示例
|
301
|
+
|
302
|
+
创建项目级提示词:
|
303
|
+
|
304
|
+
```bash
|
305
|
+
mkdir -p prompts
|
306
|
+
echo "# 自定义代码审查提示词..." > prompts/git-commit-review-prompt.md
|
307
|
+
```
|
308
|
+
|
309
|
+
创建全局提示词:
|
310
|
+
|
311
|
+
```bash
|
312
|
+
mkdir -p ~/.coderocket/prompts
|
313
|
+
echo "# 全局代码审查提示词..." > ~/.coderocket/prompts/git-commit-review-prompt.md
|
314
|
+
```
|
315
|
+
|
316
|
+
### 统一性优势
|
317
|
+
|
318
|
+
- **一致性**:所有审查功能使用相同的评判标准
|
319
|
+
- **维护性**:只需维护一个提示词文件
|
320
|
+
- **可预测性**:审查结果风格和格式保持一致
|
321
|
+
|
288
322
|
## 🔍 故障排除
|
289
323
|
|
290
324
|
### 常见问题
|
@@ -308,7 +342,6 @@ npm run build
|
|
308
342
|
# 检查API密钥配置
|
309
343
|
echo $GEMINI_API_KEY
|
310
344
|
echo $CLAUDECODE_API_KEY
|
311
|
-
echo $OPENCODE_API_KEY
|
312
345
|
|
313
346
|
# 检查配置文件
|
314
347
|
cat ~/.coderocket/env
|
package/bin/coderocket-mcp
CHANGED
@@ -15,8 +15,104 @@ const __dirname = dirname(__filename);
|
|
15
15
|
|
16
16
|
const command = process.argv[2];
|
17
17
|
|
18
|
+
// 处理工具调用命令(如 review_changes, review_commit 等)
|
19
|
+
if (command && ['review_changes', 'review_commit', 'review_code', 'review_files', 'get_ai_service_status', 'configure_ai_service'].includes(command)) {
|
20
|
+
const toolArgs = process.argv.slice(3);
|
21
|
+
|
22
|
+
async function runTool() {
|
23
|
+
try {
|
24
|
+
console.log('🔧 正在初始化服务...');
|
25
|
+
const coderocketModule = await import(resolve(__dirname, '../dist/coderocket.js'));
|
26
|
+
console.log('✅ 模块导入成功');
|
27
|
+
|
28
|
+
const { CodeRocketService, ConfigManager } = coderocketModule;
|
29
|
+
console.log('✅ 类导入成功');
|
30
|
+
|
31
|
+
// 初始化配置管理器
|
32
|
+
await ConfigManager.initialize();
|
33
|
+
console.log('✅ 配置管理器初始化完成');
|
34
|
+
|
35
|
+
const service = new CodeRocketService();
|
36
|
+
console.log(`🚀 正在执行工具: ${command}`);
|
37
|
+
|
38
|
+
let result;
|
39
|
+
switch (command) {
|
40
|
+
case 'review_changes':
|
41
|
+
result = await service.reviewChanges({
|
42
|
+
repository_path: toolArgs.find(arg => arg.startsWith('--path='))?.split('=')[1],
|
43
|
+
ai_service: toolArgs.find(arg => arg.startsWith('--ai-service='))?.split('=')[1],
|
44
|
+
custom_prompt: toolArgs.find(arg => arg.startsWith('--prompt='))?.split('=')[1],
|
45
|
+
include_staged: !toolArgs.includes('--no-staged'),
|
46
|
+
include_unstaged: !toolArgs.includes('--no-unstaged'),
|
47
|
+
});
|
48
|
+
break;
|
49
|
+
case 'review_commit':
|
50
|
+
result = await service.reviewCommit({
|
51
|
+
repository_path: toolArgs.find(arg => arg.startsWith('--path='))?.split('=')[1],
|
52
|
+
commit_hash: toolArgs.find(arg => arg.startsWith('--commit='))?.split('=')[1],
|
53
|
+
ai_service: toolArgs.find(arg => arg.startsWith('--ai-service='))?.split('=')[1],
|
54
|
+
custom_prompt: toolArgs.find(arg => arg.startsWith('--prompt='))?.split('=')[1],
|
55
|
+
});
|
56
|
+
break;
|
57
|
+
case 'review_code':
|
58
|
+
result = await service.reviewCode({
|
59
|
+
code: toolArgs.find(arg => arg.startsWith('--code='))?.split('=')[1] || '',
|
60
|
+
language: toolArgs.find(arg => arg.startsWith('--language='))?.split('=')[1],
|
61
|
+
context: toolArgs.find(arg => arg.startsWith('--context='))?.split('=')[1],
|
62
|
+
ai_service: toolArgs.find(arg => arg.startsWith('--ai-service='))?.split('=')[1],
|
63
|
+
custom_prompt: toolArgs.find(arg => arg.startsWith('--prompt='))?.split('=')[1],
|
64
|
+
});
|
65
|
+
break;
|
66
|
+
case 'review_files':
|
67
|
+
const filesArg = toolArgs.find(arg => arg.startsWith('--files='))?.split('=')[1];
|
68
|
+
const files = filesArg ? filesArg.split(',') : [];
|
69
|
+
result = await service.reviewFiles({
|
70
|
+
files,
|
71
|
+
repository_path: toolArgs.find(arg => arg.startsWith('--path='))?.split('=')[1],
|
72
|
+
ai_service: toolArgs.find(arg => arg.startsWith('--ai-service='))?.split('=')[1],
|
73
|
+
custom_prompt: toolArgs.find(arg => arg.startsWith('--prompt='))?.split('=')[1],
|
74
|
+
});
|
75
|
+
break;
|
76
|
+
case 'get_ai_service_status':
|
77
|
+
console.log('📊 正在获取AI服务状态...');
|
78
|
+
result = await service.getAIServiceStatus();
|
79
|
+
console.log('✅ AI服务状态获取完成');
|
80
|
+
break;
|
81
|
+
case 'configure_ai_service':
|
82
|
+
result = await service.configureAIService({
|
83
|
+
service: toolArgs.find(arg => arg.startsWith('--service='))?.split('=')[1] || 'gemini',
|
84
|
+
api_key: toolArgs.find(arg => arg.startsWith('--api-key='))?.split('=')[1],
|
85
|
+
scope: toolArgs.find(arg => arg.startsWith('--scope='))?.split('=')[1] || 'project',
|
86
|
+
language: toolArgs.find(arg => arg.startsWith('--language='))?.split('=')[1],
|
87
|
+
timeout: toolArgs.find(arg => arg.startsWith('--timeout='))?.split('=')[1] ?
|
88
|
+
parseInt(toolArgs.find(arg => arg.startsWith('--timeout='))?.split('=')[1], 10) : undefined,
|
89
|
+
max_retries: toolArgs.find(arg => arg.startsWith('--max-retries='))?.split('=')[1] ?
|
90
|
+
parseInt(toolArgs.find(arg => arg.startsWith('--max-retries='))?.split('=')[1], 10) : undefined,
|
91
|
+
});
|
92
|
+
break;
|
93
|
+
default:
|
94
|
+
throw new Error(`工具 ${command} 暂未实现`);
|
95
|
+
}
|
96
|
+
|
97
|
+
// 输出结果
|
98
|
+
if (typeof result === 'object') {
|
99
|
+
console.log(JSON.stringify(result, null, 2));
|
100
|
+
} else {
|
101
|
+
console.log(result);
|
102
|
+
}
|
103
|
+
} catch (error) {
|
104
|
+
console.error(`❌ 工具执行失败: ${error.message}`);
|
105
|
+
if (process.env.DEBUG === 'true') {
|
106
|
+
console.error('🔍 详细错误信息:', error);
|
107
|
+
}
|
108
|
+
process.exit(1);
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
runTool();
|
113
|
+
}
|
18
114
|
// 如果没有命令或命令是 start,直接启动 MCP 服务器
|
19
|
-
if (!command || command === 'start') {
|
115
|
+
else if (!command || command === 'start') {
|
20
116
|
// 直接导入并启动 MCP 服务器(不使用 spawn)
|
21
117
|
const serverPath = resolve(__dirname, '../dist/index.js');
|
22
118
|
|
@@ -55,10 +151,19 @@ if (!command || command === 'start') {
|
|
55
151
|
case 'help':
|
56
152
|
case '--help':
|
57
153
|
case '-h':
|
58
|
-
|
59
|
-
|
154
|
+
// 显示帮助信息时也显示 banner
|
155
|
+
try {
|
156
|
+
const bannerPath = resolve(__dirname, '../dist/banner.js');
|
157
|
+
const { showMiniBanner } = await import(bannerPath);
|
158
|
+
showMiniBanner();
|
159
|
+
console.log('');
|
160
|
+
} catch (error) {
|
161
|
+
// 如果 banner 加载失败,继续显示帮助信息
|
162
|
+
console.log('CodeRocket MCP - 独立的AI驱动代码审查服务器');
|
163
|
+
console.log('');
|
164
|
+
}
|
60
165
|
|
61
|
-
|
166
|
+
console.log(`用法:
|
62
167
|
npx @yeepay/coderocket-mcp [命令]
|
63
168
|
|
64
169
|
命令:
|
@@ -93,13 +198,26 @@ CodeRocket MCP - 独立的AI驱动代码审查服务器
|
|
93
198
|
case 'version':
|
94
199
|
case '--version':
|
95
200
|
case '-v':
|
96
|
-
//
|
201
|
+
// 显示版本信息时也显示 banner
|
97
202
|
try {
|
203
|
+
// 动态导入 banner 模块
|
204
|
+
const bannerPath = resolve(__dirname, '../dist/banner.js');
|
205
|
+
const { showMiniBanner } = await import(bannerPath);
|
206
|
+
|
207
|
+
showMiniBanner();
|
208
|
+
console.log('');
|
209
|
+
|
210
|
+
// 读取package.json获取详细版本信息
|
98
211
|
const packagePath = resolve(__dirname, '../package.json');
|
99
212
|
const packageJson = JSON.parse(
|
100
213
|
readFileSync(packagePath, 'utf-8')
|
101
214
|
);
|
102
|
-
|
215
|
+
|
216
|
+
console.log(`📦 版本: v${packageJson.version}`);
|
217
|
+
console.log(`🏠 安装路径: ${resolve(__dirname, '..')}`);
|
218
|
+
console.log(`🔗 NPM包: @yeepay/coderocket-mcp`);
|
219
|
+
console.log(`📚 文档: https://github.com/im47cn/coderocket-mcp`);
|
220
|
+
|
103
221
|
} catch (error) {
|
104
222
|
console.error('⚠️ 无法读取版本信息:', error.message);
|
105
223
|
console.error('📁 尝试的路径:', resolve(__dirname, '../package.json'));
|
package/dist/banner.js
CHANGED
@@ -42,10 +42,10 @@ function getVersion() {
|
|
42
42
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
43
43
|
const packagePath = resolve(__dirname, '../package.json');
|
44
44
|
const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'));
|
45
|
-
return packageJson.version || '1.2.
|
45
|
+
return packageJson.version || '1.2.4';
|
46
46
|
}
|
47
47
|
catch {
|
48
|
-
return '1.2.
|
48
|
+
return '1.2.4'; // Fallback
|
49
49
|
}
|
50
50
|
}
|
51
51
|
/**
|
package/dist/coderocket.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"coderocket.d.ts","sourceRoot":"","sources":["../src/coderocket.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"coderocket.d.ts","sourceRoot":"","sources":["../src/coderocket.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,yBAAyB,EACzB,YAAY,EACZ,qBAAqB,EACrB,eAAe,EACf,SAAS,EAEV,MAAM,YAAY,CAAC;AAKpB;;;;;;;;GAQG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAA2B;IAChD,OAAO,CAAC,MAAM,CAAC,WAAW,CAAS;IAEnC;;OAEG;WACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBxC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IAa3B;;OAEG;mBACkB,gBAAgB;IAarC;;OAEG;mBACkB,iBAAiB;IAatC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,wBAAwB;IAcvC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IAmB9B;;OAEG;IACH,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,GAAG,GAAG,GAAG;IAOhD;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM;IAQlD;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM;IAK5C;;OAEG;IACH,MAAM,CAAC,YAAY,IAAI,SAAS;IAQhC;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM;IAI3B;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,MAAM;IAI9B;;OAEG;IACH,MAAM,CAAC,mBAAmB,IAAI,OAAO;IAIrC;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,MAAM;IAI9B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAW5B;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;CAWnE;AAED;;;;;;GAMG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,WAAW,CAAkC;IAE5D;;OAEG;WACU,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgCtD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAmE/B;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,IAAI;IAIzB;;OAEG;WACU,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;CAWnD;AAgXD;;;;GAIG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,WAAW,CAAkB;;IAMrC;;OAEG;YACW,iBAAiB;IAS/B;;OAEG;YACW,eAAe;IAmC7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAsDzB;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IA+CnE;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC;IAmDzE;;OAEG;YACW,kBAAkB;IAWhC;;OAEG;YACW,aAAa;IAuC3B;;OAEG;IACH,OAAO,CAAC,cAAc;IA2BtB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAoB/B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAoChC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsBxB;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC;IA0DvE;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC;IA6ErE;;OAEG;IACG,kBAAkB,CACtB,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,eAAe,CAAC;IAqE3B;;OAEG;YACW,gBAAgB;IA0C9B;;;;;;OAMG;YACW,kBAAkB;IAehC;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,qBAAqB,CAAC;CA0B3D"}
|
package/dist/coderocket.js
CHANGED
@@ -89,7 +89,7 @@ export class ConfigManager {
|
|
89
89
|
static loadEnvironmentVariables() {
|
90
90
|
const envKeys = [
|
91
91
|
'AI_SERVICE', 'AI_AUTO_SWITCH', 'AI_TIMEOUT', 'AI_MAX_RETRIES', 'AI_RETRY_DELAY',
|
92
|
-
'GEMINI_API_KEY', '
|
92
|
+
'GEMINI_API_KEY', 'CLAUDECODE_API_KEY',
|
93
93
|
'NODE_ENV', 'DEBUG'
|
94
94
|
];
|
95
95
|
envKeys.forEach(key => {
|
@@ -254,7 +254,7 @@ export class PromptManager {
|
|
254
254
|
|
255
255
|
## 角色定义
|
256
256
|
|
257
|
-
|
257
|
+
你是一名资深的代码审阅专家,拥有丰富的软件开发经验和架构设计能力。你的任务是进行专业、深入、自动化的代码审阅,并提供一份准确、实用、可操作的审阅报告。
|
258
258
|
|
259
259
|
## 执行模式
|
260
260
|
|
@@ -266,97 +266,49 @@ export class PromptManager {
|
|
266
266
|
|
267
267
|
## 审阅指令
|
268
268
|
|
269
|
-
### 1.
|
269
|
+
### 1. 代码分析
|
270
270
|
|
271
|
-
|
271
|
+
对提供的代码内容进行全面分析,包括代码结构、逻辑实现、依赖关系等。
|
272
272
|
|
273
|
-
### 2.
|
273
|
+
### 2. 上下文理解
|
274
274
|
|
275
|
-
|
276
|
-
|
277
|
-
* **制定搜索策略**: 根据 commit message 的描述,制定关键词搜索策略(如:功能名、类名、修复的bug信息等)。
|
278
|
-
* **全面搜索验证**: 在整个代码库中搜索相关的功能实现、依赖关系、配置和测试文件。
|
279
|
-
* **完整性验证**: **对比搜索结果与实际修改内容**,检查是否存在应修改但未修改的**遗漏文件**。这是评估目标达成度的核心依据。
|
275
|
+
根据代码内容和提供的上下文信息,理解代码的功能目标和实现意图。
|
280
276
|
|
281
277
|
### 3. 审阅维度与标准
|
282
278
|
|
283
279
|
请从以下维度进行系统性审查:
|
284
280
|
|
285
|
-
*
|
286
|
-
*
|
287
|
-
*
|
288
|
-
*
|
289
|
-
|
281
|
+
* **功能完整性与正确性**:
|
282
|
+
* **逻辑正确性**: 代码逻辑是否正确?是否有效处理了边缘情况?
|
283
|
+
* **功能实现**: 是否完整实现了预期的功能?是否有未完成的功能点?
|
284
|
+
* **错误处理**: 是否有适当的错误处理和异常捕获?
|
285
|
+
* **代码质量与规范**:
|
290
286
|
* **代码规范**: 是否遵循项目既定标准(命名、格式、设计模式)?
|
291
|
-
* **可读性与可维护性**: 代码是否清晰、结构合理、易于理解和修改?
|
287
|
+
* **可读性与可维护性**: 代码是否清晰、结构合理、易于理解和修改?
|
288
|
+
* **注释质量**: 注释是否充分且必要?是否准确描述了代码意图?
|
292
289
|
* **健壮性与风险**:
|
293
290
|
* **安全性**: 是否存在潜在的安全漏洞(如SQL注入、密钥明文、不安全的依赖等)?
|
294
291
|
* **性能**: 是否存在明显的性能瓶颈(如不合理的循环、N+1查询等)?
|
292
|
+
* **资源管理**: 是否正确管理内存、文件句柄等资源?
|
295
293
|
* **测试与文档**:
|
296
|
-
*
|
297
|
-
*
|
294
|
+
* **可测试性**: 代码是否易于测试?是否有足够的单元测试覆盖?
|
295
|
+
* **文档完整性**: 相关的内联文档(注释)是否完整准确?
|
298
296
|
* **架构与扩展性**:
|
299
297
|
* **设计合理性**: 模块职责划分是否明确?耦合度是否合理?
|
300
298
|
* **扩展性**: 设计是否考虑了未来的扩展需求?
|
299
|
+
* **重用性**: 代码是否具有良好的重用性?
|
301
300
|
|
302
301
|
### 4. 审阅结果输出
|
303
302
|
|
304
303
|
请提供详细的审阅报告,包括:
|
305
304
|
- 审阅状态(✅通过/⚠️警告/❌失败/🔍需调查)
|
306
|
-
-
|
305
|
+
- 总体评价和功能完成度
|
307
306
|
- 具体问题和改进建议
|
308
307
|
- 优先级排序的建议列表
|
308
|
+
- 优秀实践的识别
|
309
309
|
|
310
310
|
请确保审阅报告专业、准确、可操作。
|
311
311
|
|
312
|
-
**重要:请务必使用中文回复,所有审查结果、建议和评价都必须用中文表达。**`,
|
313
|
-
'code-review-prompt': `# 代码审查提示词
|
314
|
-
|
315
|
-
## 角色定义
|
316
|
-
|
317
|
-
你是一名专业的代码审查专家,具有丰富的软件开发经验。请对提供的代码进行全面、专业的审查。
|
318
|
-
|
319
|
-
## 审查维度
|
320
|
-
|
321
|
-
请从以下维度进行审查:
|
322
|
-
|
323
|
-
### 1. 代码质量
|
324
|
-
- 代码结构是否清晰合理
|
325
|
-
- 命名是否规范和有意义
|
326
|
-
- 是否遵循编程最佳实践
|
327
|
-
|
328
|
-
### 2. 功能正确性
|
329
|
-
- 代码逻辑是否正确
|
330
|
-
- 是否处理了边缘情况
|
331
|
-
- 是否有潜在的bug
|
332
|
-
|
333
|
-
### 3. 性能和安全
|
334
|
-
- 是否存在性能问题
|
335
|
-
- 是否有安全漏洞
|
336
|
-
- 资源使用是否合理
|
337
|
-
|
338
|
-
### 4. 可维护性
|
339
|
-
- 代码是否易于理解和修改
|
340
|
-
- 是否有足够的注释
|
341
|
-
- 模块化程度如何
|
342
|
-
|
343
|
-
## 输出格式
|
344
|
-
|
345
|
-
请按以下格式提供审查结果:
|
346
|
-
|
347
|
-
**审查状态**: [✅优秀/⚠️需改进/❌有问题]
|
348
|
-
|
349
|
-
**总体评价**: [简短的总体评价]
|
350
|
-
|
351
|
-
**具体建议**:
|
352
|
-
1. [具体的改进建议]
|
353
|
-
2. [具体的改进建议]
|
354
|
-
...
|
355
|
-
|
356
|
-
**优秀实践**: [值得称赞的地方]
|
357
|
-
|
358
|
-
请确保建议具体、可操作,并提供代码示例(如适用)。
|
359
|
-
|
360
312
|
**重要:请务必使用中文回复,所有审查结果、建议和评价都必须用中文表达。**`
|
361
313
|
};
|
362
314
|
return defaultPrompts[name] || `# 默认提示词\n\n请提供专业的代码审查和分析。`;
|
@@ -372,8 +324,7 @@ export class PromptManager {
|
|
372
324
|
*/
|
373
325
|
static async preloadCommonPrompts() {
|
374
326
|
const commonPrompts = [
|
375
|
-
'git-commit-review-prompt'
|
376
|
-
'code-review-prompt'
|
327
|
+
'git-commit-review-prompt'
|
377
328
|
];
|
378
329
|
await Promise.all(commonPrompts.map(name => this.loadPrompt(name).catch(error => {
|
379
330
|
logger.warn(`预加载提示词失败: ${name}`, error);
|
@@ -392,7 +343,7 @@ class GeminiService {
|
|
392
343
|
async initialize() {
|
393
344
|
// 检查 ConfigManager 是否已初始化
|
394
345
|
if (!ConfigManager.initialized) {
|
395
|
-
|
346
|
+
throw new Error('ConfigManager 未初始化,请先调用 ConfigManager.initialize()');
|
396
347
|
}
|
397
348
|
const apiKey = ConfigManager.getAPIKey('gemini');
|
398
349
|
if (apiKey) {
|
@@ -806,7 +757,7 @@ ${request.custom_prompt ? `\n附加要求:\n${request.custom_prompt}` : ''}
|
|
806
757
|
**重要:请务必使用中文回复,所有审查结果、建议和评价都必须用中文表达。**`;
|
807
758
|
// 调用AI服务进行审查
|
808
759
|
const aiService = request.ai_service || ConfigManager.getAIService();
|
809
|
-
const result = await this.executeAIReview(aiService, '
|
760
|
+
const result = await this.executeAIReview(aiService, 'git-commit-review-prompt', reviewPrompt);
|
810
761
|
logger.info('代码审查完成', {
|
811
762
|
status: result.status,
|
812
763
|
aiService: result.ai_service_used,
|
@@ -1089,9 +1040,23 @@ ${request.custom_prompt ? `\n附加要求:\n${request.custom_prompt}` : ''}
|
|
1089
1040
|
const fullPath = resolve(repoPath, filePath);
|
1090
1041
|
const content = await readFile(fullPath, 'utf-8');
|
1091
1042
|
// 限制单个文件内容长度,避免提示词过长
|
1092
|
-
const
|
1093
|
-
?
|
1094
|
-
:
|
1043
|
+
const FILE_CONTENT_CHAR_LIMIT = process.env.FILE_CONTENT_CHAR_LIMIT
|
1044
|
+
? parseInt(process.env.FILE_CONTENT_CHAR_LIMIT, 10)
|
1045
|
+
: 5000;
|
1046
|
+
let truncatedContent;
|
1047
|
+
if (content.length > FILE_CONTENT_CHAR_LIMIT) {
|
1048
|
+
// 取前后各 100 字符作为摘要
|
1049
|
+
const head = content.substring(0, 100);
|
1050
|
+
const tail = content.substring(content.length - 100);
|
1051
|
+
const omittedLength = content.length - FILE_CONTENT_CHAR_LIMIT;
|
1052
|
+
truncatedContent =
|
1053
|
+
content.substring(0, FILE_CONTENT_CHAR_LIMIT) +
|
1054
|
+
`\n... (内容已截断, 共省略 ${omittedLength} 字符)\n` +
|
1055
|
+
`内容摘要: \n前100字符: ${head}\n后100字符: ${tail}`;
|
1056
|
+
}
|
1057
|
+
else {
|
1058
|
+
truncatedContent = content;
|
1059
|
+
}
|
1095
1060
|
fileContents.push(`## 文件: ${filePath}\n\`\`\`\n${truncatedContent}\n\`\`\``);
|
1096
1061
|
}
|
1097
1062
|
catch (error) {
|
@@ -1117,7 +1082,7 @@ ${fileContents.join('\n\n')}
|
|
1117
1082
|
${request.custom_prompt ? `\n附加要求:\n${request.custom_prompt}` : ''}`;
|
1118
1083
|
// 调用AI服务进行审查
|
1119
1084
|
const aiService = request.ai_service || ConfigManager.getAIService();
|
1120
|
-
const result = await this.executeAIReview(aiService, '
|
1085
|
+
const result = await this.executeAIReview(aiService, 'git-commit-review-prompt', reviewPrompt);
|
1121
1086
|
logger.info('文件审查完成', {
|
1122
1087
|
status: result.status,
|
1123
1088
|
aiService: result.ai_service_used,
|
@@ -1214,9 +1179,8 @@ ${request.custom_prompt ? `\n附加要求:\n${request.custom_prompt}` : ''}`;
|
|
1214
1179
|
else {
|
1215
1180
|
lines.push(configLine);
|
1216
1181
|
}
|
1217
|
-
//
|
1218
|
-
|
1219
|
-
await writeFile(configFile, newConfig, 'utf-8');
|
1182
|
+
// 写回文件
|
1183
|
+
await writeFile(configFile, lines.join('\n'), 'utf-8');
|
1220
1184
|
logger.debug('配置已保存', { key, configFile, scope });
|
1221
1185
|
}
|
1222
1186
|
catch (error) {
|