cc-reviewer 1.8.4 → 1.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -76,10 +76,11 @@ export class CodexAdapter {
76
76
  // Select role based on focus areas
77
77
  const role = selectRole(request.focusAreas);
78
78
  // Build prompt with retry context if needed
79
+ // Use 'schema-enforced' since Codex gets --output-schema flag (avoids redundant inline JSON template)
79
80
  let prompt = buildHandoffPrompt({
80
81
  handoff,
81
82
  role,
82
- outputFormat: 'json',
83
+ outputFormat: 'schema-enforced',
83
84
  });
84
85
  // Add retry context if this is a retry attempt
85
86
  if (attempt > 0) {
@@ -139,9 +140,14 @@ export class CodexAdapter {
139
140
  };
140
141
  }
141
142
  // Check for empty/minimal data on any parse path
143
+ // A valid review may have findings, agreements, disagreements, alternatives,
144
+ // or a non-default risk assessment. Only retry if truly empty across all fields.
142
145
  const hasMinimalData = output.findings.length === 0 &&
143
146
  output.agreements.length === 0 &&
144
- output.disagreements.length === 0;
147
+ output.disagreements.length === 0 &&
148
+ output.alternatives.length === 0 &&
149
+ output.risk_assessment.overall_level === 'medium' &&
150
+ output.risk_assessment.score === 50;
145
151
  if (hasMinimalData) {
146
152
  if (attempt < MAX_RETRIES) {
147
153
  console.error(`[codex] Received empty output, retrying...`);
@@ -231,6 +237,7 @@ export class CodexAdapter {
231
237
  }
232
238
  async runPeerWithRetry(request, attempt, startTime, previousError, previousOutput) {
233
239
  try {
240
+ // Use 'schema-enforced' since Codex gets --output-schema flag (avoids redundant inline JSON template)
234
241
  let prompt = buildPeerPrompt({
235
242
  workingDir: request.workingDir,
236
243
  prompt: request.prompt,
@@ -239,7 +246,7 @@ export class CodexAdapter {
239
246
  context: request.context,
240
247
  focusAreas: request.focusAreas,
241
248
  customInstructions: request.customPrompt,
242
- outputFormat: 'json',
249
+ outputFormat: 'schema-enforced',
243
250
  });
244
251
  if (attempt > 0) {
245
252
  prompt += `\n\n---\n\n# RETRY ATTEMPT ${attempt + 1}\n\n` +
@@ -320,9 +327,8 @@ export class CodexAdapter {
320
327
  schemaFile = null;
321
328
  }
322
329
  const args = [
323
- '--search',
324
330
  'exec',
325
- '-m', 'gpt-5.3-codex',
331
+ '-m', 'gpt-5.4',
326
332
  '-c', `model_reasoning_effort=${reasoningEffort}`,
327
333
  '-c', 'model_reasoning_summary_format=experimental',
328
334
  '--dangerously-bypass-approvals-and-sandbox',
@@ -137,9 +137,14 @@ export class GeminiAdapter {
137
137
  };
138
138
  }
139
139
  // If output has no substantive data, retry or fail
140
+ // A valid review may have findings, agreements, disagreements, alternatives,
141
+ // or a non-default risk assessment. Only retry if truly empty across all fields.
140
142
  const hasMinimalData = output.findings.length === 0 &&
141
143
  output.agreements.length === 0 &&
142
- output.disagreements.length === 0;
144
+ output.disagreements.length === 0 &&
145
+ output.alternatives.length === 0 &&
146
+ output.risk_assessment.overall_level === 'medium' &&
147
+ output.risk_assessment.score === 50;
143
148
  if (hasMinimalData) {
144
149
  if (attempt < MAX_RETRIES) {
145
150
  console.error(`[gemini] Received empty output, retrying...`);
package/dist/handoff.d.ts CHANGED
@@ -215,7 +215,7 @@ export declare function selectRole(focusAreas?: FocusArea[]): ReviewerRole;
215
215
  export interface PromptOptions {
216
216
  handoff: Handoff;
217
217
  role?: ReviewerRole;
218
- outputFormat: 'json' | 'markdown';
218
+ outputFormat: 'json' | 'markdown' | 'schema-enforced';
219
219
  }
220
220
  /**
221
221
  * Build the review prompt using minimal, targeted context
@@ -238,7 +238,7 @@ export interface PeerPromptOptions {
238
238
  context?: string;
239
239
  focusAreas?: FocusArea[];
240
240
  customInstructions?: string;
241
- outputFormat: 'json';
241
+ outputFormat: 'json' | 'schema-enforced';
242
242
  }
243
243
  /**
244
244
  * Build a prompt for general-purpose peer assistance (not review).
package/dist/handoff.js CHANGED
@@ -372,7 +372,23 @@ ${handoff.priorityFiles.map(f => `- \`${f}\``).join('\n')}`);
372
372
  // ==========================================================================
373
373
  // SECTION 7: OUTPUT FORMAT
374
374
  // ==========================================================================
375
- if (outputFormat === 'json') {
375
+ if (outputFormat === 'schema-enforced') {
376
+ // Schema is enforced externally (e.g. via --output-schema flag).
377
+ // Only include behavioral rules, skip the redundant JSON template.
378
+ sections.push(`
379
+ ---
380
+
381
+ # OUTPUT FORMAT
382
+
383
+ Respond with valid JSON matching the provided output schema.
384
+
385
+ **Rules:**
386
+ - Use \`git diff\` and file reading to verify before claiming issues
387
+ - Include evidence (code snippets) for findings
388
+ - Confidence reflects how sure YOU are (not CC)
389
+ - Answer CC's uncertainties and questions explicitly`);
390
+ }
391
+ else if (outputFormat === 'json') {
376
392
  sections.push(`
377
393
  ---
378
394
 
@@ -481,7 +497,7 @@ export function enhanceHandoff(handoff, uncertainties, questions, decisions) {
481
497
  * The peer acts as a collaborative coworker, not a critic.
482
498
  */
483
499
  export function buildPeerPrompt(options) {
484
- const { workingDir, prompt, taskType, relevantFiles, context, focusAreas, customInstructions } = options;
500
+ const { workingDir, prompt, taskType, relevantFiles, context, focusAreas, customInstructions, outputFormat } = options;
485
501
  // Select role based on focus areas (reuse existing role selection)
486
502
  const role = selectRole(focusAreas);
487
503
  const sections = [];
@@ -549,7 +565,25 @@ ${customInstructions}`);
549
565
  5. Reference specific files and line numbers
550
566
  6. Suggest concrete next steps`);
551
567
  // SECTION 7: OUTPUT FORMAT
552
- sections.push(`
568
+ if (outputFormat === 'schema-enforced') {
569
+ // Schema is enforced externally (e.g. via --output-schema flag).
570
+ // Only include behavioral rules, skip the redundant JSON template.
571
+ sections.push(`
572
+ ---
573
+
574
+ # OUTPUT FORMAT
575
+
576
+ Respond with valid JSON matching the provided output schema.
577
+
578
+ **Rules:**
579
+ - Read files before making claims
580
+ - Reference specific file paths and line numbers
581
+ - Be concrete and actionable — no vague suggestions
582
+ - Confidence reflects how sure YOU are about your answer
583
+ - Include alternatives when there are meaningful tradeoffs`);
584
+ }
585
+ else {
586
+ sections.push(`
553
587
  ---
554
588
 
555
589
  # OUTPUT FORMAT
@@ -596,5 +630,6 @@ Respond with valid JSON:
596
630
  - Be concrete and actionable — no vague suggestions
597
631
  - Confidence reflects how sure YOU are about your answer
598
632
  - Include alternatives when there are meaningful tradeoffs`);
633
+ }
599
634
  return sections.join('\n');
600
635
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-reviewer",
3
- "version": "1.8.4",
3
+ "version": "1.8.5",
4
4
  "description": "MCP server for Claude Code - Get second-opinion feedback from Codex/Gemini CLIs",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",