cc-reviewer 2.0.0 → 3.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.
@@ -1,194 +0,0 @@
1
- /**
2
- * MCP Peer Tool Implementations
3
- *
4
- * General-purpose coworker tools:
5
- * 1. ask_codex - Ask Codex for help
6
- * 2. ask_gemini - Ask Gemini for help
7
- * 3. ask_multi - Ask both in parallel
8
- */
9
- import { PeerResult } from '../adapters/index.js';
10
- export type PeerInput = {
11
- workingDir: string;
12
- prompt: string;
13
- taskType?: string;
14
- relevantFiles?: string[];
15
- context?: string;
16
- focusAreas?: string[];
17
- customPrompt?: string;
18
- reasoningEffort?: 'high' | 'xhigh';
19
- serviceTier?: 'default' | 'fast' | 'flex';
20
- };
21
- export declare function formatPeerResponse(result: PeerResult, modelName: string): string;
22
- export declare function handleAskCodex(input: PeerInput): Promise<{
23
- content: Array<{
24
- type: 'text';
25
- text: string;
26
- }>;
27
- }>;
28
- export declare function handleAskGemini(input: PeerInput): Promise<{
29
- content: Array<{
30
- type: 'text';
31
- text: string;
32
- }>;
33
- }>;
34
- export declare function handleAskMulti(input: PeerInput): Promise<{
35
- content: Array<{
36
- type: 'text';
37
- text: string;
38
- }>;
39
- }>;
40
- export declare const PEER_TOOL_DEFINITIONS: {
41
- ask_codex: {
42
- name: string;
43
- description: string;
44
- inputSchema: {
45
- type: string;
46
- properties: {
47
- workingDir: {
48
- type: string;
49
- description: string;
50
- };
51
- prompt: {
52
- type: string;
53
- description: string;
54
- };
55
- taskType: {
56
- type: string;
57
- enum: string[];
58
- description: string;
59
- };
60
- relevantFiles: {
61
- type: string;
62
- items: {
63
- type: string;
64
- };
65
- description: string;
66
- };
67
- context: {
68
- type: string;
69
- description: string;
70
- };
71
- focusAreas: {
72
- type: string;
73
- items: {
74
- type: string;
75
- enum: string[];
76
- };
77
- description: string;
78
- };
79
- customPrompt: {
80
- type: string;
81
- description: string;
82
- };
83
- reasoningEffort: {
84
- type: string;
85
- enum: string[];
86
- description: string;
87
- };
88
- serviceTier: {
89
- type: string;
90
- enum: string[];
91
- description: string;
92
- };
93
- };
94
- required: string[];
95
- };
96
- };
97
- ask_gemini: {
98
- name: string;
99
- description: string;
100
- inputSchema: {
101
- type: string;
102
- properties: {
103
- workingDir: {
104
- type: string;
105
- description: string;
106
- };
107
- prompt: {
108
- type: string;
109
- description: string;
110
- };
111
- taskType: {
112
- type: string;
113
- enum: string[];
114
- description: string;
115
- };
116
- relevantFiles: {
117
- type: string;
118
- items: {
119
- type: string;
120
- };
121
- description: string;
122
- };
123
- context: {
124
- type: string;
125
- description: string;
126
- };
127
- focusAreas: {
128
- type: string;
129
- items: {
130
- type: string;
131
- enum: string[];
132
- };
133
- description: string;
134
- };
135
- customPrompt: {
136
- type: string;
137
- description: string;
138
- };
139
- };
140
- required: string[];
141
- };
142
- };
143
- ask_multi: {
144
- name: string;
145
- description: string;
146
- inputSchema: {
147
- type: string;
148
- properties: {
149
- workingDir: {
150
- type: string;
151
- description: string;
152
- };
153
- prompt: {
154
- type: string;
155
- description: string;
156
- };
157
- taskType: {
158
- type: string;
159
- enum: string[];
160
- description: string;
161
- };
162
- relevantFiles: {
163
- type: string;
164
- items: {
165
- type: string;
166
- };
167
- description: string;
168
- };
169
- context: {
170
- type: string;
171
- description: string;
172
- };
173
- focusAreas: {
174
- type: string;
175
- items: {
176
- type: string;
177
- enum: string[];
178
- };
179
- description: string;
180
- };
181
- customPrompt: {
182
- type: string;
183
- description: string;
184
- };
185
- serviceTier: {
186
- type: string;
187
- enum: string[];
188
- description: string;
189
- };
190
- };
191
- required: string[];
192
- };
193
- };
194
- };
@@ -1,347 +0,0 @@
1
- /**
2
- * MCP Peer Tool Implementations
3
- *
4
- * General-purpose coworker tools:
5
- * 1. ask_codex - Ask Codex for help
6
- * 2. ask_gemini - Ask Gemini for help
7
- * 3. ask_multi - Ask both in parallel
8
- */
9
- import { getAdapter, getAvailableAdapters, } from '../adapters/index.js';
10
- // =============================================================================
11
- // HELPER FUNCTIONS
12
- // =============================================================================
13
- function toPeerRequest(input) {
14
- return {
15
- workingDir: input.workingDir,
16
- prompt: input.prompt,
17
- taskType: input.taskType,
18
- relevantFiles: input.relevantFiles,
19
- context: input.context,
20
- focusAreas: input.focusAreas,
21
- customPrompt: input.customPrompt,
22
- reasoningEffort: input.reasoningEffort,
23
- serviceTier: input.serviceTier,
24
- };
25
- }
26
- export function formatPeerResponse(result, modelName) {
27
- if (!result.success) {
28
- return formatPeerErrorResponse(result.error, result.suggestion);
29
- }
30
- const output = result.output;
31
- const lines = [];
32
- lines.push(`## ${modelName} Response\n`);
33
- lines.push(`**Execution Time:** ${(result.executionTimeMs / 1000).toFixed(1)}s`);
34
- lines.push(`**Confidence:** ${Math.round(output.confidence * 100)}%\n`);
35
- // Main answer
36
- lines.push(`### Answer\n`);
37
- lines.push(output.answer);
38
- lines.push('');
39
- // Key points
40
- if (output.key_points.length > 0) {
41
- lines.push(`### Key Points\n`);
42
- for (const point of output.key_points) {
43
- lines.push(`- ${point}`);
44
- }
45
- lines.push('');
46
- }
47
- // Suggested actions
48
- if (output.suggested_actions.length > 0) {
49
- lines.push(`### Suggested Actions\n`);
50
- const priorityEmoji = {
51
- high: '🔴', medium: '🟡', low: '🟢',
52
- };
53
- for (const action of output.suggested_actions) {
54
- lines.push(`${priorityEmoji[action.priority] || '•'} **${action.action}**`);
55
- if (action.file) {
56
- lines.push(` 📍 ${action.file}`);
57
- }
58
- lines.push(` ${action.rationale}`);
59
- lines.push('');
60
- }
61
- }
62
- // File references
63
- if (output.file_references.length > 0) {
64
- lines.push(`### Files Examined\n`);
65
- for (const ref of output.file_references) {
66
- const loc = ref.lines ? `${ref.path}:${ref.lines}` : ref.path;
67
- lines.push(`- \`${loc}\` — ${ref.relevance}`);
68
- }
69
- lines.push('');
70
- }
71
- // Alternatives
72
- if (output.alternatives && output.alternatives.length > 0) {
73
- lines.push(`### Alternatives\n`);
74
- for (const alt of output.alternatives) {
75
- lines.push(`**${alt.topic}**`);
76
- lines.push(` Current: ${alt.current_approach}`);
77
- lines.push(` Alternative: ${alt.alternative}`);
78
- lines.push(` Recommendation: ${alt.recommendation}`);
79
- lines.push('');
80
- }
81
- }
82
- return lines.join('\n');
83
- }
84
- function formatPeerErrorResponse(error, suggestion) {
85
- const emoji = {
86
- cli_not_found: '❌',
87
- timeout: '⏱️',
88
- rate_limit: '🚫',
89
- auth_error: '🔐',
90
- parse_error: '⚠️',
91
- cli_error: '❌',
92
- };
93
- let response = `${emoji[error.type] || '❌'} **${error.type}**: ${error.message}`;
94
- if (suggestion) {
95
- response += `\n\n💡 ${suggestion}`;
96
- }
97
- return response;
98
- }
99
- // =============================================================================
100
- // SINGLE MODEL HANDLERS
101
- // =============================================================================
102
- export async function handleAskCodex(input) {
103
- const adapter = getAdapter('codex');
104
- if (!adapter) {
105
- return { content: [{ type: 'text', text: '❌ Codex adapter not registered' }] };
106
- }
107
- const available = await adapter.isAvailable();
108
- if (!available) {
109
- return {
110
- content: [{
111
- type: 'text',
112
- text: '❌ Codex CLI not found.\n\nInstall with: npm install -g @openai/codex\n\nAlternative: Use ask_gemini instead'
113
- }]
114
- };
115
- }
116
- const request = toPeerRequest(input);
117
- const result = await adapter.runPeerRequest(request);
118
- return { content: [{ type: 'text', text: formatPeerResponse(result, 'Codex') }] };
119
- }
120
- export async function handleAskGemini(input) {
121
- const adapter = getAdapter('gemini');
122
- if (!adapter) {
123
- return { content: [{ type: 'text', text: '❌ Gemini adapter not registered' }] };
124
- }
125
- const available = await adapter.isAvailable();
126
- if (!available) {
127
- return {
128
- content: [{
129
- type: 'text',
130
- text: '❌ Gemini CLI not found.\n\nInstall with: npm install -g @google/gemini-cli\n\nAlternative: Use ask_codex instead'
131
- }]
132
- };
133
- }
134
- const request = toPeerRequest(input);
135
- const result = await adapter.runPeerRequest(request);
136
- return { content: [{ type: 'text', text: formatPeerResponse(result, 'Gemini') }] };
137
- }
138
- // =============================================================================
139
- // MULTI-MODEL HANDLER
140
- // =============================================================================
141
- export async function handleAskMulti(input) {
142
- const request = toPeerRequest(input);
143
- const availableAdapters = await getAvailableAdapters();
144
- if (availableAdapters.length === 0) {
145
- return {
146
- content: [{
147
- type: 'text',
148
- text: `❌ No AI CLIs found.\n\nInstall at least one:\n - Codex: npm install -g @openai/codex\n - Gemini: npm install -g @google/gemini-cli`
149
- }]
150
- };
151
- }
152
- const promises = availableAdapters.map(async (adapter) => {
153
- const result = await adapter.runPeerRequest(request);
154
- return { adapter, result };
155
- });
156
- const results = await Promise.all(promises);
157
- const successful = [];
158
- const failed = [];
159
- for (const { adapter, result } of results) {
160
- if (result.success) {
161
- successful.push({ model: adapter.id, output: result.output });
162
- }
163
- else {
164
- failed.push({ model: adapter.id, error: result.error.message });
165
- }
166
- }
167
- const lines = [];
168
- if (failed.length === results.length) {
169
- lines.push('## Multi-Model Response ❌ All Failed\n');
170
- }
171
- else if (failed.length > 0) {
172
- lines.push('## Multi-Model Response ⚠️ Partial Success\n');
173
- }
174
- else {
175
- lines.push('## Multi-Model Response ✓\n');
176
- }
177
- lines.push(`**Models:** ${availableAdapters.map(a => a.id).join(', ')}`);
178
- lines.push('');
179
- for (const { model, output } of successful) {
180
- lines.push(`### ${model.charAt(0).toUpperCase() + model.slice(1)} Response\n`);
181
- lines.push(formatPeerResponse({ success: true, output, executionTimeMs: 0 }, model));
182
- lines.push('');
183
- }
184
- if (failed.length > 0) {
185
- lines.push('### Failures\n');
186
- for (const { model, error } of failed) {
187
- lines.push(`**${model}:** ${error}`);
188
- }
189
- lines.push('');
190
- }
191
- if (successful.length > 1) {
192
- lines.push(`---\n\n**Synthesis Instructions:**\n- Compare perspectives from each model\n- Note agreements and disagreements\n- Use your judgment to form a final answer`);
193
- }
194
- return { content: [{ type: 'text', text: lines.join('\n') }] };
195
- }
196
- // =============================================================================
197
- // TOOL DEFINITIONS
198
- // =============================================================================
199
- export const PEER_TOOL_DEFINITIONS = {
200
- ask_codex: {
201
- name: 'ask_codex',
202
- description: "Ask OpenAI Codex CLI for help as a peer engineer. Use for planning, debugging, explaining, fixing, exploring, or answering questions. Codex excels at correctness, logic, and edge cases.",
203
- inputSchema: {
204
- type: 'object',
205
- properties: {
206
- workingDir: {
207
- type: 'string',
208
- description: 'Working directory for filesystem access',
209
- },
210
- prompt: {
211
- type: 'string',
212
- description: 'Your question or request',
213
- },
214
- taskType: {
215
- type: 'string',
216
- enum: ['plan', 'debug', 'explain', 'question', 'fix', 'explore', 'general'],
217
- description: 'Hint about the type of task',
218
- },
219
- relevantFiles: {
220
- type: 'array',
221
- items: { type: 'string' },
222
- description: 'Files the peer should focus on',
223
- },
224
- context: {
225
- type: 'string',
226
- description: 'Additional context (error messages, prior analysis)',
227
- },
228
- focusAreas: {
229
- type: 'array',
230
- items: {
231
- type: 'string',
232
- enum: ['security', 'performance', 'architecture', 'correctness', 'maintainability', 'scalability', 'testing', 'documentation'],
233
- },
234
- description: 'Areas to focus on',
235
- },
236
- customPrompt: {
237
- type: 'string',
238
- description: 'Additional instructions for the peer',
239
- },
240
- reasoningEffort: {
241
- type: 'string',
242
- enum: ['high', 'xhigh'],
243
- description: 'Codex reasoning effort (default: high)',
244
- },
245
- serviceTier: {
246
- type: 'string',
247
- enum: ['default', 'fast', 'flex'],
248
- description: 'Codex service tier (fast = priority processing, flex = cheaper/slower)',
249
- },
250
- },
251
- required: ['workingDir', 'prompt'],
252
- },
253
- },
254
- ask_gemini: {
255
- name: 'ask_gemini',
256
- description: "Ask Google Gemini CLI for help as a peer engineer. Use for planning, debugging, explaining, fixing, exploring, or answering questions. Gemini excels at architecture, patterns, and scalability.",
257
- inputSchema: {
258
- type: 'object',
259
- properties: {
260
- workingDir: {
261
- type: 'string',
262
- description: 'Working directory for filesystem access',
263
- },
264
- prompt: {
265
- type: 'string',
266
- description: 'Your question or request',
267
- },
268
- taskType: {
269
- type: 'string',
270
- enum: ['plan', 'debug', 'explain', 'question', 'fix', 'explore', 'general'],
271
- description: 'Hint about the type of task',
272
- },
273
- relevantFiles: {
274
- type: 'array',
275
- items: { type: 'string' },
276
- description: 'Files the peer should focus on',
277
- },
278
- context: {
279
- type: 'string',
280
- description: 'Additional context (error messages, prior analysis)',
281
- },
282
- focusAreas: {
283
- type: 'array',
284
- items: {
285
- type: 'string',
286
- enum: ['security', 'performance', 'architecture', 'correctness', 'maintainability', 'scalability', 'testing', 'documentation'],
287
- },
288
- description: 'Areas to focus on',
289
- },
290
- customPrompt: {
291
- type: 'string',
292
- description: 'Additional instructions for the peer',
293
- },
294
- },
295
- required: ['workingDir', 'prompt'],
296
- },
297
- },
298
- ask_multi: {
299
- name: 'ask_multi',
300
- description: "Ask both Codex and Gemini CLIs for help in parallel. Get multiple perspectives on planning, debugging, explaining, or any task. Synthesize the responses yourself.",
301
- inputSchema: {
302
- type: 'object',
303
- properties: {
304
- workingDir: {
305
- type: 'string',
306
- description: 'Working directory for filesystem access',
307
- },
308
- prompt: {
309
- type: 'string',
310
- description: 'Your question or request',
311
- },
312
- taskType: {
313
- type: 'string',
314
- enum: ['plan', 'debug', 'explain', 'question', 'fix', 'explore', 'general'],
315
- description: 'Hint about the type of task',
316
- },
317
- relevantFiles: {
318
- type: 'array',
319
- items: { type: 'string' },
320
- description: 'Files the peer should focus on',
321
- },
322
- context: {
323
- type: 'string',
324
- description: 'Additional context (error messages, prior analysis)',
325
- },
326
- focusAreas: {
327
- type: 'array',
328
- items: {
329
- type: 'string',
330
- enum: ['security', 'performance', 'architecture', 'correctness', 'maintainability', 'scalability', 'testing', 'documentation'],
331
- },
332
- description: 'Areas to focus on',
333
- },
334
- customPrompt: {
335
- type: 'string',
336
- description: 'Additional instructions for the peer',
337
- },
338
- serviceTier: {
339
- type: 'string',
340
- enum: ['default', 'fast', 'flex'],
341
- description: 'Codex service tier (fast = priority processing, flex = cheaper/slower). Only applies to Codex.',
342
- },
343
- },
344
- required: ['workingDir', 'prompt'],
345
- },
346
- },
347
- };
File without changes
File without changes