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.
- package/README.md +15 -35
- package/commands/{codex-xhigh.md → codex-xhigh-review.md} +3 -3
- package/commands/{multi.md → multi-review.md} +1 -1
- package/dist/adapters/base.d.ts +3 -41
- package/dist/adapters/codex.d.ts +4 -6
- package/dist/adapters/codex.js +68 -322
- package/dist/adapters/gemini.d.ts +4 -6
- package/dist/adapters/gemini.js +46 -276
- package/dist/commands.d.ts +2 -3
- package/dist/commands.js +33 -11
- package/dist/decoders/codex.d.ts +11 -0
- package/dist/decoders/codex.js +29 -0
- package/dist/handoff.d.ts +2 -17
- package/dist/handoff.js +3 -87
- package/dist/index.d.ts +1 -1
- package/dist/index.js +17 -22
- package/dist/schema.d.ts +6 -195
- package/dist/schema.js +1 -190
- package/dist/tools/feedback.d.ts +5 -6
- package/dist/tools/feedback.js +63 -338
- package/dist/types.d.ts +0 -1
- package/package.json +2 -3
- package/commands/ask-codex.md +0 -36
- package/commands/ask-gemini.md +0 -35
- package/commands/ask-multi.md +0 -39
- package/dist/setup.d.ts +0 -7
- package/dist/setup.js +0 -27
- package/dist/tools/peer.d.ts +0 -194
- package/dist/tools/peer.js +0 -347
- /package/commands/{codex.md → codex-review.md} +0 -0
- /package/commands/{gemini.md → gemini-review.md} +0 -0
package/dist/handoff.js
CHANGED
|
@@ -154,10 +154,11 @@ export function selectRole(focusAreas) {
|
|
|
154
154
|
return CHANGE_FOCUSED_REVIEWER;
|
|
155
155
|
}
|
|
156
156
|
/**
|
|
157
|
-
* Build the review prompt using minimal, targeted context
|
|
157
|
+
* Build the review prompt using minimal, targeted context.
|
|
158
|
+
* No output format constraints — reviewer responds naturally, CC interprets.
|
|
158
159
|
*/
|
|
159
160
|
export function buildHandoffPrompt(options) {
|
|
160
|
-
const { handoff
|
|
161
|
+
const { handoff } = options;
|
|
161
162
|
const role = options.role || selectRole(handoff.focusAreas);
|
|
162
163
|
const sections = [];
|
|
163
164
|
// SECTION 1: ROLE
|
|
@@ -197,38 +198,6 @@ ${handoff.decisions.map((d, i) => `${i + 1}. **${d.decision}**
|
|
|
197
198
|
if (handoff.priorityFiles && handoff.priorityFiles.length > 0) {
|
|
198
199
|
sections.push(`## PRIORITY FILES\n\n${handoff.priorityFiles.map(f => `- \`${f}\``).join('\n')}`);
|
|
199
200
|
}
|
|
200
|
-
// SECTION 7: OUTPUT FORMAT
|
|
201
|
-
if (outputFormat === 'schema-enforced') {
|
|
202
|
-
sections.push(`## OUTPUT FORMAT
|
|
203
|
-
Respond with valid JSON matching the schema. Confidence reflects YOUR certainty.`);
|
|
204
|
-
}
|
|
205
|
-
else if (outputFormat === 'json') {
|
|
206
|
-
sections.push(`## OUTPUT FORMAT
|
|
207
|
-
Respond with valid JSON:
|
|
208
|
-
\`\`\`json
|
|
209
|
-
{
|
|
210
|
-
"findings": [{
|
|
211
|
-
"id": "string",
|
|
212
|
-
"category": "security|performance|correctness|architecture|other",
|
|
213
|
-
"severity": "critical|high|medium|low|info",
|
|
214
|
-
"confidence": 0.0-1.0,
|
|
215
|
-
"title": "string",
|
|
216
|
-
"description": "string",
|
|
217
|
-
"location": { "file": "string", "line_start": 0 },
|
|
218
|
-
"evidence": "code snippet",
|
|
219
|
-
"suggestion": "string"
|
|
220
|
-
}],
|
|
221
|
-
"uncertainty_responses": [{"uncertainty_index": 0, "verified": true, "finding": "string", "recommendation": "string"}],
|
|
222
|
-
"question_answers": [{"question_index": 0, "answer": "string", "confidence": 0.0-1.0}],
|
|
223
|
-
"agreements": ["string"],
|
|
224
|
-
"risk_assessment": { "level": "critical|high|medium|low|minimal", "summary": "string" }
|
|
225
|
-
}
|
|
226
|
-
\`\`\``);
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
sections.push(`## OUTPUT FORMAT
|
|
230
|
-
Structure: ## Findings, ## Uncertainty Responses, ## Question Answers, ## Agreements, ## Risk Assessment.`);
|
|
231
|
-
}
|
|
232
201
|
return sections.join('\n\n');
|
|
233
202
|
}
|
|
234
203
|
// =============================================================================
|
|
@@ -258,56 +227,3 @@ export function enhanceHandoff(handoff, uncertainties, questions, decisions) {
|
|
|
258
227
|
decisions: decisions || handoff.decisions,
|
|
259
228
|
};
|
|
260
229
|
}
|
|
261
|
-
/**
|
|
262
|
-
* Build a prompt for general-purpose peer assistance (not review).
|
|
263
|
-
* The peer acts as a collaborative coworker, not a critic.
|
|
264
|
-
*/
|
|
265
|
-
export function buildPeerPrompt(options) {
|
|
266
|
-
const { workingDir, prompt, taskType, relevantFiles, context, focusAreas, customInstructions, outputFormat } = options;
|
|
267
|
-
const role = selectRole(focusAreas);
|
|
268
|
-
const sections = [];
|
|
269
|
-
// SECTION 1: ROLE
|
|
270
|
-
sections.push(`# ROLE: ${role.name} — Peer Engineer
|
|
271
|
-
|
|
272
|
-
${role.systemPrompt}
|
|
273
|
-
Be direct and actionable.`);
|
|
274
|
-
// SECTION 2: TASK
|
|
275
|
-
const taskLabel = taskType ? ` [${taskType.toUpperCase()}]` : '';
|
|
276
|
-
sections.push(`## YOUR TASK${taskLabel}
|
|
277
|
-
|
|
278
|
-
**Request:** ${prompt}${context ? `\n**Context:** ${context}` : ''}`);
|
|
279
|
-
// SECTION 3: RELEVANT FILES
|
|
280
|
-
if (relevantFiles && relevantFiles.length > 0) {
|
|
281
|
-
sections.push(`## RELEVANT FILES\n${relevantFiles.map(f => `- \`${f}\``).join('\n')}`);
|
|
282
|
-
}
|
|
283
|
-
// SECTION 4: FOCUS AREAS
|
|
284
|
-
if (focusAreas && focusAreas.length > 0) {
|
|
285
|
-
sections.push(`## FOCUS AREAS\n\n${focusAreas.join(', ')}`);
|
|
286
|
-
}
|
|
287
|
-
// SECTION 5: CUSTOM INSTRUCTIONS
|
|
288
|
-
if (customInstructions) {
|
|
289
|
-
sections.push(`## ADDITIONAL INSTRUCTIONS\n\n${customInstructions}`);
|
|
290
|
-
}
|
|
291
|
-
// SECTION 6: OUTPUT FORMAT
|
|
292
|
-
if (outputFormat === 'schema-enforced') {
|
|
293
|
-
sections.push(`## OUTPUT FORMAT
|
|
294
|
-
Respond with valid JSON matching the schema. Confidence reflects YOUR certainty.`);
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
sections.push(`## OUTPUT FORMAT
|
|
298
|
-
Respond with valid JSON:
|
|
299
|
-
\`\`\`json
|
|
300
|
-
{
|
|
301
|
-
"responder": "string",
|
|
302
|
-
"answer": "markdown",
|
|
303
|
-
"confidence": 0.0-1.0,
|
|
304
|
-
"key_points": ["string"],
|
|
305
|
-
"suggested_actions": [{ "action": "string", "priority": "high|medium|low", "file": "string", "rationale": "string" }],
|
|
306
|
-
"file_references": [{ "path": "string", "lines": "string", "relevance": "string" }],
|
|
307
|
-
"alternatives": [{ "topic": "string", "current_approach": "string", "alternative": "string", "tradeoffs": { "pros": [], "cons": [] }, "recommendation": "string" }],
|
|
308
|
-
"execution_notes": "string"
|
|
309
|
-
}
|
|
310
|
-
\`\`\``);
|
|
311
|
-
}
|
|
312
|
-
return sections.join('\n\n');
|
|
313
|
-
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -13,21 +13,31 @@
|
|
|
13
13
|
*
|
|
14
14
|
* Usage:
|
|
15
15
|
* - npx cc-reviewer # Run MCP server (normal usage)
|
|
16
|
-
* - npx cc-reviewer
|
|
16
|
+
* - npx cc-reviewer update # Install/update slash commands
|
|
17
17
|
*/
|
|
18
18
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
19
19
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
20
20
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
21
21
|
import { handleCodexReview, handleGeminiReview, handleMultiReview, ReviewInputSchema, TOOL_DEFINITIONS } from './tools/feedback.js';
|
|
22
|
-
import { handleAskCodex, handleAskGemini, handleAskMulti, PEER_TOOL_DEFINITIONS, } from './tools/peer.js';
|
|
23
|
-
import { PeerInputSchema } from './schema.js';
|
|
24
22
|
import { logCliStatus } from './cli/check.js';
|
|
25
23
|
import { installCommands } from './commands.js';
|
|
26
|
-
//
|
|
27
|
-
|
|
24
|
+
// Read version from package.json
|
|
25
|
+
import { readFileSync } from 'fs';
|
|
26
|
+
import { join, dirname } from 'path';
|
|
27
|
+
import { fileURLToPath } from 'url';
|
|
28
|
+
const __pkgPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json');
|
|
29
|
+
const __pkg = JSON.parse(readFileSync(__pkgPath, 'utf-8'));
|
|
30
|
+
const VERSION = __pkg.version;
|
|
31
|
+
// Handle subcommands
|
|
32
|
+
const subcommand = process.argv[2];
|
|
33
|
+
if (subcommand === 'update' || subcommand === '--setup' || subcommand === '--commands') {
|
|
28
34
|
const result = installCommands();
|
|
29
35
|
if (result.success) {
|
|
30
|
-
console.log(
|
|
36
|
+
console.log(`cc-reviewer v${VERSION}`);
|
|
37
|
+
if (result.removed.length > 0) {
|
|
38
|
+
console.log(`✓ Removed ${result.removed.length} deprecated commands: ${result.removed.map(c => `/${c}`).join(', ')}`);
|
|
39
|
+
}
|
|
40
|
+
console.log(`✓ Installed ${result.installed.length} slash commands: ${result.installed.map(c => `/${c}`).join(', ')}`);
|
|
31
41
|
process.exit(0);
|
|
32
42
|
}
|
|
33
43
|
else {
|
|
@@ -40,7 +50,7 @@ import './adapters/index.js';
|
|
|
40
50
|
// Create the MCP server
|
|
41
51
|
const server = new Server({
|
|
42
52
|
name: 'ai-reviewer',
|
|
43
|
-
version:
|
|
53
|
+
version: VERSION,
|
|
44
54
|
}, {
|
|
45
55
|
capabilities: {
|
|
46
56
|
tools: {},
|
|
@@ -53,9 +63,6 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
53
63
|
TOOL_DEFINITIONS.codex_review,
|
|
54
64
|
TOOL_DEFINITIONS.gemini_review,
|
|
55
65
|
TOOL_DEFINITIONS.multi_review,
|
|
56
|
-
PEER_TOOL_DEFINITIONS.ask_codex,
|
|
57
|
-
PEER_TOOL_DEFINITIONS.ask_gemini,
|
|
58
|
-
PEER_TOOL_DEFINITIONS.ask_multi,
|
|
59
66
|
],
|
|
60
67
|
};
|
|
61
68
|
});
|
|
@@ -76,18 +83,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
76
83
|
const input = ReviewInputSchema.parse(args);
|
|
77
84
|
return await handleMultiReview(input);
|
|
78
85
|
}
|
|
79
|
-
case 'ask_codex': {
|
|
80
|
-
const input = PeerInputSchema.parse(args);
|
|
81
|
-
return await handleAskCodex(input);
|
|
82
|
-
}
|
|
83
|
-
case 'ask_gemini': {
|
|
84
|
-
const input = PeerInputSchema.parse(args);
|
|
85
|
-
return await handleAskGemini(input);
|
|
86
|
-
}
|
|
87
|
-
case 'ask_multi': {
|
|
88
|
-
const input = PeerInputSchema.parse(args);
|
|
89
|
-
return await handleAskMulti(input);
|
|
90
|
-
}
|
|
91
86
|
default:
|
|
92
87
|
return {
|
|
93
88
|
content: [{
|
package/dist/schema.d.ts
CHANGED
|
@@ -76,8 +76,8 @@ export declare const ReviewFinding: z.ZodObject<{
|
|
|
76
76
|
column_start?: number | undefined;
|
|
77
77
|
column_end?: number | undefined;
|
|
78
78
|
} | undefined;
|
|
79
|
-
evidence?: string | undefined;
|
|
80
79
|
suggestion?: string | undefined;
|
|
80
|
+
evidence?: string | undefined;
|
|
81
81
|
cwe_id?: string | undefined;
|
|
82
82
|
owasp_category?: string | undefined;
|
|
83
83
|
tags?: string[] | undefined;
|
|
@@ -95,8 +95,8 @@ export declare const ReviewFinding: z.ZodObject<{
|
|
|
95
95
|
column_start?: number | undefined;
|
|
96
96
|
column_end?: number | undefined;
|
|
97
97
|
} | undefined;
|
|
98
|
-
evidence?: string | undefined;
|
|
99
98
|
suggestion?: string | undefined;
|
|
99
|
+
evidence?: string | undefined;
|
|
100
100
|
cwe_id?: string | undefined;
|
|
101
101
|
owasp_category?: string | undefined;
|
|
102
102
|
tags?: string[] | undefined;
|
|
@@ -279,8 +279,8 @@ export declare const ReviewOutput: z.ZodObject<{
|
|
|
279
279
|
column_start?: number | undefined;
|
|
280
280
|
column_end?: number | undefined;
|
|
281
281
|
} | undefined;
|
|
282
|
-
evidence?: string | undefined;
|
|
283
282
|
suggestion?: string | undefined;
|
|
283
|
+
evidence?: string | undefined;
|
|
284
284
|
cwe_id?: string | undefined;
|
|
285
285
|
owasp_category?: string | undefined;
|
|
286
286
|
tags?: string[] | undefined;
|
|
@@ -298,8 +298,8 @@ export declare const ReviewOutput: z.ZodObject<{
|
|
|
298
298
|
column_start?: number | undefined;
|
|
299
299
|
column_end?: number | undefined;
|
|
300
300
|
} | undefined;
|
|
301
|
-
evidence?: string | undefined;
|
|
302
301
|
suggestion?: string | undefined;
|
|
302
|
+
evidence?: string | undefined;
|
|
303
303
|
cwe_id?: string | undefined;
|
|
304
304
|
owasp_category?: string | undefined;
|
|
305
305
|
tags?: string[] | undefined;
|
|
@@ -444,8 +444,8 @@ export declare const ReviewOutput: z.ZodObject<{
|
|
|
444
444
|
column_start?: number | undefined;
|
|
445
445
|
column_end?: number | undefined;
|
|
446
446
|
} | undefined;
|
|
447
|
-
evidence?: string | undefined;
|
|
448
447
|
suggestion?: string | undefined;
|
|
448
|
+
evidence?: string | undefined;
|
|
449
449
|
cwe_id?: string | undefined;
|
|
450
450
|
owasp_category?: string | undefined;
|
|
451
451
|
tags?: string[] | undefined;
|
|
@@ -512,8 +512,8 @@ export declare const ReviewOutput: z.ZodObject<{
|
|
|
512
512
|
column_start?: number | undefined;
|
|
513
513
|
column_end?: number | undefined;
|
|
514
514
|
} | undefined;
|
|
515
|
-
evidence?: string | undefined;
|
|
516
515
|
suggestion?: string | undefined;
|
|
516
|
+
evidence?: string | undefined;
|
|
517
517
|
cwe_id?: string | undefined;
|
|
518
518
|
owasp_category?: string | undefined;
|
|
519
519
|
tags?: string[] | undefined;
|
|
@@ -649,192 +649,3 @@ export declare function isSubstantiveReview(output: ReviewOutput): boolean;
|
|
|
649
649
|
* This provides backwards compatibility during transition.
|
|
650
650
|
*/
|
|
651
651
|
export declare function parseLegacyMarkdownOutput(markdown: string, reviewer: string): ReviewOutput | null;
|
|
652
|
-
export declare const SuggestedAction: z.ZodObject<{
|
|
653
|
-
action: z.ZodString;
|
|
654
|
-
priority: z.ZodEnum<["high", "medium", "low"]>;
|
|
655
|
-
file: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
656
|
-
rationale: z.ZodString;
|
|
657
|
-
}, "strip", z.ZodTypeAny, {
|
|
658
|
-
rationale: string;
|
|
659
|
-
action: string;
|
|
660
|
-
priority: "high" | "medium" | "low";
|
|
661
|
-
file?: string | null | undefined;
|
|
662
|
-
}, {
|
|
663
|
-
rationale: string;
|
|
664
|
-
action: string;
|
|
665
|
-
priority: "high" | "medium" | "low";
|
|
666
|
-
file?: string | null | undefined;
|
|
667
|
-
}>;
|
|
668
|
-
export type SuggestedAction = z.infer<typeof SuggestedAction>;
|
|
669
|
-
export declare const FileReference: z.ZodObject<{
|
|
670
|
-
path: z.ZodString;
|
|
671
|
-
lines: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
672
|
-
relevance: z.ZodString;
|
|
673
|
-
}, "strip", z.ZodTypeAny, {
|
|
674
|
-
path: string;
|
|
675
|
-
relevance: string;
|
|
676
|
-
lines?: string | null | undefined;
|
|
677
|
-
}, {
|
|
678
|
-
path: string;
|
|
679
|
-
relevance: string;
|
|
680
|
-
lines?: string | null | undefined;
|
|
681
|
-
}>;
|
|
682
|
-
export type FileReference = z.infer<typeof FileReference>;
|
|
683
|
-
export declare const PeerOutput: z.ZodObject<{
|
|
684
|
-
responder: z.ZodString;
|
|
685
|
-
timestamp: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
686
|
-
answer: z.ZodString;
|
|
687
|
-
confidence: z.ZodNumber;
|
|
688
|
-
key_points: z.ZodArray<z.ZodString, "many">;
|
|
689
|
-
suggested_actions: z.ZodArray<z.ZodObject<{
|
|
690
|
-
action: z.ZodString;
|
|
691
|
-
priority: z.ZodEnum<["high", "medium", "low"]>;
|
|
692
|
-
file: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
693
|
-
rationale: z.ZodString;
|
|
694
|
-
}, "strip", z.ZodTypeAny, {
|
|
695
|
-
rationale: string;
|
|
696
|
-
action: string;
|
|
697
|
-
priority: "high" | "medium" | "low";
|
|
698
|
-
file?: string | null | undefined;
|
|
699
|
-
}, {
|
|
700
|
-
rationale: string;
|
|
701
|
-
action: string;
|
|
702
|
-
priority: "high" | "medium" | "low";
|
|
703
|
-
file?: string | null | undefined;
|
|
704
|
-
}>, "many">;
|
|
705
|
-
file_references: z.ZodArray<z.ZodObject<{
|
|
706
|
-
path: z.ZodString;
|
|
707
|
-
lines: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
708
|
-
relevance: z.ZodString;
|
|
709
|
-
}, "strip", z.ZodTypeAny, {
|
|
710
|
-
path: string;
|
|
711
|
-
relevance: string;
|
|
712
|
-
lines?: string | null | undefined;
|
|
713
|
-
}, {
|
|
714
|
-
path: string;
|
|
715
|
-
relevance: string;
|
|
716
|
-
lines?: string | null | undefined;
|
|
717
|
-
}>, "many">;
|
|
718
|
-
alternatives: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
719
|
-
topic: z.ZodString;
|
|
720
|
-
current_approach: z.ZodString;
|
|
721
|
-
alternative: z.ZodString;
|
|
722
|
-
tradeoffs: z.ZodObject<{
|
|
723
|
-
pros: z.ZodArray<z.ZodString, "many">;
|
|
724
|
-
cons: z.ZodArray<z.ZodString, "many">;
|
|
725
|
-
}, "strip", z.ZodTypeAny, {
|
|
726
|
-
pros: string[];
|
|
727
|
-
cons: string[];
|
|
728
|
-
}, {
|
|
729
|
-
pros: string[];
|
|
730
|
-
cons: string[];
|
|
731
|
-
}>;
|
|
732
|
-
recommendation: z.ZodEnum<["strongly_prefer", "consider", "situational", "informational"]>;
|
|
733
|
-
}, "strip", z.ZodTypeAny, {
|
|
734
|
-
topic: string;
|
|
735
|
-
tradeoffs: {
|
|
736
|
-
pros: string[];
|
|
737
|
-
cons: string[];
|
|
738
|
-
};
|
|
739
|
-
current_approach: string;
|
|
740
|
-
alternative: string;
|
|
741
|
-
recommendation: "strongly_prefer" | "consider" | "situational" | "informational";
|
|
742
|
-
}, {
|
|
743
|
-
topic: string;
|
|
744
|
-
tradeoffs: {
|
|
745
|
-
pros: string[];
|
|
746
|
-
cons: string[];
|
|
747
|
-
};
|
|
748
|
-
current_approach: string;
|
|
749
|
-
alternative: string;
|
|
750
|
-
recommendation: "strongly_prefer" | "consider" | "situational" | "informational";
|
|
751
|
-
}>, "many">>>;
|
|
752
|
-
execution_notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
753
|
-
}, "strip", z.ZodTypeAny, {
|
|
754
|
-
confidence: number;
|
|
755
|
-
answer: string;
|
|
756
|
-
responder: string;
|
|
757
|
-
key_points: string[];
|
|
758
|
-
suggested_actions: {
|
|
759
|
-
rationale: string;
|
|
760
|
-
action: string;
|
|
761
|
-
priority: "high" | "medium" | "low";
|
|
762
|
-
file?: string | null | undefined;
|
|
763
|
-
}[];
|
|
764
|
-
file_references: {
|
|
765
|
-
path: string;
|
|
766
|
-
relevance: string;
|
|
767
|
-
lines?: string | null | undefined;
|
|
768
|
-
}[];
|
|
769
|
-
alternatives?: {
|
|
770
|
-
topic: string;
|
|
771
|
-
tradeoffs: {
|
|
772
|
-
pros: string[];
|
|
773
|
-
cons: string[];
|
|
774
|
-
};
|
|
775
|
-
current_approach: string;
|
|
776
|
-
alternative: string;
|
|
777
|
-
recommendation: "strongly_prefer" | "consider" | "situational" | "informational";
|
|
778
|
-
}[] | null | undefined;
|
|
779
|
-
timestamp?: string | null | undefined;
|
|
780
|
-
execution_notes?: string | null | undefined;
|
|
781
|
-
}, {
|
|
782
|
-
confidence: number;
|
|
783
|
-
answer: string;
|
|
784
|
-
responder: string;
|
|
785
|
-
key_points: string[];
|
|
786
|
-
suggested_actions: {
|
|
787
|
-
rationale: string;
|
|
788
|
-
action: string;
|
|
789
|
-
priority: "high" | "medium" | "low";
|
|
790
|
-
file?: string | null | undefined;
|
|
791
|
-
}[];
|
|
792
|
-
file_references: {
|
|
793
|
-
path: string;
|
|
794
|
-
relevance: string;
|
|
795
|
-
lines?: string | null | undefined;
|
|
796
|
-
}[];
|
|
797
|
-
alternatives?: {
|
|
798
|
-
topic: string;
|
|
799
|
-
tradeoffs: {
|
|
800
|
-
pros: string[];
|
|
801
|
-
cons: string[];
|
|
802
|
-
};
|
|
803
|
-
current_approach: string;
|
|
804
|
-
alternative: string;
|
|
805
|
-
recommendation: "strongly_prefer" | "consider" | "situational" | "informational";
|
|
806
|
-
}[] | null | undefined;
|
|
807
|
-
timestamp?: string | null | undefined;
|
|
808
|
-
execution_notes?: string | null | undefined;
|
|
809
|
-
}>;
|
|
810
|
-
export type PeerOutput = z.infer<typeof PeerOutput>;
|
|
811
|
-
export declare const TaskType: z.ZodEnum<["plan", "debug", "explain", "question", "fix", "explore", "general"]>;
|
|
812
|
-
export type TaskType = z.infer<typeof TaskType>;
|
|
813
|
-
export declare const PeerInputSchema: z.ZodObject<{
|
|
814
|
-
workingDir: z.ZodString;
|
|
815
|
-
prompt: z.ZodString;
|
|
816
|
-
taskType: z.ZodOptional<z.ZodEnum<["plan", "debug", "explain", "question", "fix", "explore", "general"]>>;
|
|
817
|
-
relevantFiles: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
818
|
-
context: z.ZodOptional<z.ZodString>;
|
|
819
|
-
focusAreas: z.ZodOptional<z.ZodArray<z.ZodEnum<["security", "performance", "architecture", "correctness", "maintainability", "scalability", "testing", "documentation"]>, "many">>;
|
|
820
|
-
customPrompt: z.ZodOptional<z.ZodString>;
|
|
821
|
-
}, "strip", z.ZodTypeAny, {
|
|
822
|
-
workingDir: string;
|
|
823
|
-
prompt: string;
|
|
824
|
-
taskType?: "question" | "plan" | "debug" | "explain" | "fix" | "explore" | "general" | undefined;
|
|
825
|
-
context?: string | undefined;
|
|
826
|
-
relevantFiles?: string[] | undefined;
|
|
827
|
-
focusAreas?: ("performance" | "security" | "testing" | "architecture" | "correctness" | "maintainability" | "scalability" | "documentation")[] | undefined;
|
|
828
|
-
customPrompt?: string | undefined;
|
|
829
|
-
}, {
|
|
830
|
-
workingDir: string;
|
|
831
|
-
prompt: string;
|
|
832
|
-
taskType?: "question" | "plan" | "debug" | "explain" | "fix" | "explore" | "general" | undefined;
|
|
833
|
-
context?: string | undefined;
|
|
834
|
-
relevantFiles?: string[] | undefined;
|
|
835
|
-
focusAreas?: ("performance" | "security" | "testing" | "architecture" | "correctness" | "maintainability" | "scalability" | "documentation")[] | undefined;
|
|
836
|
-
customPrompt?: string | undefined;
|
|
837
|
-
}>;
|
|
838
|
-
export type PeerInput = z.infer<typeof PeerInputSchema>;
|
|
839
|
-
export declare function getPeerOutputJsonSchema(): object;
|
|
840
|
-
export declare function parsePeerOutput(rawOutput: string): PeerOutput | null;
|
package/dist/schema.js
CHANGED
|
@@ -154,7 +154,7 @@ export function getReviewOutputJsonSchema() {
|
|
|
154
154
|
return {
|
|
155
155
|
type: 'object',
|
|
156
156
|
additionalProperties: false,
|
|
157
|
-
required: ['reviewer', 'findings', 'risk_assessment'],
|
|
157
|
+
required: ['reviewer', 'findings', 'agreements', 'disagreements', 'alternatives', 'risk_assessment', 'uncertainty_responses', 'question_answers'],
|
|
158
158
|
properties: {
|
|
159
159
|
reviewer: { type: 'string' },
|
|
160
160
|
findings: {
|
|
@@ -499,192 +499,3 @@ export function parseLegacyMarkdownOutput(markdown, reviewer) {
|
|
|
499
499
|
return null;
|
|
500
500
|
}
|
|
501
501
|
}
|
|
502
|
-
// =============================================================================
|
|
503
|
-
// PEER OUTPUT SCHEMA (General-purpose coworker responses)
|
|
504
|
-
// =============================================================================
|
|
505
|
-
export const SuggestedAction = z.object({
|
|
506
|
-
action: z.string().describe('What to do'),
|
|
507
|
-
priority: z.enum(['high', 'medium', 'low']),
|
|
508
|
-
file: z.string().nullable().optional().describe('Relevant file path'),
|
|
509
|
-
rationale: z.string().describe('Why this action is recommended'),
|
|
510
|
-
});
|
|
511
|
-
export const FileReference = z.object({
|
|
512
|
-
path: z.string().describe('Relative file path'),
|
|
513
|
-
lines: z.string().nullable().optional().describe('Line range, e.g. "10-25"'),
|
|
514
|
-
relevance: z.string().describe('Why this file matters'),
|
|
515
|
-
});
|
|
516
|
-
export const PeerOutput = z.object({
|
|
517
|
-
responder: z.string().describe('"codex" or "gemini"'),
|
|
518
|
-
timestamp: z.string().nullable().optional(),
|
|
519
|
-
// Core response
|
|
520
|
-
answer: z.string().describe('Main response text (markdown)'),
|
|
521
|
-
confidence: ConfidenceScore.describe('Confidence in the response (0-1)'),
|
|
522
|
-
// Structured breakdown
|
|
523
|
-
key_points: z.array(z.string()).describe('Bullet summary of main points'),
|
|
524
|
-
// Actionable items
|
|
525
|
-
suggested_actions: z.array(SuggestedAction).describe('Recommended actions'),
|
|
526
|
-
// File references
|
|
527
|
-
file_references: z.array(FileReference).describe('Files examined by the peer'),
|
|
528
|
-
// Optional — nullable because OpenAI strict mode sends null instead of omitting
|
|
529
|
-
alternatives: z.array(Alternative).nullable().optional().describe('Alternative approaches'),
|
|
530
|
-
execution_notes: z.string().nullable().optional().describe('Notes about the process'),
|
|
531
|
-
});
|
|
532
|
-
// =============================================================================
|
|
533
|
-
// PEER INPUT SCHEMA
|
|
534
|
-
// =============================================================================
|
|
535
|
-
export const TaskType = z.enum(['plan', 'debug', 'explain', 'question', 'fix', 'explore', 'general']);
|
|
536
|
-
export const PeerInputSchema = z.object({
|
|
537
|
-
workingDir: z.string().describe('Working directory for filesystem access'),
|
|
538
|
-
prompt: z.string().describe('The question or request from CC'),
|
|
539
|
-
taskType: TaskType.optional().describe('Hint about the type of task'),
|
|
540
|
-
relevantFiles: z.array(z.string()).optional().describe('Files the peer should focus on'),
|
|
541
|
-
context: z.string().optional().describe('Additional context (error messages, prior analysis)'),
|
|
542
|
-
focusAreas: z.array(z.enum([
|
|
543
|
-
'security', 'performance', 'architecture', 'correctness',
|
|
544
|
-
'maintainability', 'scalability', 'testing', 'documentation'
|
|
545
|
-
])).optional().describe('Areas to focus on'),
|
|
546
|
-
customPrompt: z.string().optional().describe('Additional instructions for the peer'),
|
|
547
|
-
});
|
|
548
|
-
// =============================================================================
|
|
549
|
-
// PEER OUTPUT JSON SCHEMA (for embedding in prompts)
|
|
550
|
-
// =============================================================================
|
|
551
|
-
export function getPeerOutputJsonSchema() {
|
|
552
|
-
return {
|
|
553
|
-
type: 'object',
|
|
554
|
-
additionalProperties: false,
|
|
555
|
-
required: ['responder', 'answer', 'confidence', 'key_points', 'suggested_actions', 'file_references', 'timestamp', 'alternatives', 'execution_notes'],
|
|
556
|
-
properties: {
|
|
557
|
-
responder: { type: 'string' },
|
|
558
|
-
timestamp: { anyOf: [{ type: 'string' }, { type: 'null' }] },
|
|
559
|
-
answer: { type: 'string' },
|
|
560
|
-
confidence: { type: 'number', minimum: 0, maximum: 1 },
|
|
561
|
-
key_points: {
|
|
562
|
-
type: 'array',
|
|
563
|
-
items: { type: 'string' },
|
|
564
|
-
},
|
|
565
|
-
suggested_actions: {
|
|
566
|
-
type: 'array',
|
|
567
|
-
items: {
|
|
568
|
-
type: 'object',
|
|
569
|
-
additionalProperties: false,
|
|
570
|
-
required: ['action', 'priority', 'rationale', 'file'],
|
|
571
|
-
properties: {
|
|
572
|
-
action: { type: 'string' },
|
|
573
|
-
priority: { type: 'string', enum: ['high', 'medium', 'low'] },
|
|
574
|
-
file: { anyOf: [{ type: 'string' }, { type: 'null' }] },
|
|
575
|
-
rationale: { type: 'string' },
|
|
576
|
-
},
|
|
577
|
-
},
|
|
578
|
-
},
|
|
579
|
-
file_references: {
|
|
580
|
-
type: 'array',
|
|
581
|
-
items: {
|
|
582
|
-
type: 'object',
|
|
583
|
-
additionalProperties: false,
|
|
584
|
-
required: ['path', 'relevance', 'lines'],
|
|
585
|
-
properties: {
|
|
586
|
-
path: { type: 'string' },
|
|
587
|
-
lines: { anyOf: [{ type: 'string' }, { type: 'null' }] },
|
|
588
|
-
relevance: { type: 'string' },
|
|
589
|
-
},
|
|
590
|
-
},
|
|
591
|
-
},
|
|
592
|
-
alternatives: {
|
|
593
|
-
anyOf: [
|
|
594
|
-
{
|
|
595
|
-
type: 'array',
|
|
596
|
-
items: {
|
|
597
|
-
type: 'object',
|
|
598
|
-
additionalProperties: false,
|
|
599
|
-
required: ['topic', 'current_approach', 'alternative', 'tradeoffs', 'recommendation'],
|
|
600
|
-
properties: {
|
|
601
|
-
topic: { type: 'string' },
|
|
602
|
-
current_approach: { type: 'string' },
|
|
603
|
-
alternative: { type: 'string' },
|
|
604
|
-
tradeoffs: {
|
|
605
|
-
type: 'object',
|
|
606
|
-
additionalProperties: false,
|
|
607
|
-
required: ['pros', 'cons'],
|
|
608
|
-
properties: {
|
|
609
|
-
pros: { type: 'array', items: { type: 'string' } },
|
|
610
|
-
cons: { type: 'array', items: { type: 'string' } },
|
|
611
|
-
},
|
|
612
|
-
},
|
|
613
|
-
recommendation: { type: 'string', enum: ['strongly_prefer', 'consider', 'situational', 'informational'] },
|
|
614
|
-
},
|
|
615
|
-
},
|
|
616
|
-
},
|
|
617
|
-
{ type: 'null' },
|
|
618
|
-
],
|
|
619
|
-
},
|
|
620
|
-
execution_notes: { anyOf: [{ type: 'string' }, { type: 'null' }] },
|
|
621
|
-
},
|
|
622
|
-
};
|
|
623
|
-
}
|
|
624
|
-
// =============================================================================
|
|
625
|
-
// PEER OUTPUT PARSING
|
|
626
|
-
// =============================================================================
|
|
627
|
-
function normalizePeerOutput(parsed) {
|
|
628
|
-
const normalized = { ...parsed };
|
|
629
|
-
if (!normalized.responder) {
|
|
630
|
-
normalized.responder = 'external';
|
|
631
|
-
}
|
|
632
|
-
normalized.key_points = normalized.key_points ?? [];
|
|
633
|
-
normalized.suggested_actions = normalized.suggested_actions ?? [];
|
|
634
|
-
normalized.file_references = normalized.file_references ?? [];
|
|
635
|
-
if (normalized.confidence === undefined) {
|
|
636
|
-
normalized.confidence = 0.5;
|
|
637
|
-
}
|
|
638
|
-
if (!normalized.answer && typeof normalized.response === 'string') {
|
|
639
|
-
normalized.answer = normalized.response;
|
|
640
|
-
}
|
|
641
|
-
return normalized;
|
|
642
|
-
}
|
|
643
|
-
export function parsePeerOutput(rawOutput) {
|
|
644
|
-
try {
|
|
645
|
-
let jsonStr = rawOutput;
|
|
646
|
-
// Unwrap Gemini envelope
|
|
647
|
-
try {
|
|
648
|
-
const envelope = JSON.parse(rawOutput);
|
|
649
|
-
if (envelope && typeof envelope.session_id === 'string' && typeof envelope.response === 'string') {
|
|
650
|
-
jsonStr = envelope.response;
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
catch {
|
|
654
|
-
// Not an envelope
|
|
655
|
-
}
|
|
656
|
-
// Extract from ```json ... ``` blocks
|
|
657
|
-
const jsonBlockMatch = jsonStr.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
658
|
-
if (jsonBlockMatch) {
|
|
659
|
-
jsonStr = jsonBlockMatch[1].trim();
|
|
660
|
-
}
|
|
661
|
-
// Find JSON object boundaries
|
|
662
|
-
const jsonStart = jsonStr.indexOf('{');
|
|
663
|
-
const jsonEnd = jsonStr.lastIndexOf('}');
|
|
664
|
-
if (jsonStart !== -1 && jsonEnd !== -1 && jsonEnd > jsonStart) {
|
|
665
|
-
jsonStr = jsonStr.slice(jsonStart, jsonEnd + 1);
|
|
666
|
-
}
|
|
667
|
-
const parsed = JSON.parse(jsonStr);
|
|
668
|
-
// Try direct parse
|
|
669
|
-
const result = PeerOutput.safeParse(parsed);
|
|
670
|
-
if (result.success) {
|
|
671
|
-
return result.data;
|
|
672
|
-
}
|
|
673
|
-
// Normalize and retry
|
|
674
|
-
const recognizedFields = ['responder', 'answer', 'response', 'key_points', 'suggested_actions', 'file_references', 'confidence'];
|
|
675
|
-
const hasRecognizedField = typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed) &&
|
|
676
|
-
recognizedFields.some(f => f in parsed);
|
|
677
|
-
if (!hasRecognizedField) {
|
|
678
|
-
return null;
|
|
679
|
-
}
|
|
680
|
-
const normalized = normalizePeerOutput(parsed);
|
|
681
|
-
const retryResult = PeerOutput.safeParse(normalized);
|
|
682
|
-
if (retryResult.success) {
|
|
683
|
-
return retryResult.data;
|
|
684
|
-
}
|
|
685
|
-
return null;
|
|
686
|
-
}
|
|
687
|
-
catch {
|
|
688
|
-
return null;
|
|
689
|
-
}
|
|
690
|
-
}
|
package/dist/tools/feedback.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MCP Tool Implementations
|
|
2
|
+
* MCP Tool Implementations — Review Tools
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* 2. Multi-model parallel review (multi_review)
|
|
4
|
+
* Returns raw reviewer text to CC. No JSON parsing, no reformatting.
|
|
5
|
+
* CC handles interpretation and synthesis.
|
|
7
6
|
*/
|
|
8
7
|
import { z } from 'zod';
|
|
9
8
|
export declare const ReviewInputSchema: z.ZodObject<{
|
|
@@ -20,8 +19,8 @@ export declare const ReviewInputSchema: z.ZodObject<{
|
|
|
20
19
|
ccOutput: string;
|
|
21
20
|
outputType: "findings" | "analysis" | "plan" | "proposal";
|
|
22
21
|
focusAreas?: ("performance" | "security" | "testing" | "architecture" | "correctness" | "maintainability" | "scalability" | "documentation")[] | undefined;
|
|
23
|
-
customPrompt?: string | undefined;
|
|
24
22
|
analyzedFiles?: string[] | undefined;
|
|
23
|
+
customPrompt?: string | undefined;
|
|
25
24
|
reasoningEffort?: "high" | "xhigh" | undefined;
|
|
26
25
|
serviceTier?: "default" | "fast" | "flex" | undefined;
|
|
27
26
|
}, {
|
|
@@ -29,8 +28,8 @@ export declare const ReviewInputSchema: z.ZodObject<{
|
|
|
29
28
|
ccOutput: string;
|
|
30
29
|
outputType: "findings" | "analysis" | "plan" | "proposal";
|
|
31
30
|
focusAreas?: ("performance" | "security" | "testing" | "architecture" | "correctness" | "maintainability" | "scalability" | "documentation")[] | undefined;
|
|
32
|
-
customPrompt?: string | undefined;
|
|
33
31
|
analyzedFiles?: string[] | undefined;
|
|
32
|
+
customPrompt?: string | undefined;
|
|
34
33
|
reasoningEffort?: "high" | "xhigh" | undefined;
|
|
35
34
|
serviceTier?: "default" | "fast" | "flex" | undefined;
|
|
36
35
|
}>;
|