cc-reviewer 1.0.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/dist/cli/check.d.ts +20 -0
- package/dist/cli/check.js +75 -0
- package/dist/cli/codex.d.ts +11 -0
- package/dist/cli/codex.js +236 -0
- package/dist/cli/gemini.d.ts +12 -0
- package/dist/cli/gemini.js +229 -0
- package/dist/errors.d.ts +46 -0
- package/dist/errors.js +188 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +77 -0
- package/dist/prompt.d.ts +24 -0
- package/dist/prompt.js +134 -0
- package/dist/tools/feedback.d.ts +185 -0
- package/dist/tools/feedback.js +360 -0
- package/dist/types.d.ts +100 -0
- package/dist/types.js +26 -0
- package/package.json +43 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool Implementations for AI Reviewer
|
|
3
|
+
*/
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { runCodexReview } from '../cli/codex.js';
|
|
6
|
+
import { runGeminiReview } from '../cli/gemini.js';
|
|
7
|
+
import { isCliAvailable } from '../cli/check.js';
|
|
8
|
+
import { formatErrorForUser } from '../errors.js';
|
|
9
|
+
// Input schema for feedback tools
|
|
10
|
+
export const FeedbackInputSchema = z.object({
|
|
11
|
+
workingDir: z.string().describe('Working directory for the CLI to operate in'),
|
|
12
|
+
ccOutput: z.string().describe("Claude Code's output to review (findings, plan, analysis)"),
|
|
13
|
+
outputType: z.enum(['plan', 'findings', 'analysis', 'proposal']).describe('Type of output being reviewed'),
|
|
14
|
+
analyzedFiles: z.array(z.string()).optional().describe('File paths that CC analyzed'),
|
|
15
|
+
focusAreas: z.array(z.enum([
|
|
16
|
+
'security', 'performance', 'architecture', 'correctness',
|
|
17
|
+
'maintainability', 'scalability', 'testing', 'documentation'
|
|
18
|
+
])).optional().describe('Areas to focus the review on'),
|
|
19
|
+
customPrompt: z.string().optional().describe('Custom instructions for the reviewer')
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* Convert tool input to FeedbackRequest
|
|
23
|
+
*/
|
|
24
|
+
function toFeedbackRequest(input) {
|
|
25
|
+
return {
|
|
26
|
+
workingDir: input.workingDir,
|
|
27
|
+
ccOutput: input.ccOutput,
|
|
28
|
+
outputType: input.outputType,
|
|
29
|
+
analyzedFiles: input.analyzedFiles,
|
|
30
|
+
focusAreas: input.focusAreas,
|
|
31
|
+
customPrompt: input.customPrompt
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Format successful feedback for display
|
|
36
|
+
*/
|
|
37
|
+
function formatSuccessResponse(result) {
|
|
38
|
+
if (!result.success) {
|
|
39
|
+
return formatErrorResponse(result);
|
|
40
|
+
}
|
|
41
|
+
return `## ${result.model.charAt(0).toUpperCase() + result.model.slice(1)} Review
|
|
42
|
+
|
|
43
|
+
${result.feedback}`;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Format error response for display
|
|
47
|
+
*/
|
|
48
|
+
function formatErrorResponse(result) {
|
|
49
|
+
if (result.success) {
|
|
50
|
+
return result.feedback;
|
|
51
|
+
}
|
|
52
|
+
let response = formatErrorForUser(result.error);
|
|
53
|
+
if (result.suggestion) {
|
|
54
|
+
response += `\n\nš” Suggestion: ${result.suggestion}`;
|
|
55
|
+
}
|
|
56
|
+
return response;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Codex feedback tool handler
|
|
60
|
+
*/
|
|
61
|
+
export async function handleCodexFeedback(input) {
|
|
62
|
+
// Check if Codex CLI is available
|
|
63
|
+
const available = await isCliAvailable('codex');
|
|
64
|
+
if (!available) {
|
|
65
|
+
return {
|
|
66
|
+
content: [{
|
|
67
|
+
type: 'text',
|
|
68
|
+
text: 'ā Codex CLI not found.\n\nInstall with: npm install -g @openai/codex\n\nAlternative: Use gemini_feedback instead'
|
|
69
|
+
}]
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const request = toFeedbackRequest(input);
|
|
73
|
+
const result = await runCodexReview(request);
|
|
74
|
+
return {
|
|
75
|
+
content: [{
|
|
76
|
+
type: 'text',
|
|
77
|
+
text: formatSuccessResponse(result)
|
|
78
|
+
}]
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Gemini feedback tool handler
|
|
83
|
+
*/
|
|
84
|
+
export async function handleGeminiFeedback(input) {
|
|
85
|
+
// Check if Gemini CLI is available
|
|
86
|
+
const available = await isCliAvailable('gemini');
|
|
87
|
+
if (!available) {
|
|
88
|
+
return {
|
|
89
|
+
content: [{
|
|
90
|
+
type: 'text',
|
|
91
|
+
text: 'ā Gemini CLI not found.\n\nInstall with: npm install -g @google/generative-ai-cli\n\nAlternative: Use codex_feedback instead'
|
|
92
|
+
}]
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const request = toFeedbackRequest(input);
|
|
96
|
+
const result = await runGeminiReview(request);
|
|
97
|
+
return {
|
|
98
|
+
content: [{
|
|
99
|
+
type: 'text',
|
|
100
|
+
text: formatSuccessResponse(result)
|
|
101
|
+
}]
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Multi-model feedback tool handler (parallel execution)
|
|
106
|
+
*/
|
|
107
|
+
export async function handleMultiFeedback(input) {
|
|
108
|
+
const request = toFeedbackRequest(input);
|
|
109
|
+
// Check availability of both CLIs
|
|
110
|
+
const [codexAvailable, geminiAvailable] = await Promise.all([
|
|
111
|
+
isCliAvailable('codex'),
|
|
112
|
+
isCliAvailable('gemini')
|
|
113
|
+
]);
|
|
114
|
+
if (!codexAvailable && !geminiAvailable) {
|
|
115
|
+
return {
|
|
116
|
+
content: [{
|
|
117
|
+
type: 'text',
|
|
118
|
+
text: `ā No AI CLIs found.
|
|
119
|
+
|
|
120
|
+
Install at least one:
|
|
121
|
+
- Codex: npm install -g @openai/codex
|
|
122
|
+
- Gemini: npm install -g @google/generative-ai-cli`
|
|
123
|
+
}]
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
// Run available CLIs in parallel
|
|
127
|
+
const promises = [];
|
|
128
|
+
const cliNames = [];
|
|
129
|
+
if (codexAvailable) {
|
|
130
|
+
promises.push(runCodexReview(request));
|
|
131
|
+
cliNames.push('codex');
|
|
132
|
+
}
|
|
133
|
+
if (geminiAvailable) {
|
|
134
|
+
promises.push(runGeminiReview(request));
|
|
135
|
+
cliNames.push('gemini');
|
|
136
|
+
}
|
|
137
|
+
const results = await Promise.allSettled(promises);
|
|
138
|
+
// Process results
|
|
139
|
+
const multiResult = {
|
|
140
|
+
successful: [],
|
|
141
|
+
failed: [],
|
|
142
|
+
partialSuccess: false,
|
|
143
|
+
allFailed: false
|
|
144
|
+
};
|
|
145
|
+
results.forEach((result, index) => {
|
|
146
|
+
if (result.status === 'fulfilled') {
|
|
147
|
+
const feedbackResult = result.value;
|
|
148
|
+
if (feedbackResult.success) {
|
|
149
|
+
multiResult.successful.push({
|
|
150
|
+
model: feedbackResult.model,
|
|
151
|
+
feedback: feedbackResult.feedback
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
multiResult.failed.push({
|
|
156
|
+
model: feedbackResult.model,
|
|
157
|
+
error: feedbackResult.error
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
// Promise rejected (unexpected)
|
|
163
|
+
multiResult.failed.push({
|
|
164
|
+
model: cliNames[index],
|
|
165
|
+
error: {
|
|
166
|
+
type: 'cli_error',
|
|
167
|
+
cli: cliNames[index],
|
|
168
|
+
exitCode: -1,
|
|
169
|
+
stderr: result.reason?.message || 'Unknown error'
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
multiResult.partialSuccess = multiResult.successful.length > 0 && multiResult.failed.length > 0;
|
|
175
|
+
multiResult.allFailed = multiResult.successful.length === 0;
|
|
176
|
+
// Format response
|
|
177
|
+
return {
|
|
178
|
+
content: [{
|
|
179
|
+
type: 'text',
|
|
180
|
+
text: formatMultiResponse(multiResult, codexAvailable, geminiAvailable)
|
|
181
|
+
}]
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Format multi-model response
|
|
186
|
+
*/
|
|
187
|
+
function formatMultiResponse(result, codexAvailable, geminiAvailable) {
|
|
188
|
+
const parts = [];
|
|
189
|
+
// Header with status
|
|
190
|
+
if (result.allFailed) {
|
|
191
|
+
parts.push('## Multi-Model Review - All Failed ā\n');
|
|
192
|
+
}
|
|
193
|
+
else if (result.partialSuccess) {
|
|
194
|
+
parts.push('## Multi-Model Review - Partial Success ā ļø\n');
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
parts.push('## Multi-Model Review ā\n');
|
|
198
|
+
}
|
|
199
|
+
// Show availability status
|
|
200
|
+
const statusLines = [];
|
|
201
|
+
if (!codexAvailable)
|
|
202
|
+
statusLines.push('- Codex: Not available');
|
|
203
|
+
if (!geminiAvailable)
|
|
204
|
+
statusLines.push('- Gemini: Not available');
|
|
205
|
+
if (statusLines.length > 0) {
|
|
206
|
+
parts.push('**CLI Status:**');
|
|
207
|
+
parts.push(statusLines.join('\n'));
|
|
208
|
+
parts.push('');
|
|
209
|
+
}
|
|
210
|
+
// Successful reviews
|
|
211
|
+
if (result.successful.length > 0) {
|
|
212
|
+
for (const success of result.successful) {
|
|
213
|
+
parts.push(`### ${success.model.charAt(0).toUpperCase() + success.model.slice(1)} Review\n`);
|
|
214
|
+
parts.push(success.feedback);
|
|
215
|
+
parts.push('');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Failed reviews
|
|
219
|
+
if (result.failed.length > 0) {
|
|
220
|
+
parts.push('### Failures\n');
|
|
221
|
+
for (const failure of result.failed) {
|
|
222
|
+
parts.push(`**${failure.model}:** ${formatErrorForUser(failure.error)}\n`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// Synthesis instruction (only if we have successful results)
|
|
226
|
+
if (result.successful.length > 1) {
|
|
227
|
+
parts.push(`---
|
|
228
|
+
|
|
229
|
+
**Note:** Both models provided feedback above. Please synthesize their perspectives:
|
|
230
|
+
- Mark agreements with āā
|
|
231
|
+
- Resolve conflicts with your recommendation
|
|
232
|
+
- Highlight unique insights from each model`);
|
|
233
|
+
}
|
|
234
|
+
return parts.join('\n');
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Tool definitions for MCP registration
|
|
238
|
+
*/
|
|
239
|
+
export const TOOL_DEFINITIONS = {
|
|
240
|
+
codex_feedback: {
|
|
241
|
+
name: 'codex_feedback',
|
|
242
|
+
description: "Get Codex's review of Claude Code's work. Codex focuses on correctness, edge cases, and performance.",
|
|
243
|
+
inputSchema: {
|
|
244
|
+
type: 'object',
|
|
245
|
+
properties: {
|
|
246
|
+
workingDir: {
|
|
247
|
+
type: 'string',
|
|
248
|
+
description: 'Working directory for the CLI to operate in'
|
|
249
|
+
},
|
|
250
|
+
ccOutput: {
|
|
251
|
+
type: 'string',
|
|
252
|
+
description: "Claude Code's output to review (findings, plan, analysis)"
|
|
253
|
+
},
|
|
254
|
+
outputType: {
|
|
255
|
+
type: 'string',
|
|
256
|
+
enum: ['plan', 'findings', 'analysis', 'proposal'],
|
|
257
|
+
description: 'Type of output being reviewed'
|
|
258
|
+
},
|
|
259
|
+
analyzedFiles: {
|
|
260
|
+
type: 'array',
|
|
261
|
+
items: { type: 'string' },
|
|
262
|
+
description: 'File paths that CC analyzed'
|
|
263
|
+
},
|
|
264
|
+
focusAreas: {
|
|
265
|
+
type: 'array',
|
|
266
|
+
items: {
|
|
267
|
+
type: 'string',
|
|
268
|
+
enum: ['security', 'performance', 'architecture', 'correctness', 'maintainability', 'scalability', 'testing', 'documentation']
|
|
269
|
+
},
|
|
270
|
+
description: 'Areas to focus the review on'
|
|
271
|
+
},
|
|
272
|
+
customPrompt: {
|
|
273
|
+
type: 'string',
|
|
274
|
+
description: 'Custom instructions for the reviewer'
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
required: ['workingDir', 'ccOutput', 'outputType']
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
gemini_feedback: {
|
|
281
|
+
name: 'gemini_feedback',
|
|
282
|
+
description: "Get Gemini's review of Claude Code's work. Gemini focuses on design patterns, scalability, and tech debt.",
|
|
283
|
+
inputSchema: {
|
|
284
|
+
type: 'object',
|
|
285
|
+
properties: {
|
|
286
|
+
workingDir: {
|
|
287
|
+
type: 'string',
|
|
288
|
+
description: 'Working directory for the CLI to operate in'
|
|
289
|
+
},
|
|
290
|
+
ccOutput: {
|
|
291
|
+
type: 'string',
|
|
292
|
+
description: "Claude Code's output to review (findings, plan, analysis)"
|
|
293
|
+
},
|
|
294
|
+
outputType: {
|
|
295
|
+
type: 'string',
|
|
296
|
+
enum: ['plan', 'findings', 'analysis', 'proposal'],
|
|
297
|
+
description: 'Type of output being reviewed'
|
|
298
|
+
},
|
|
299
|
+
analyzedFiles: {
|
|
300
|
+
type: 'array',
|
|
301
|
+
items: { type: 'string' },
|
|
302
|
+
description: 'File paths that CC analyzed'
|
|
303
|
+
},
|
|
304
|
+
focusAreas: {
|
|
305
|
+
type: 'array',
|
|
306
|
+
items: {
|
|
307
|
+
type: 'string',
|
|
308
|
+
enum: ['security', 'performance', 'architecture', 'correctness', 'maintainability', 'scalability', 'testing', 'documentation']
|
|
309
|
+
},
|
|
310
|
+
description: 'Areas to focus the review on'
|
|
311
|
+
},
|
|
312
|
+
customPrompt: {
|
|
313
|
+
type: 'string',
|
|
314
|
+
description: 'Custom instructions for the reviewer'
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
required: ['workingDir', 'ccOutput', 'outputType']
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
multi_feedback: {
|
|
321
|
+
name: 'multi_feedback',
|
|
322
|
+
description: "Get parallel reviews from all available AI CLIs (Codex and Gemini). Returns combined feedback for synthesis.",
|
|
323
|
+
inputSchema: {
|
|
324
|
+
type: 'object',
|
|
325
|
+
properties: {
|
|
326
|
+
workingDir: {
|
|
327
|
+
type: 'string',
|
|
328
|
+
description: 'Working directory for the CLI to operate in'
|
|
329
|
+
},
|
|
330
|
+
ccOutput: {
|
|
331
|
+
type: 'string',
|
|
332
|
+
description: "Claude Code's output to review (findings, plan, analysis)"
|
|
333
|
+
},
|
|
334
|
+
outputType: {
|
|
335
|
+
type: 'string',
|
|
336
|
+
enum: ['plan', 'findings', 'analysis', 'proposal'],
|
|
337
|
+
description: 'Type of output being reviewed'
|
|
338
|
+
},
|
|
339
|
+
analyzedFiles: {
|
|
340
|
+
type: 'array',
|
|
341
|
+
items: { type: 'string' },
|
|
342
|
+
description: 'File paths that CC analyzed'
|
|
343
|
+
},
|
|
344
|
+
focusAreas: {
|
|
345
|
+
type: 'array',
|
|
346
|
+
items: {
|
|
347
|
+
type: 'string',
|
|
348
|
+
enum: ['security', 'performance', 'architecture', 'correctness', 'maintainability', 'scalability', 'testing', 'documentation']
|
|
349
|
+
},
|
|
350
|
+
description: 'Areas to focus the review on'
|
|
351
|
+
},
|
|
352
|
+
customPrompt: {
|
|
353
|
+
type: 'string',
|
|
354
|
+
description: 'Custom instructions for the reviewer'
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
required: ['workingDir', 'ccOutput', 'outputType']
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for AI Reviewer MCP Server
|
|
3
|
+
*/
|
|
4
|
+
export type OutputType = 'plan' | 'findings' | 'analysis' | 'proposal';
|
|
5
|
+
export type FocusArea = 'security' | 'performance' | 'architecture' | 'correctness' | 'maintainability' | 'scalability' | 'testing' | 'documentation';
|
|
6
|
+
export type CliType = 'codex' | 'gemini';
|
|
7
|
+
export interface FeedbackRequest {
|
|
8
|
+
workingDir: string;
|
|
9
|
+
ccOutput: string;
|
|
10
|
+
outputType: OutputType;
|
|
11
|
+
analyzedFiles?: string[];
|
|
12
|
+
focusAreas?: FocusArea[];
|
|
13
|
+
customPrompt?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface FeedbackSuccess {
|
|
16
|
+
success: true;
|
|
17
|
+
feedback: string;
|
|
18
|
+
model: CliType;
|
|
19
|
+
}
|
|
20
|
+
export interface FeedbackFailure {
|
|
21
|
+
success: false;
|
|
22
|
+
error: FeedbackError;
|
|
23
|
+
suggestion?: string;
|
|
24
|
+
model: CliType;
|
|
25
|
+
}
|
|
26
|
+
export type FeedbackResult = FeedbackSuccess | FeedbackFailure;
|
|
27
|
+
export type FeedbackError = {
|
|
28
|
+
type: 'cli_not_found';
|
|
29
|
+
cli: CliType;
|
|
30
|
+
installCmd: string;
|
|
31
|
+
} | {
|
|
32
|
+
type: 'timeout';
|
|
33
|
+
cli: CliType;
|
|
34
|
+
durationMs: number;
|
|
35
|
+
} | {
|
|
36
|
+
type: 'rate_limit';
|
|
37
|
+
cli: CliType;
|
|
38
|
+
retryAfterMs?: number;
|
|
39
|
+
} | {
|
|
40
|
+
type: 'auth_error';
|
|
41
|
+
cli: CliType;
|
|
42
|
+
message: string;
|
|
43
|
+
} | {
|
|
44
|
+
type: 'invalid_response';
|
|
45
|
+
cli: CliType;
|
|
46
|
+
rawOutput: string;
|
|
47
|
+
} | {
|
|
48
|
+
type: 'cli_error';
|
|
49
|
+
cli: CliType;
|
|
50
|
+
exitCode: number;
|
|
51
|
+
stderr: string;
|
|
52
|
+
};
|
|
53
|
+
export interface MultiFeedbackResult {
|
|
54
|
+
successful: Array<{
|
|
55
|
+
model: CliType;
|
|
56
|
+
feedback: string;
|
|
57
|
+
}>;
|
|
58
|
+
failed: Array<{
|
|
59
|
+
model: CliType;
|
|
60
|
+
error: FeedbackError;
|
|
61
|
+
}>;
|
|
62
|
+
partialSuccess: boolean;
|
|
63
|
+
allFailed: boolean;
|
|
64
|
+
}
|
|
65
|
+
export interface CliStatus {
|
|
66
|
+
codex: boolean;
|
|
67
|
+
gemini: boolean;
|
|
68
|
+
}
|
|
69
|
+
export interface StructuredFeedback {
|
|
70
|
+
agreements: Array<{
|
|
71
|
+
finding: string;
|
|
72
|
+
reason: string;
|
|
73
|
+
}>;
|
|
74
|
+
disagreements: Array<{
|
|
75
|
+
finding: string;
|
|
76
|
+
reason: string;
|
|
77
|
+
correction: string;
|
|
78
|
+
}>;
|
|
79
|
+
additions: Array<{
|
|
80
|
+
finding: string;
|
|
81
|
+
location: string;
|
|
82
|
+
impact: string;
|
|
83
|
+
}>;
|
|
84
|
+
alternatives: Array<{
|
|
85
|
+
topic: string;
|
|
86
|
+
alternative: string;
|
|
87
|
+
tradeoffs: string;
|
|
88
|
+
}>;
|
|
89
|
+
riskAssessment: {
|
|
90
|
+
level: 'Low' | 'Medium' | 'High';
|
|
91
|
+
reason: string;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export interface ReviewerPersona {
|
|
95
|
+
name: string;
|
|
96
|
+
focus: string;
|
|
97
|
+
style: string;
|
|
98
|
+
}
|
|
99
|
+
export declare const REVIEWER_PERSONAS: Record<CliType, ReviewerPersona>;
|
|
100
|
+
export declare const FOCUS_AREA_DESCRIPTIONS: Record<FocusArea, string>;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for AI Reviewer MCP Server
|
|
3
|
+
*/
|
|
4
|
+
export const REVIEWER_PERSONAS = {
|
|
5
|
+
codex: {
|
|
6
|
+
name: 'Codex',
|
|
7
|
+
focus: 'correctness, edge cases, performance',
|
|
8
|
+
style: 'Apply pragmatic skepticism - verify before agreeing.'
|
|
9
|
+
},
|
|
10
|
+
gemini: {
|
|
11
|
+
name: 'Gemini',
|
|
12
|
+
focus: 'design patterns, scalability, tech debt',
|
|
13
|
+
style: 'Think holistically - consider broader context.'
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
// Focus area descriptions
|
|
17
|
+
export const FOCUS_AREA_DESCRIPTIONS = {
|
|
18
|
+
security: 'Vulnerabilities, auth, input validation',
|
|
19
|
+
performance: 'Speed, memory, efficiency',
|
|
20
|
+
architecture: 'Design patterns, structure, coupling',
|
|
21
|
+
correctness: 'Logic errors, edge cases, bugs',
|
|
22
|
+
maintainability: 'Code clarity, documentation, complexity',
|
|
23
|
+
scalability: 'Load handling, bottlenecks',
|
|
24
|
+
testing: 'Test coverage, test quality',
|
|
25
|
+
documentation: 'Comments, docs, API docs'
|
|
26
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cc-reviewer",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for Claude Code - Get second-opinion feedback from Codex/Gemini CLIs",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"cc-reviewer": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/**/*"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"start": "node dist/index.js",
|
|
16
|
+
"dev": "tsc --watch",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"claude",
|
|
22
|
+
"claude-code",
|
|
23
|
+
"codex",
|
|
24
|
+
"gemini",
|
|
25
|
+
"ai-review",
|
|
26
|
+
"code-review"
|
|
27
|
+
],
|
|
28
|
+
"author": "SimonRen",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/SimonRen/cc-reviewer.git"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/SimonRen/cc-reviewer#readme",
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
37
|
+
"zod": "^3.22.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^20.0.0",
|
|
41
|
+
"typescript": "^5.0.0"
|
|
42
|
+
}
|
|
43
|
+
}
|