@yeepay/coderocket-mcp 1.4.1 → 1.5.0
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/debug-mcp-protocol.js +184 -0
- package/dist/index.js +57 -33
- package/dist/index.js.map +1 -1
- package/dist/standardToolDefinitions.d.ts +7 -0
- package/dist/standardToolDefinitions.d.ts.map +1 -0
- package/dist/standardToolDefinitions.js +129 -0
- package/dist/standardToolDefinitions.js.map +1 -0
- package/fix-mcp-config.js +60 -0
- package/fix-roocode-config.js +56 -0
- package/package.json +1 -1
- package/test-mcp-server.js +141 -0
- package/update-roocode-config-v1.5.js +74 -0
- package/verify-roocode-config.js +145 -0
@@ -0,0 +1,184 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
/**
|
4
|
+
* MCP协议调试脚本
|
5
|
+
* 模拟RooCode客户端与coderocket-mcp服务器的完整交互
|
6
|
+
*/
|
7
|
+
|
8
|
+
import { spawn } from 'child_process';
|
9
|
+
|
10
|
+
function testMCPProtocol(command, args = []) {
|
11
|
+
return new Promise((resolve, reject) => {
|
12
|
+
console.log(`🚀 启动MCP服务器: ${command} ${args.join(' ')}`);
|
13
|
+
|
14
|
+
const server = spawn(command, args, {
|
15
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
16
|
+
env: {
|
17
|
+
...process.env,
|
18
|
+
DEBUG: 'true',
|
19
|
+
NODE_ENV: 'development'
|
20
|
+
}
|
21
|
+
});
|
22
|
+
|
23
|
+
let responses = [];
|
24
|
+
let buffer = '';
|
25
|
+
|
26
|
+
// 设置超时
|
27
|
+
const timeout = setTimeout(() => {
|
28
|
+
console.log('⏰ 测试超时');
|
29
|
+
server.kill();
|
30
|
+
resolve(responses);
|
31
|
+
}, 15000);
|
32
|
+
|
33
|
+
server.stdout.on('data', (data) => {
|
34
|
+
buffer += data.toString();
|
35
|
+
|
36
|
+
// 尝试解析JSON响应
|
37
|
+
const lines = buffer.split('\n');
|
38
|
+
buffer = lines.pop() || ''; // 保留不完整的行
|
39
|
+
|
40
|
+
for (const line of lines) {
|
41
|
+
if (line.trim()) {
|
42
|
+
try {
|
43
|
+
const response = JSON.parse(line);
|
44
|
+
console.log('📨 收到响应:', JSON.stringify(response, null, 2));
|
45
|
+
responses.push(response);
|
46
|
+
} catch (e) {
|
47
|
+
console.log('📤 非JSON输出:', line);
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
});
|
52
|
+
|
53
|
+
server.stderr.on('data', (data) => {
|
54
|
+
const output = data.toString();
|
55
|
+
if (output.includes('MCP 服务器启动成功')) {
|
56
|
+
console.log('✅ 服务器启动成功,开始协议测试');
|
57
|
+
|
58
|
+
// 1. 发送初始化请求
|
59
|
+
setTimeout(() => {
|
60
|
+
console.log('\n🔧 发送初始化请求');
|
61
|
+
const initRequest = {
|
62
|
+
jsonrpc: '2.0',
|
63
|
+
id: 1,
|
64
|
+
method: 'initialize',
|
65
|
+
params: {
|
66
|
+
protocolVersion: '2024-11-05',
|
67
|
+
capabilities: {
|
68
|
+
roots: {
|
69
|
+
listChanged: true
|
70
|
+
},
|
71
|
+
sampling: {}
|
72
|
+
},
|
73
|
+
clientInfo: {
|
74
|
+
name: 'test-client',
|
75
|
+
version: '1.0.0'
|
76
|
+
}
|
77
|
+
}
|
78
|
+
};
|
79
|
+
server.stdin.write(JSON.stringify(initRequest) + '\n');
|
80
|
+
}, 500);
|
81
|
+
|
82
|
+
// 2. 发送工具列表请求
|
83
|
+
setTimeout(() => {
|
84
|
+
console.log('\n📋 发送工具列表请求');
|
85
|
+
const listToolsRequest = {
|
86
|
+
jsonrpc: '2.0',
|
87
|
+
id: 2,
|
88
|
+
method: 'tools/list',
|
89
|
+
params: {}
|
90
|
+
};
|
91
|
+
server.stdin.write(JSON.stringify(listToolsRequest) + '\n');
|
92
|
+
}, 1000);
|
93
|
+
|
94
|
+
// 3. 发送工具调用请求
|
95
|
+
setTimeout(() => {
|
96
|
+
console.log('\n🔧 发送工具调用请求');
|
97
|
+
const callToolRequest = {
|
98
|
+
jsonrpc: '2.0',
|
99
|
+
id: 3,
|
100
|
+
method: 'tools/call',
|
101
|
+
params: {
|
102
|
+
name: 'get_ai_service_status',
|
103
|
+
arguments: {}
|
104
|
+
}
|
105
|
+
};
|
106
|
+
server.stdin.write(JSON.stringify(callToolRequest) + '\n');
|
107
|
+
}, 1500);
|
108
|
+
|
109
|
+
// 4. 结束测试
|
110
|
+
setTimeout(() => {
|
111
|
+
clearTimeout(timeout);
|
112
|
+
server.kill();
|
113
|
+
resolve(responses);
|
114
|
+
}, 3000);
|
115
|
+
}
|
116
|
+
});
|
117
|
+
|
118
|
+
server.on('error', (error) => {
|
119
|
+
clearTimeout(timeout);
|
120
|
+
console.error('❌ 服务器错误:', error.message);
|
121
|
+
reject(error);
|
122
|
+
});
|
123
|
+
|
124
|
+
server.on('exit', (code, signal) => {
|
125
|
+
clearTimeout(timeout);
|
126
|
+
console.log(`🔚 服务器退出: code=${code}, signal=${signal}`);
|
127
|
+
});
|
128
|
+
});
|
129
|
+
}
|
130
|
+
|
131
|
+
async function runProtocolTest() {
|
132
|
+
console.log('🧪 开始MCP协议调试测试\n');
|
133
|
+
|
134
|
+
try {
|
135
|
+
const responses = await testMCPProtocol('node', ['dist/index.js']);
|
136
|
+
|
137
|
+
console.log('\n📊 测试结果分析:');
|
138
|
+
console.log(`总响应数: ${responses.length}`);
|
139
|
+
|
140
|
+
const initResponse = responses.find(r => r.id === 1);
|
141
|
+
const toolsResponse = responses.find(r => r.id === 2);
|
142
|
+
const callResponse = responses.find(r => r.id === 3);
|
143
|
+
|
144
|
+
if (initResponse) {
|
145
|
+
console.log('✅ 初始化响应: 正常');
|
146
|
+
console.log(' 服务器信息:', initResponse.result?.serverInfo);
|
147
|
+
} else {
|
148
|
+
console.log('❌ 初始化响应: 缺失');
|
149
|
+
}
|
150
|
+
|
151
|
+
if (toolsResponse) {
|
152
|
+
console.log('✅ 工具列表响应: 正常');
|
153
|
+
console.log(' 工具数量:', toolsResponse.result?.tools?.length || 0);
|
154
|
+
if (toolsResponse.result?.tools) {
|
155
|
+
console.log(' 工具名称:', toolsResponse.result.tools.map(t => t.name));
|
156
|
+
}
|
157
|
+
} else {
|
158
|
+
console.log('❌ 工具列表响应: 缺失');
|
159
|
+
}
|
160
|
+
|
161
|
+
if (callResponse) {
|
162
|
+
console.log('✅ 工具调用响应: 正常');
|
163
|
+
} else {
|
164
|
+
console.log('❌ 工具调用响应: 缺失');
|
165
|
+
}
|
166
|
+
|
167
|
+
console.log('\n🎯 诊断建议:');
|
168
|
+
if (responses.length === 0) {
|
169
|
+
console.log('- 服务器可能没有正确响应JSON-RPC请求');
|
170
|
+
console.log('- 检查MCP协议实现是否正确');
|
171
|
+
} else if (!toolsResponse || !toolsResponse.result?.tools?.length) {
|
172
|
+
console.log('- 工具列表为空或响应格式错误');
|
173
|
+
console.log('- 检查toolDefinitions和工具注册逻辑');
|
174
|
+
} else {
|
175
|
+
console.log('- MCP协议工作正常');
|
176
|
+
console.log('- 问题可能在RooCode客户端配置或连接');
|
177
|
+
}
|
178
|
+
|
179
|
+
} catch (error) {
|
180
|
+
console.error('❌ 协议测试失败:', error.message);
|
181
|
+
}
|
182
|
+
}
|
183
|
+
|
184
|
+
runProtocolTest().catch(console.error);
|
package/dist/index.js
CHANGED
@@ -2,13 +2,19 @@
|
|
2
2
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
5
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
6
5
|
import { readFile } from 'fs/promises';
|
7
6
|
import { resolve, dirname } from 'path';
|
8
7
|
import { fileURLToPath } from 'url';
|
9
8
|
import { CodeRocketService, initializeCodeRocket } from './coderocket.js';
|
10
|
-
import {
|
11
|
-
|
9
|
+
import { CODEROCKET_TOOLS } from './standardToolDefinitions.js';
|
10
|
+
// 调试模式检测
|
11
|
+
const DEBUG_MODE = process.env.DEBUG === 'true' || process.env.NODE_ENV === 'development';
|
12
|
+
function debugLog(message, data) {
|
13
|
+
console.error(`[CODEROCKET-MCP-DEBUG] ${new Date().toISOString()} - ${message}`);
|
14
|
+
if (data) {
|
15
|
+
console.error(`[CODEROCKET-MCP-DEBUG] Data:`, JSON.stringify(data, null, 2));
|
16
|
+
}
|
17
|
+
}
|
12
18
|
// 读取版本号
|
13
19
|
const getVersion = async () => {
|
14
20
|
try {
|
@@ -33,6 +39,7 @@ class CodeRocketMCPServer {
|
|
33
39
|
server;
|
34
40
|
codeRocketService = null;
|
35
41
|
constructor() {
|
42
|
+
debugLog('🚀 CodeRocket MCP Server 构造函数开始', { version: VERSION });
|
36
43
|
this.server = new Server({
|
37
44
|
name: 'coderocket-mcp',
|
38
45
|
version: VERSION,
|
@@ -41,63 +48,69 @@ class CodeRocketMCPServer {
|
|
41
48
|
tools: {},
|
42
49
|
},
|
43
50
|
});
|
51
|
+
debugLog('✅ MCP Server 实例创建完成');
|
44
52
|
// 延迟初始化 CodeRocketService,等待 ConfigManager 初始化完成
|
45
53
|
this.setupToolHandlers();
|
54
|
+
debugLog('✅ 工具处理器设置完成');
|
46
55
|
}
|
47
56
|
setupToolHandlers() {
|
57
|
+
debugLog('🔧 开始设置工具处理器');
|
48
58
|
// 注册工具列表处理器
|
49
59
|
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
$refStrategy: 'none',
|
57
|
-
}),
|
58
|
-
})),
|
59
|
-
};
|
60
|
+
debugLog('📋 收到工具列表请求');
|
61
|
+
debugLog('📋 返回工具列表', {
|
62
|
+
toolCount: CODEROCKET_TOOLS.length,
|
63
|
+
toolNames: CODEROCKET_TOOLS.map(t => t.name)
|
64
|
+
});
|
65
|
+
return { tools: CODEROCKET_TOOLS };
|
60
66
|
});
|
61
67
|
// 注册工具调用处理器
|
62
68
|
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
63
69
|
const { name, arguments: args } = request.params;
|
70
|
+
debugLog('🔧 收到工具调用请求', { toolName: name, args });
|
64
71
|
// 确保 CodeRocketService 已初始化
|
65
72
|
if (!this.codeRocketService) {
|
73
|
+
debugLog('❌ CodeRocketService 未初始化');
|
66
74
|
throw new Error('CodeRocketService 未初始化,请稍后重试');
|
67
75
|
}
|
68
|
-
// 辅助函数,用于创建和执行工具调用
|
69
|
-
const createToolHandler = async (schema, serviceMethod) => {
|
70
|
-
const parsedArgs = schema.parse(args);
|
71
|
-
const result = await serviceMethod.call(this.codeRocketService, parsedArgs);
|
72
|
-
return {
|
73
|
-
content: [
|
74
|
-
{
|
75
|
-
type: 'text',
|
76
|
-
text: JSON.stringify(result, null, 2),
|
77
|
-
},
|
78
|
-
],
|
79
|
-
};
|
80
|
-
};
|
81
76
|
try {
|
77
|
+
let result;
|
78
|
+
const safeArgs = args || {};
|
82
79
|
switch (name) {
|
83
80
|
case 'review_code':
|
84
|
-
|
81
|
+
result = await this.codeRocketService.reviewCode(safeArgs);
|
82
|
+
break;
|
85
83
|
case 'review_changes':
|
86
|
-
|
84
|
+
result = await this.codeRocketService.reviewChanges(safeArgs);
|
85
|
+
break;
|
87
86
|
case 'review_commit':
|
88
|
-
|
87
|
+
result = await this.codeRocketService.reviewCommit(safeArgs);
|
88
|
+
break;
|
89
89
|
case 'review_files':
|
90
|
-
|
90
|
+
result = await this.codeRocketService.reviewFiles(safeArgs);
|
91
|
+
break;
|
91
92
|
case 'configure_ai_service':
|
92
|
-
|
93
|
+
result = await this.codeRocketService.configureAIService(safeArgs);
|
94
|
+
break;
|
93
95
|
case 'get_ai_service_status':
|
94
|
-
|
96
|
+
result = await this.codeRocketService.getAIServiceStatus(safeArgs);
|
97
|
+
break;
|
95
98
|
default:
|
96
|
-
throw new Error(
|
99
|
+
throw new Error(`未知工具: ${name}`);
|
97
100
|
}
|
101
|
+
debugLog('✅ 工具调用成功', { toolName: name, resultType: typeof result });
|
102
|
+
return {
|
103
|
+
content: [
|
104
|
+
{
|
105
|
+
type: 'text',
|
106
|
+
text: JSON.stringify(result, null, 2),
|
107
|
+
},
|
108
|
+
],
|
109
|
+
};
|
98
110
|
}
|
99
111
|
catch (error) {
|
100
112
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
113
|
+
debugLog('❌ 工具调用失败', { toolName: name, error: errorMessage });
|
101
114
|
return {
|
102
115
|
content: [
|
103
116
|
{
|
@@ -121,23 +134,34 @@ class CodeRocketMCPServer {
|
|
121
134
|
}
|
122
135
|
async run() {
|
123
136
|
try {
|
137
|
+
debugLog('🚀 开始启动 CodeRocket MCP 服务器');
|
124
138
|
// 使用新的初始化函数初始化所有系统组件
|
139
|
+
debugLog('🔧 开始初始化系统组件');
|
125
140
|
await initializeCodeRocket();
|
141
|
+
debugLog('✅ 系统组件初始化完成');
|
126
142
|
// 现在可以安全地初始化 CodeRocketService
|
143
|
+
debugLog('🔧 开始初始化 CodeRocketService');
|
127
144
|
this.codeRocketService = new CodeRocketService();
|
145
|
+
debugLog('✅ CodeRocketService 初始化完成');
|
146
|
+
debugLog('🔧 开始连接 MCP 传输层');
|
128
147
|
const transport = new StdioServerTransport();
|
129
148
|
await this.server.connect(transport);
|
149
|
+
debugLog('✅ MCP 服务器启动成功,等待客户端连接');
|
130
150
|
}
|
131
151
|
catch (error) {
|
132
152
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
153
|
+
debugLog('❌ 服务器启动失败', { error: errorMessage, stack: error instanceof Error ? error.stack : undefined });
|
133
154
|
console.error('❌ CodeRocket MCP 服务器启动失败:', errorMessage);
|
134
155
|
process.exit(1);
|
135
156
|
}
|
136
157
|
}
|
137
158
|
}
|
138
159
|
// 启动服务器
|
160
|
+
debugLog('🌟 开始创建 CodeRocket MCP 服务器实例');
|
139
161
|
const server = new CodeRocketMCPServer();
|
162
|
+
debugLog('🌟 服务器实例创建完成,开始运行');
|
140
163
|
server.run().catch(error => {
|
164
|
+
debugLog('💥 服务器运行失败', { error: error.message, stack: error.stack });
|
141
165
|
console.error('Failed to start server:', error);
|
142
166
|
process.exit(1);
|
143
167
|
});
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"standardToolDefinitions.d.ts","sourceRoot":"","sources":["../src/standardToolDefinitions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAE1D,eAAO,MAAM,gBAAgB,EAAE,IAAI,EA2HlC,CAAC"}
|
@@ -0,0 +1,129 @@
|
|
1
|
+
/**
|
2
|
+
* 标准MCP工具定义
|
3
|
+
* 符合官方MCP协议规范
|
4
|
+
*/
|
5
|
+
export const CODEROCKET_TOOLS = [
|
6
|
+
{
|
7
|
+
name: 'review_code',
|
8
|
+
description: '对指定的代码片段进行AI驱动的代码审查,提供改进建议、潜在问题识别和最佳实践推荐',
|
9
|
+
inputSchema: {
|
10
|
+
type: 'object',
|
11
|
+
properties: {
|
12
|
+
code: {
|
13
|
+
type: 'string',
|
14
|
+
description: '要审查的代码内容'
|
15
|
+
},
|
16
|
+
language: {
|
17
|
+
type: 'string',
|
18
|
+
description: '代码语言(如:javascript, python, typescript等)',
|
19
|
+
default: 'auto'
|
20
|
+
},
|
21
|
+
focus: {
|
22
|
+
type: 'string',
|
23
|
+
description: '审查重点(如:performance, security, readability等)',
|
24
|
+
default: 'general'
|
25
|
+
}
|
26
|
+
},
|
27
|
+
required: ['code']
|
28
|
+
}
|
29
|
+
},
|
30
|
+
{
|
31
|
+
name: 'review_changes',
|
32
|
+
description: '审查Git工作区中的未提交更改,分析修改内容并提供改进建议',
|
33
|
+
inputSchema: {
|
34
|
+
type: 'object',
|
35
|
+
properties: {
|
36
|
+
staged_only: {
|
37
|
+
type: 'boolean',
|
38
|
+
description: '是否只审查已暂存的更改',
|
39
|
+
default: false
|
40
|
+
},
|
41
|
+
include_context: {
|
42
|
+
type: 'boolean',
|
43
|
+
description: '是否包含更改上下文',
|
44
|
+
default: true
|
45
|
+
}
|
46
|
+
},
|
47
|
+
required: []
|
48
|
+
}
|
49
|
+
},
|
50
|
+
{
|
51
|
+
name: 'review_commit',
|
52
|
+
description: '审查指定的Git提交,分析提交内容、消息质量和代码更改',
|
53
|
+
inputSchema: {
|
54
|
+
type: 'object',
|
55
|
+
properties: {
|
56
|
+
commit_hash: {
|
57
|
+
type: 'string',
|
58
|
+
description: 'Git提交哈希值(可选,默认为最新提交)'
|
59
|
+
},
|
60
|
+
include_diff: {
|
61
|
+
type: 'boolean',
|
62
|
+
description: '是否包含详细的差异信息',
|
63
|
+
default: true
|
64
|
+
}
|
65
|
+
},
|
66
|
+
required: []
|
67
|
+
}
|
68
|
+
},
|
69
|
+
{
|
70
|
+
name: 'review_files',
|
71
|
+
description: '审查指定的文件列表,提供代码质量分析和改进建议',
|
72
|
+
inputSchema: {
|
73
|
+
type: 'object',
|
74
|
+
properties: {
|
75
|
+
files: {
|
76
|
+
type: 'array',
|
77
|
+
items: {
|
78
|
+
type: 'string'
|
79
|
+
},
|
80
|
+
description: '要审查的文件路径列表'
|
81
|
+
},
|
82
|
+
recursive: {
|
83
|
+
type: 'boolean',
|
84
|
+
description: '如果指定目录,是否递归审查子目录',
|
85
|
+
default: false
|
86
|
+
}
|
87
|
+
},
|
88
|
+
required: ['files']
|
89
|
+
}
|
90
|
+
},
|
91
|
+
{
|
92
|
+
name: 'configure_ai_service',
|
93
|
+
description: '配置AI服务设置,包括服务提供商、模型选择和API密钥等',
|
94
|
+
inputSchema: {
|
95
|
+
type: 'object',
|
96
|
+
properties: {
|
97
|
+
service: {
|
98
|
+
type: 'string',
|
99
|
+
enum: ['gemini', 'claude'],
|
100
|
+
description: 'AI服务提供商'
|
101
|
+
},
|
102
|
+
api_key: {
|
103
|
+
type: 'string',
|
104
|
+
description: 'API密钥'
|
105
|
+
},
|
106
|
+
model: {
|
107
|
+
type: 'string',
|
108
|
+
description: '模型名称(可选)'
|
109
|
+
},
|
110
|
+
timeout: {
|
111
|
+
type: 'number',
|
112
|
+
description: '请求超时时间(秒)',
|
113
|
+
default: 30
|
114
|
+
}
|
115
|
+
},
|
116
|
+
required: ['service', 'api_key']
|
117
|
+
}
|
118
|
+
},
|
119
|
+
{
|
120
|
+
name: 'get_ai_service_status',
|
121
|
+
description: '获取当前AI服务的状态信息,包括配置详情和连接状态',
|
122
|
+
inputSchema: {
|
123
|
+
type: 'object',
|
124
|
+
properties: {},
|
125
|
+
required: []
|
126
|
+
}
|
127
|
+
}
|
128
|
+
];
|
129
|
+
//# sourceMappingURL=standardToolDefinitions.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"standardToolDefinitions.js","sourceRoot":"","sources":["../src/standardToolDefinitions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,CAAC,MAAM,gBAAgB,GAAW;IACtC;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,0CAA0C;QACvD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,UAAU;iBACxB;gBACD,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,yCAAyC;oBACtD,OAAO,EAAE,MAAM;iBAChB;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,6CAA6C;oBAC1D,OAAO,EAAE,SAAS;iBACnB;aACF;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;SACnB;KACF;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,+BAA+B;QAC5C,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE;oBACX,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,aAAa;oBAC1B,OAAO,EAAE,KAAK;iBACf;gBACD,eAAe,EAAE;oBACf,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,WAAW;oBACxB,OAAO,EAAE,IAAI;iBACd;aACF;YACD,QAAQ,EAAE,EAAE;SACb;KACF;IACD;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,6BAA6B;QAC1C,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,sBAAsB;iBACpC;gBACD,YAAY,EAAE;oBACZ,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,aAAa;oBAC1B,OAAO,EAAE,IAAI;iBACd;aACF;YACD,QAAQ,EAAE,EAAE;SACb;KACF;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,yBAAyB;QACtC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,KAAK,EAAE;oBACL,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;qBACf;oBACD,WAAW,EAAE,YAAY;iBAC1B;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,kBAAkB;oBAC/B,OAAO,EAAE,KAAK;iBACf;aACF;YACD,QAAQ,EAAE,CAAC,OAAO,CAAC;SACpB;KACF;IACD;QACE,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,8BAA8B;QAC3C,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;oBAC1B,WAAW,EAAE,SAAS;iBACvB;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,OAAO;iBACrB;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,UAAU;iBACxB;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,WAAW;oBACxB,OAAO,EAAE,EAAE;iBACZ;aACF;YACD,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;SACjC;KACF;IACD;QACE,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,2BAA2B;QACxC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,EAAE;SACb;KACF;CACF,CAAC"}
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
/**
|
4
|
+
* 修复MCP配置文件,添加coderocket-mcp工具的alwaysAllow列表
|
5
|
+
*/
|
6
|
+
|
7
|
+
import { readFileSync, writeFileSync } from 'fs';
|
8
|
+
import { resolve } from 'path';
|
9
|
+
|
10
|
+
const configPath = "/Users/dreambt/Library/Application Support/Code/User/globalStorage/rooveterinaryinc.roo-cline/settings/mcp_settings.json";
|
11
|
+
|
12
|
+
// coderocket-mcp提供的所有工具
|
13
|
+
const coderocketTools = [
|
14
|
+
"review_code",
|
15
|
+
"review_changes",
|
16
|
+
"review_commit",
|
17
|
+
"review_files",
|
18
|
+
"configure_ai_service",
|
19
|
+
"get_ai_service_status"
|
20
|
+
];
|
21
|
+
|
22
|
+
try {
|
23
|
+
console.log('🔧 正在修复MCP配置...');
|
24
|
+
|
25
|
+
// 读取现有配置
|
26
|
+
const configContent = readFileSync(configPath, 'utf-8');
|
27
|
+
const config = JSON.parse(configContent);
|
28
|
+
|
29
|
+
// 更新coderocket-mcp相关的配置
|
30
|
+
const serversToUpdate = ['coderocket-mcp', 'global-coderocket-mcp', 'test-coderocket-mcp'];
|
31
|
+
|
32
|
+
let updated = false;
|
33
|
+
|
34
|
+
for (const serverName of serversToUpdate) {
|
35
|
+
if (config.mcpServers[serverName]) {
|
36
|
+
console.log(`📝 更新 ${serverName} 配置...`);
|
37
|
+
config.mcpServers[serverName].alwaysAllow = coderocketTools;
|
38
|
+
updated = true;
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
if (updated) {
|
43
|
+
// 写回配置文件
|
44
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
45
|
+
console.log('✅ MCP配置修复完成!');
|
46
|
+
console.log('');
|
47
|
+
console.log('📋 已添加的工具:');
|
48
|
+
coderocketTools.forEach(tool => {
|
49
|
+
console.log(` - ${tool}`);
|
50
|
+
});
|
51
|
+
console.log('');
|
52
|
+
console.log('🔄 请重启RooCode以使配置生效');
|
53
|
+
} else {
|
54
|
+
console.log('⚠️ 未找到需要更新的coderocket-mcp配置');
|
55
|
+
}
|
56
|
+
|
57
|
+
} catch (error) {
|
58
|
+
console.error('❌ 修复配置失败:', error.message);
|
59
|
+
process.exit(1);
|
60
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
/**
|
4
|
+
* 修复RooCode MCP配置
|
5
|
+
* 禁用有问题的配置,只保留工作正常的配置
|
6
|
+
*/
|
7
|
+
|
8
|
+
import { readFileSync, writeFileSync } from 'fs';
|
9
|
+
|
10
|
+
const configPath = "/Users/dreambt/Library/Application Support/Code/User/globalStorage/rooveterinaryinc.roo-cline/settings/mcp_settings.json";
|
11
|
+
|
12
|
+
function fixConfig() {
|
13
|
+
try {
|
14
|
+
console.log('🔧 修复RooCode MCP配置...');
|
15
|
+
|
16
|
+
// 读取配置
|
17
|
+
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
18
|
+
|
19
|
+
// 禁用有问题的配置
|
20
|
+
if (config.mcpServers['coderocket-mcp']) {
|
21
|
+
config.mcpServers['coderocket-mcp'].disabled = true;
|
22
|
+
console.log('❌ 禁用 coderocket-mcp (npx版本启动超时)');
|
23
|
+
}
|
24
|
+
|
25
|
+
if (config.mcpServers['global-coderocket-mcp']) {
|
26
|
+
config.mcpServers['global-coderocket-mcp'].disabled = true;
|
27
|
+
console.log('❌ 禁用 global-coderocket-mcp (命令不存在)');
|
28
|
+
}
|
29
|
+
|
30
|
+
// 确保test-coderocket-mcp启用
|
31
|
+
if (config.mcpServers['test-coderocket-mcp']) {
|
32
|
+
config.mcpServers['test-coderocket-mcp'].disabled = false;
|
33
|
+
console.log('✅ 启用 test-coderocket-mcp (本地开发版本)');
|
34
|
+
}
|
35
|
+
|
36
|
+
// 写回配置
|
37
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
38
|
+
|
39
|
+
console.log('\n✅ 配置修复完成!');
|
40
|
+
console.log('\n📋 当前活跃配置:');
|
41
|
+
console.log(' - test-coderocket-mcp: 本地开发版本');
|
42
|
+
console.log(' 命令: node /Users/dreambt/sources/coderocket/coderocket-mcp/dist/index.js');
|
43
|
+
console.log(' 工具: 6个 (review_code, review_changes, review_commit, review_files, configure_ai_service, get_ai_service_status)');
|
44
|
+
|
45
|
+
console.log('\n🔄 请重启RooCode以使配置生效');
|
46
|
+
console.log('\n💡 如果问题仍然存在,请检查:');
|
47
|
+
console.log(' 1. RooCode是否正确加载MCP配置');
|
48
|
+
console.log(' 2. 是否有其他MCP服务器冲突');
|
49
|
+
console.log(' 3. RooCode的MCP功能是否启用');
|
50
|
+
|
51
|
+
} catch (error) {
|
52
|
+
console.error('❌ 修复配置失败:', error.message);
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
fixConfig();
|
package/package.json
CHANGED
@@ -0,0 +1,141 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
/**
|
4
|
+
* MCP服务器连接测试脚本
|
5
|
+
* 用于验证coderocket-mcp服务器是否正常响应
|
6
|
+
*/
|
7
|
+
|
8
|
+
import { spawn } from 'child_process';
|
9
|
+
import { resolve } from 'path';
|
10
|
+
|
11
|
+
const DEBUG = true;
|
12
|
+
|
13
|
+
function log(message, data) {
|
14
|
+
console.log(`[TEST] ${new Date().toISOString()} - ${message}`);
|
15
|
+
if (data) {
|
16
|
+
console.log(`[TEST] Data:`, JSON.stringify(data, null, 2));
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
function testMCPServer(command, args = []) {
|
21
|
+
return new Promise((resolve, reject) => {
|
22
|
+
log(`🚀 启动MCP服务器测试`, { command, args });
|
23
|
+
|
24
|
+
const server = spawn(command, args, {
|
25
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
26
|
+
env: {
|
27
|
+
...process.env,
|
28
|
+
DEBUG: 'true',
|
29
|
+
NODE_ENV: 'development'
|
30
|
+
}
|
31
|
+
});
|
32
|
+
|
33
|
+
let stdout = '';
|
34
|
+
let stderr = '';
|
35
|
+
let hasResponded = false;
|
36
|
+
|
37
|
+
// 设置超时
|
38
|
+
const timeout = setTimeout(() => {
|
39
|
+
if (!hasResponded) {
|
40
|
+
log('⏰ 服务器启动超时');
|
41
|
+
server.kill();
|
42
|
+
reject(new Error('服务器启动超时'));
|
43
|
+
}
|
44
|
+
}, 10000);
|
45
|
+
|
46
|
+
server.stdout.on('data', (data) => {
|
47
|
+
stdout += data.toString();
|
48
|
+
log('📤 服务器stdout输出', data.toString());
|
49
|
+
});
|
50
|
+
|
51
|
+
server.stderr.on('data', (data) => {
|
52
|
+
stderr += data.toString();
|
53
|
+
log('📤 服务器stderr输出', data.toString());
|
54
|
+
|
55
|
+
// 检查是否有调试日志表明服务器启动成功
|
56
|
+
if (data.toString().includes('MCP 服务器启动成功')) {
|
57
|
+
hasResponded = true;
|
58
|
+
clearTimeout(timeout);
|
59
|
+
|
60
|
+
// 发送工具列表请求
|
61
|
+
log('📋 发送工具列表请求');
|
62
|
+
const listToolsRequest = {
|
63
|
+
jsonrpc: '2.0',
|
64
|
+
id: 1,
|
65
|
+
method: 'tools/list',
|
66
|
+
params: {}
|
67
|
+
};
|
68
|
+
|
69
|
+
server.stdin.write(JSON.stringify(listToolsRequest) + '\n');
|
70
|
+
|
71
|
+
// 等待响应
|
72
|
+
setTimeout(() => {
|
73
|
+
server.kill();
|
74
|
+
resolve({ stdout, stderr });
|
75
|
+
}, 3000);
|
76
|
+
}
|
77
|
+
});
|
78
|
+
|
79
|
+
server.on('error', (error) => {
|
80
|
+
clearTimeout(timeout);
|
81
|
+
log('❌ 服务器启动错误', error.message);
|
82
|
+
reject(error);
|
83
|
+
});
|
84
|
+
|
85
|
+
server.on('exit', (code, signal) => {
|
86
|
+
clearTimeout(timeout);
|
87
|
+
log('🔚 服务器退出', { code, signal });
|
88
|
+
if (!hasResponded) {
|
89
|
+
reject(new Error(`服务器异常退出: code=${code}, signal=${signal}`));
|
90
|
+
}
|
91
|
+
});
|
92
|
+
});
|
93
|
+
}
|
94
|
+
|
95
|
+
async function runTests() {
|
96
|
+
console.log('🧪 开始MCP服务器连接测试\n');
|
97
|
+
|
98
|
+
const tests = [
|
99
|
+
{
|
100
|
+
name: 'test-coderocket-mcp (本地开发版)',
|
101
|
+
command: 'node',
|
102
|
+
args: [resolve(process.cwd(), 'dist/index.js')]
|
103
|
+
},
|
104
|
+
{
|
105
|
+
name: 'coderocket-mcp (npm全局版)',
|
106
|
+
command: 'coderocket-mcp',
|
107
|
+
args: []
|
108
|
+
},
|
109
|
+
{
|
110
|
+
name: 'coderocket-mcp (npx版)',
|
111
|
+
command: 'npx',
|
112
|
+
args: ['-y', '@yeepay/coderocket-mcp@1.4.1']
|
113
|
+
}
|
114
|
+
];
|
115
|
+
|
116
|
+
for (const test of tests) {
|
117
|
+
try {
|
118
|
+
console.log(`\n🔍 测试: ${test.name}`);
|
119
|
+
console.log(`📋 命令: ${test.command} ${test.args.join(' ')}`);
|
120
|
+
|
121
|
+
const result = await testMCPServer(test.command, test.args);
|
122
|
+
|
123
|
+
console.log(`✅ ${test.name} - 测试通过`);
|
124
|
+
console.log('📤 输出摘要:');
|
125
|
+
console.log(' stdout行数:', result.stdout.split('\n').length);
|
126
|
+
console.log(' stderr行数:', result.stderr.split('\n').length);
|
127
|
+
|
128
|
+
// 检查是否有工具列表响应
|
129
|
+
if (result.stdout.includes('tools') || result.stderr.includes('tools')) {
|
130
|
+
console.log(' 🎯 检测到工具列表响应');
|
131
|
+
}
|
132
|
+
|
133
|
+
} catch (error) {
|
134
|
+
console.log(`❌ ${test.name} - 测试失败: ${error.message}`);
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
console.log('\n🏁 测试完成');
|
139
|
+
}
|
140
|
+
|
141
|
+
runTests().catch(console.error);
|
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
/**
|
4
|
+
* 更新RooCode配置使用标准MCP实现v1.5.0
|
5
|
+
*/
|
6
|
+
|
7
|
+
import { readFileSync, writeFileSync } from 'fs';
|
8
|
+
|
9
|
+
const configPath = "/Users/dreambt/Library/Application Support/Code/User/globalStorage/rooveterinaryinc.roo-cline/settings/mcp_settings.json";
|
10
|
+
|
11
|
+
function updateConfig() {
|
12
|
+
try {
|
13
|
+
console.log('🔧 更新RooCode配置使用标准MCP实现v1.5.0...');
|
14
|
+
|
15
|
+
// 读取配置
|
16
|
+
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
17
|
+
|
18
|
+
// 更新test-coderocket-mcp配置
|
19
|
+
if (config.mcpServers['test-coderocket-mcp']) {
|
20
|
+
config.mcpServers['test-coderocket-mcp'] = {
|
21
|
+
command: 'node',
|
22
|
+
args: ['/Users/dreambt/sources/coderocket/coderocket-mcp/dist/index.js'],
|
23
|
+
disabled: false,
|
24
|
+
alwaysAllow: [
|
25
|
+
'review_code',
|
26
|
+
'review_changes',
|
27
|
+
'review_commit',
|
28
|
+
'review_files',
|
29
|
+
'configure_ai_service',
|
30
|
+
'get_ai_service_status'
|
31
|
+
]
|
32
|
+
};
|
33
|
+
console.log('✅ 更新 test-coderocket-mcp 配置 (标准MCP实现v1.5.0)');
|
34
|
+
}
|
35
|
+
|
36
|
+
// 确保其他配置仍然禁用
|
37
|
+
if (config.mcpServers['coderocket-mcp']) {
|
38
|
+
config.mcpServers['coderocket-mcp'].disabled = true;
|
39
|
+
console.log('❌ 保持 coderocket-mcp 禁用状态');
|
40
|
+
}
|
41
|
+
|
42
|
+
if (config.mcpServers['global-coderocket-mcp']) {
|
43
|
+
config.mcpServers['global-coderocket-mcp'].disabled = true;
|
44
|
+
console.log('❌ 保持 global-coderocket-mcp 禁用状态');
|
45
|
+
}
|
46
|
+
|
47
|
+
// 写回配置
|
48
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
49
|
+
|
50
|
+
console.log('\n✅ 配置更新完成!');
|
51
|
+
console.log('\n📋 标准MCP实现特性:');
|
52
|
+
console.log(' ✅ 符合官方MCP协议规范');
|
53
|
+
console.log(' ✅ 使用标准Tool类型定义');
|
54
|
+
console.log(' ✅ 直接使用JSON Schema而非Zod转换');
|
55
|
+
console.log(' ✅ 简化的错误处理机制');
|
56
|
+
console.log(' ✅ 完整的调试日志系统');
|
57
|
+
|
58
|
+
console.log('\n📊 工具列表:');
|
59
|
+
console.log(' 🔍 review_code - 代码片段审查');
|
60
|
+
console.log(' 🚀 review_changes - Git更改审查');
|
61
|
+
console.log(' 📝 review_commit - Git提交审查');
|
62
|
+
console.log(' 📁 review_files - 文件列表审查');
|
63
|
+
console.log(' ⚙️ configure_ai_service - AI服务配置');
|
64
|
+
console.log(' 📊 get_ai_service_status - AI服务状态');
|
65
|
+
|
66
|
+
console.log('\n🔄 请重启RooCode以使用标准MCP实现');
|
67
|
+
console.log('\n💡 如果工具现在可见,说明问题已解决!');
|
68
|
+
|
69
|
+
} catch (error) {
|
70
|
+
console.error('❌ 更新配置失败:', error.message);
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
updateConfig();
|
@@ -0,0 +1,145 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
/**
|
4
|
+
* RooCode MCP配置验证脚本
|
5
|
+
* 验证所有coderocket-mcp配置是否能正常启动
|
6
|
+
*/
|
7
|
+
|
8
|
+
import { spawn } from 'child_process';
|
9
|
+
import { readFileSync } from 'fs';
|
10
|
+
|
11
|
+
const configPath = "/Users/dreambt/Library/Application Support/Code/User/globalStorage/rooveterinaryinc.roo-cline/settings/mcp_settings.json";
|
12
|
+
|
13
|
+
function testCommand(name, command, args) {
|
14
|
+
return new Promise((resolve) => {
|
15
|
+
console.log(`\n🧪 测试配置: ${name}`);
|
16
|
+
console.log(`📋 命令: ${command} ${args.join(' ')}`);
|
17
|
+
|
18
|
+
const child = spawn(command, args, {
|
19
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
20
|
+
env: { ...process.env, DEBUG: 'true' }
|
21
|
+
});
|
22
|
+
|
23
|
+
let hasOutput = false;
|
24
|
+
let errorOutput = '';
|
25
|
+
|
26
|
+
const timeout = setTimeout(() => {
|
27
|
+
child.kill();
|
28
|
+
resolve({
|
29
|
+
name,
|
30
|
+
success: hasOutput,
|
31
|
+
error: hasOutput ? null : '启动超时'
|
32
|
+
});
|
33
|
+
}, 5000);
|
34
|
+
|
35
|
+
child.stderr.on('data', (data) => {
|
36
|
+
const output = data.toString();
|
37
|
+
errorOutput += output;
|
38
|
+
|
39
|
+
if (output.includes('MCP 服务器启动成功') || output.includes('✅ MCP Server')) {
|
40
|
+
hasOutput = true;
|
41
|
+
clearTimeout(timeout);
|
42
|
+
child.kill();
|
43
|
+
resolve({
|
44
|
+
name,
|
45
|
+
success: true,
|
46
|
+
error: null
|
47
|
+
});
|
48
|
+
}
|
49
|
+
});
|
50
|
+
|
51
|
+
child.on('error', (error) => {
|
52
|
+
clearTimeout(timeout);
|
53
|
+
resolve({
|
54
|
+
name,
|
55
|
+
success: false,
|
56
|
+
error: error.message
|
57
|
+
});
|
58
|
+
});
|
59
|
+
|
60
|
+
child.on('exit', (code) => {
|
61
|
+
clearTimeout(timeout);
|
62
|
+
if (!hasOutput) {
|
63
|
+
resolve({
|
64
|
+
name,
|
65
|
+
success: false,
|
66
|
+
error: `进程退出 (code: ${code})`
|
67
|
+
});
|
68
|
+
}
|
69
|
+
});
|
70
|
+
});
|
71
|
+
}
|
72
|
+
|
73
|
+
async function verifyConfig() {
|
74
|
+
console.log('🔍 验证RooCode MCP配置\n');
|
75
|
+
|
76
|
+
try {
|
77
|
+
// 读取配置文件
|
78
|
+
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
79
|
+
const coderocketConfigs = Object.entries(config.mcpServers)
|
80
|
+
.filter(([name]) => name.includes('coderocket'));
|
81
|
+
|
82
|
+
console.log(`📋 找到 ${coderocketConfigs.length} 个coderocket-mcp配置:`);
|
83
|
+
coderocketConfigs.forEach(([name, cfg]) => {
|
84
|
+
console.log(` - ${name}: ${cfg.command} ${cfg.args?.join(' ') || ''} (disabled: ${cfg.disabled})`);
|
85
|
+
});
|
86
|
+
|
87
|
+
// 测试每个配置
|
88
|
+
const results = [];
|
89
|
+
for (const [name, cfg] of coderocketConfigs) {
|
90
|
+
if (cfg.disabled) {
|
91
|
+
console.log(`\n⏭️ 跳过已禁用的配置: ${name}`);
|
92
|
+
continue;
|
93
|
+
}
|
94
|
+
|
95
|
+
const result = await testCommand(name, cfg.command, cfg.args || []);
|
96
|
+
results.push(result);
|
97
|
+
}
|
98
|
+
|
99
|
+
// 输出结果
|
100
|
+
console.log('\n📊 验证结果:');
|
101
|
+
results.forEach(result => {
|
102
|
+
if (result.success) {
|
103
|
+
console.log(`✅ ${result.name}: 正常`);
|
104
|
+
} else {
|
105
|
+
console.log(`❌ ${result.name}: ${result.error}`);
|
106
|
+
}
|
107
|
+
});
|
108
|
+
|
109
|
+
// 建议
|
110
|
+
console.log('\n💡 建议:');
|
111
|
+
const workingConfigs = results.filter(r => r.success);
|
112
|
+
const failedConfigs = results.filter(r => !r.success);
|
113
|
+
|
114
|
+
if (workingConfigs.length > 0) {
|
115
|
+
console.log(`✅ 有 ${workingConfigs.length} 个配置正常工作:`);
|
116
|
+
workingConfigs.forEach(r => console.log(` - ${r.name}`));
|
117
|
+
console.log('\n🔧 建议操作:');
|
118
|
+
console.log('1. 禁用失败的配置');
|
119
|
+
console.log('2. 只保留一个工作正常的配置');
|
120
|
+
console.log('3. 重启RooCode');
|
121
|
+
}
|
122
|
+
|
123
|
+
if (failedConfigs.length > 0) {
|
124
|
+
console.log(`\n❌ 有 ${failedConfigs.length} 个配置失败:`);
|
125
|
+
failedConfigs.forEach(r => console.log(` - ${r.name}: ${r.error}`));
|
126
|
+
}
|
127
|
+
|
128
|
+
// 生成修复脚本
|
129
|
+
if (failedConfigs.length > 0) {
|
130
|
+
console.log('\n🔧 生成配置修复建议...');
|
131
|
+
|
132
|
+
// 找到最佳配置
|
133
|
+
const bestConfig = workingConfigs[0];
|
134
|
+
if (bestConfig) {
|
135
|
+
console.log(`\n推荐使用配置: ${bestConfig.name}`);
|
136
|
+
console.log('可以禁用其他配置以避免冲突');
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
} catch (error) {
|
141
|
+
console.error('❌ 验证失败:', error.message);
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
verifyConfig().catch(console.error);
|