cc-reviewer 2.1.0 → 3.0.1

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 CHANGED
@@ -11,11 +11,11 @@ claude mcp add -s user cc-reviewer -- npx -y cc-reviewer
11
11
 
12
12
  **Step 2: Restart Claude Code**
13
13
 
14
- The MCP tools and slash commands (`/codex`, `/gemini`, `/multi`, `/ask-codex`, `/ask-gemini`, `/ask-multi`) are automatically installed.
14
+ The MCP tools and slash commands (`/codex-review`, `/gemini-review`, `/multi-review`) are automatically installed.
15
15
 
16
16
  **Manual command install** (if needed):
17
17
  ```bash
18
- npx cc-reviewer --setup
18
+ npx cc-reviewer update
19
19
  ```
20
20
 
21
21
  Verify with:
@@ -52,14 +52,10 @@ gemini # follow auth prompts
52
52
  These tools provide **external second-opinion reviews** from Codex and Gemini CLIs. They are designed to complement Claude Code's native review capabilities, not replace them.
53
53
 
54
54
  **Review tools** (external second-opinion on your work):
55
- - `/codex` or "review with codex" - Get external Codex review
56
- - `/gemini` or "review with gemini" - Get external Gemini review
57
- - `/multi` - Get parallel reviews from both CLIs
58
-
59
- **Ask tools** (get help from a peer engineer):
60
- - `/ask-codex` - Ask Codex for help (planning, debugging, explaining, fixing)
61
- - `/ask-gemini` - Ask Gemini for help (architecture, patterns, scalability)
62
- - `/ask-multi` - Ask both models in parallel
55
+ - `/codex-review` or "review with codex" - Get external Codex review
56
+ - `/codex-xhigh-review` - Deep-thinking Codex review with xhigh reasoning
57
+ - `/gemini-review` or "review with gemini" - Get external Gemini review
58
+ - `/multi-review` - Get parallel reviews from both CLIs
63
59
 
64
60
  **For regular reviews:** Just say "review" and Claude Code will use its native capabilities. These external tools are only invoked when explicitly requested.
65
61
 
@@ -68,24 +64,18 @@ These tools provide **external second-opinion reviews** from Codex and Gemini CL
68
64
  These commands are available after restart:
69
65
 
70
66
  ```bash
71
- # Review tools
72
- /codex # Review with Codex
73
- /codex security # Focus on security
74
- /codex-xhigh # Codex with xhigh reasoning effort
75
- /gemini # Review with Gemini
76
- /gemini architecture # Focus on architecture
77
- /multi # Both models in parallel
78
-
79
- # Ask tools (peer engineer)
80
- /ask-codex # Ask Codex for help
81
- /ask-gemini # Ask Gemini for help
82
- /ask-multi # Ask both in parallel
67
+ /codex-review # Review with Codex
68
+ /codex-review security # Focus on security
69
+ /codex-xhigh-review # Codex with xhigh reasoning effort
70
+ /gemini-review # Review with Gemini
71
+ /gemini-review architecture # Focus on architecture
72
+ /multi-review # Both models in parallel
83
73
  ```
84
74
 
85
75
  ## How It Works
86
76
 
87
77
  ```
88
- CC does work → User: /codex → External CLI reviews → CC synthesizes → Updated output
78
+ CC does work → User: /codex-review → External CLI reviews → CC synthesizes → Updated output
89
79
  ```
90
80
 
91
81
  **Key Principles:**
@@ -108,33 +98,23 @@ CC does work → User: /codex → External CLI reviews → CC synthesizes → Up
108
98
 
109
99
  ## MCP Tools
110
100
 
111
- The plugin exposes six MCP tools:
101
+ The plugin exposes three MCP tools:
112
102
 
113
103
  | Tool | Description |
114
104
  |------|-------------|
115
105
  | `codex_review` | Get Codex review (correctness, edge cases, performance) |
116
106
  | `gemini_review` | Get Gemini review (design patterns, scalability, tech debt) |
117
107
  | `multi_review` | Parallel review from both models |
118
- | `ask_codex` | Ask Codex for help (planning, debugging, explaining, fixing) |
119
- | `ask_gemini` | Ask Gemini for help (architecture, patterns, scalability) |
120
- | `ask_multi` | Ask both models in parallel |
121
108
 
122
109
  ## Output Format
123
110
 
124
- **Review tools** return structured JSON feedback with:
111
+ **Review tools** return structured feedback from the external CLIs. Claude Code parses this feedback to identify:
125
112
  - **Findings**: Issues with severity, confidence, location, and suggestions
126
113
  - **Agreements**: Validations of CC's correct assessments
127
114
  - **Disagreements**: Challenges to CC's claims with corrections
128
115
  - **Alternatives**: Different approaches with tradeoffs
129
116
  - **Risk Assessment**: Overall risk level with top concerns
130
117
 
131
- **Ask tools** return structured JSON responses with:
132
- - **Answer**: Main response text (markdown)
133
- - **Key Points**: Bullet summary of main points
134
- - **Suggested Actions**: Recommended actions with priority and rationale
135
- - **File References**: Files examined with line ranges and relevance
136
- - **Alternatives**: Alternative approaches considered
137
-
138
118
  ## Development
139
119
 
140
120
  ```bash
@@ -17,10 +17,10 @@ Use the `codex_review` MCP tool with `reasoningEffort: "xhigh"` for deeper analy
17
17
  2. Call the `codex_review` tool with:
18
18
  - `workingDir`: current working directory
19
19
  - `ccOutput`: brief summary of recent changes or context
20
- - `reasoningEffort`: "xhigh" (this is the key difference from /codex)
20
+ - `reasoningEffort`: "xhigh" (this is the key difference from /codex-review)
21
21
  - `serviceTier`: if user says "fast mode"/"fast"/"priority" → "fast"; if "flex"/"cheap"/"budget" → "flex"; otherwise omit
22
- - `focus`: extracted from $ARGUMENTS if it's a known focus area
23
- - `customInstructions`: $ARGUMENTS if it's custom text
22
+ - `focusAreas`: extracted from $ARGUMENTS if it's a known focus area
23
+ - `customPrompt`: $ARGUMENTS if it's custom text
24
24
 
25
25
  3. After receiving feedback - VALIDATE before accepting:
26
26
 
@@ -7,7 +7,7 @@ Get parallel reviews from both Codex and Gemini, raw output for manual synthesis
7
7
 
8
8
  ## When to Use
9
9
 
10
- Use `/multi` when you want parallel reviews from both Codex and Gemini.
10
+ Use `/multi-review` when you want parallel reviews from both Codex and Gemini.
11
11
 
12
12
  ## Before Calling - PREPARE THE HANDOFF
13
13
 
@@ -5,7 +5,7 @@
5
5
  * Makes it easy to add new models (Ollama, Azure, etc.) without
6
6
  * changing the core orchestration logic.
7
7
  */
8
- import { FocusArea, OutputType, ReasoningEffort, ServiceTier, TaskType } from '../types.js';
8
+ import { FocusArea, OutputType, ReasoningEffort, ServiceTier } from '../types.js';
9
9
  export interface ReviewerCapabilities {
10
10
  /** Display name for this reviewer */
11
11
  name: string;
@@ -54,26 +54,6 @@ export interface ExpertRole {
54
54
  export declare const EXPERT_ROLES: Record<string, ExpertRole>;
55
55
  /** @deprecated Use handoff.ts selectRole() instead */
56
56
  export declare function selectExpertRole(focusAreas?: FocusArea[]): ExpertRole;
57
- export interface PeerRequest {
58
- /** Working directory containing the code */
59
- workingDir: string;
60
- /** The question or request from CC */
61
- prompt: string;
62
- /** Hint about the type of task */
63
- taskType?: TaskType;
64
- /** Files the peer should focus on */
65
- relevantFiles?: string[];
66
- /** Additional context (error messages, prior analysis) */
67
- context?: string;
68
- /** Areas to focus on */
69
- focusAreas?: FocusArea[];
70
- /** Custom instructions from the user */
71
- customPrompt?: string;
72
- /** Reasoning effort level (for models that support it) */
73
- reasoningEffort?: ReasoningEffort;
74
- /** Service tier (for models that support it: priority = fast, flex = cheap) */
75
- serviceTier?: ServiceTier;
76
- }
77
57
  export interface ReviewSuccess {
78
58
  success: true;
79
59
  output: string;
@@ -92,19 +72,6 @@ export interface ReviewError {
92
72
  message: string;
93
73
  details?: Record<string, unknown>;
94
74
  }
95
- export interface PeerSuccess {
96
- success: true;
97
- output: string;
98
- executionTimeMs: number;
99
- }
100
- export interface PeerFailure {
101
- success: false;
102
- error: ReviewError;
103
- suggestion?: string;
104
- rawOutput?: string;
105
- executionTimeMs: number;
106
- }
107
- export type PeerResult = PeerSuccess | PeerFailure;
108
75
  /**
109
76
  * Base interface that all reviewer adapters must implement.
110
77
  * This allows easy addition of new AI CLIs without changing orchestration logic.
@@ -118,8 +85,6 @@ export interface ReviewerAdapter {
118
85
  isAvailable(): Promise<boolean>;
119
86
  /** Run a review and return structured output */
120
87
  runReview(request: ReviewRequest): Promise<ReviewResult>;
121
- /** Run a general-purpose peer request and return structured output */
122
- runPeerRequest(request: PeerRequest): Promise<PeerResult>;
123
88
  /**
124
89
  * Optional: Run peer review of another model's output
125
90
  * Future capability - not currently implemented by any adapter
@@ -5,13 +5,12 @@
5
5
  * Returns raw text — no JSON parsing or schema enforcement.
6
6
  * CC handles interpretation of the reviewer's response.
7
7
  */
8
- import { ReviewerAdapter, ReviewerCapabilities, ReviewRequest, ReviewResult, PeerRequest, PeerResult } from './base.js';
8
+ import { ReviewerAdapter, ReviewerCapabilities, ReviewRequest, ReviewResult } from './base.js';
9
9
  export declare class CodexAdapter implements ReviewerAdapter {
10
10
  readonly id = "codex";
11
11
  getCapabilities(): ReviewerCapabilities;
12
12
  isAvailable(): Promise<boolean>;
13
13
  runReview(request: ReviewRequest): Promise<ReviewResult>;
14
- runPeerRequest(request: PeerRequest): Promise<PeerResult>;
15
14
  private runCli;
16
15
  private handleException;
17
16
  private categorizeError;
@@ -10,7 +10,7 @@ import { existsSync } from 'fs';
10
10
  import { registerAdapter, } from './base.js';
11
11
  import { CliExecutor } from '../executor.js';
12
12
  import { CodexEventDecoder } from '../decoders/index.js';
13
- import { buildSimpleHandoff, buildHandoffPrompt, buildPeerPrompt, selectRole, } from '../handoff.js';
13
+ import { buildSimpleHandoff, buildHandoffPrompt, selectRole, } from '../handoff.js';
14
14
  // =============================================================================
15
15
  // CONFIGURATION
16
16
  // =============================================================================
@@ -70,46 +70,7 @@ export class CodexAdapter {
70
70
  return {
71
71
  success: false,
72
72
  error: { type: 'cli_error', message: 'Codex returned empty response' },
73
- suggestion: 'Try again or use /gemini instead',
74
- executionTimeMs: Date.now() - startTime,
75
- };
76
- }
77
- return { success: true, output: result.stdout, executionTimeMs: Date.now() - startTime };
78
- }
79
- catch (error) {
80
- return this.handleException(error, startTime);
81
- }
82
- }
83
- async runPeerRequest(request) {
84
- const startTime = Date.now();
85
- if (!existsSync(request.workingDir)) {
86
- return {
87
- success: false,
88
- error: { type: 'cli_error', message: `Working directory does not exist: ${request.workingDir}` },
89
- suggestion: 'Check that the working directory path is correct',
90
- executionTimeMs: Date.now() - startTime,
91
- };
92
- }
93
- try {
94
- const prompt = buildPeerPrompt({
95
- workingDir: request.workingDir,
96
- prompt: request.prompt,
97
- taskType: request.taskType,
98
- relevantFiles: request.relevantFiles,
99
- context: request.context,
100
- focusAreas: request.focusAreas,
101
- customInstructions: request.customPrompt,
102
- });
103
- const result = await this.runCli(prompt, request.workingDir, request.reasoningEffort || 'high', request.serviceTier);
104
- if (result.exitCode !== 0) {
105
- const error = this.categorizeError(result.stderr);
106
- return { success: false, error, suggestion: this.getSuggestion(error), executionTimeMs: Date.now() - startTime };
107
- }
108
- if (!result.stdout.trim()) {
109
- return {
110
- success: false,
111
- error: { type: 'cli_error', message: 'Codex returned empty response' },
112
- suggestion: 'Try again or use /ask-gemini instead',
73
+ suggestion: 'Try again or use /gemini-review instead',
113
74
  executionTimeMs: Date.now() - startTime,
114
75
  };
115
76
  }
@@ -126,7 +87,8 @@ export class CodexAdapter {
126
87
  '-m', 'gpt-5.4',
127
88
  '-c', `model_reasoning_effort=${reasoningEffort}`,
128
89
  '-c', 'model_reasoning_summary_format=experimental',
129
- '--dangerously-bypass-approvals-and-sandbox',
90
+ '--full-auto',
91
+ '--sandbox', 'read-only',
130
92
  '--skip-git-repo-check',
131
93
  '-C', workingDir,
132
94
  '-', // Read prompt from stdin
@@ -178,11 +140,11 @@ export class CodexAdapter {
178
140
  const err = error;
179
141
  if (err.code === 'ENOENT') {
180
142
  return { success: false, error: { type: 'cli_not_found', message: 'Codex CLI not found' },
181
- suggestion: 'Install with: npm install -g @openai/codex', executionTimeMs: Date.now() - startTime };
143
+ suggestion: 'Install with: npm install -g @openai/codex-cli', executionTimeMs: Date.now() - startTime };
182
144
  }
183
145
  if (err.message === 'TIMEOUT') {
184
146
  return { success: false, error: { type: 'timeout', message: 'Codex timed out — no events received' },
185
- suggestion: 'Try a smaller scope or use /gemini', executionTimeMs: Date.now() - startTime };
147
+ suggestion: 'Try a smaller scope or use /gemini-review', executionTimeMs: Date.now() - startTime };
186
148
  }
187
149
  if (err.message === 'MAX_TIMEOUT') {
188
150
  return { success: false, error: { type: 'timeout', message: 'Task exceeded 60 minute maximum' },
@@ -205,9 +167,9 @@ export class CodexAdapter {
205
167
  }
206
168
  getSuggestion(error) {
207
169
  switch (error.type) {
208
- case 'rate_limit': return 'Wait and retry, or use /gemini instead';
170
+ case 'rate_limit': return 'Wait and retry, or use /gemini-review instead';
209
171
  case 'auth_error': return 'Run `codex login` to authenticate';
210
- case 'cli_not_found': return 'Install with: npm install -g @openai/codex';
172
+ case 'cli_not_found': return 'Install with: npm install -g @openai/codex-cli';
211
173
  default: return 'Check the error message and try again';
212
174
  }
213
175
  }
@@ -5,13 +5,12 @@
5
5
  * Returns raw text — no JSON parsing or schema enforcement.
6
6
  * CC handles interpretation of the reviewer's response.
7
7
  */
8
- import { ReviewerAdapter, ReviewerCapabilities, ReviewRequest, ReviewResult, PeerRequest, PeerResult } from './base.js';
8
+ import { ReviewerAdapter, ReviewerCapabilities, ReviewRequest, ReviewResult } from './base.js';
9
9
  export declare class GeminiAdapter implements ReviewerAdapter {
10
10
  readonly id = "gemini";
11
11
  getCapabilities(): ReviewerCapabilities;
12
12
  isAvailable(): Promise<boolean>;
13
13
  runReview(request: ReviewRequest): Promise<ReviewResult>;
14
- runPeerRequest(request: PeerRequest): Promise<PeerResult>;
15
14
  private runCli;
16
15
  private handleException;
17
16
  private categorizeError;
@@ -10,7 +10,7 @@ import { existsSync } from 'fs';
10
10
  import { registerAdapter, } from './base.js';
11
11
  import { CliExecutor } from '../executor.js';
12
12
  import { GeminiEventDecoder } from '../decoders/index.js';
13
- import { buildSimpleHandoff, buildHandoffPrompt, buildPeerPrompt, selectRole, } from '../handoff.js';
13
+ import { buildSimpleHandoff, buildHandoffPrompt, selectRole, } from '../handoff.js';
14
14
  // =============================================================================
15
15
  // CONFIGURATION
16
16
  // =============================================================================
@@ -67,46 +67,7 @@ export class GeminiAdapter {
67
67
  return {
68
68
  success: false,
69
69
  error: { type: 'cli_error', message: 'Gemini returned empty response' },
70
- suggestion: 'Try again or use /codex instead',
71
- executionTimeMs: Date.now() - startTime,
72
- };
73
- }
74
- return { success: true, output: result.stdout, executionTimeMs: Date.now() - startTime };
75
- }
76
- catch (error) {
77
- return this.handleException(error, startTime);
78
- }
79
- }
80
- async runPeerRequest(request) {
81
- const startTime = Date.now();
82
- if (!existsSync(request.workingDir)) {
83
- return {
84
- success: false,
85
- error: { type: 'cli_error', message: `Working directory does not exist: ${request.workingDir}` },
86
- suggestion: 'Check that the working directory path is correct',
87
- executionTimeMs: Date.now() - startTime,
88
- };
89
- }
90
- try {
91
- const prompt = buildPeerPrompt({
92
- workingDir: request.workingDir,
93
- prompt: request.prompt,
94
- taskType: request.taskType,
95
- relevantFiles: request.relevantFiles,
96
- context: request.context,
97
- focusAreas: request.focusAreas,
98
- customInstructions: request.customPrompt,
99
- });
100
- const result = await this.runCli(prompt, request.workingDir);
101
- if (result.exitCode !== 0) {
102
- const error = this.categorizeError(result.stderr);
103
- return { success: false, error, suggestion: this.getSuggestion(error), executionTimeMs: Date.now() - startTime };
104
- }
105
- if (!result.stdout.trim()) {
106
- return {
107
- success: false,
108
- error: { type: 'cli_error', message: 'Gemini returned empty response' },
109
- suggestion: 'Try again or use /ask-codex instead',
70
+ suggestion: 'Try again or use /codex-review instead',
110
71
  executionTimeMs: Date.now() - startTime,
111
72
  };
112
73
  }
@@ -118,7 +79,8 @@ export class GeminiAdapter {
118
79
  }
119
80
  async runCli(prompt, workingDir) {
120
81
  const args = [
121
- '--yolo',
82
+ '--sandbox',
83
+ '--approval-mode', 'plan',
122
84
  '--output-format', 'stream-json',
123
85
  '--include-directories', workingDir,
124
86
  '-p', '',
@@ -162,7 +124,7 @@ export class GeminiAdapter {
162
124
  }
163
125
  if (err.message === 'TIMEOUT') {
164
126
  return { success: false, error: { type: 'timeout', message: 'Gemini timed out — no events received' },
165
- suggestion: 'Try a smaller scope or use /codex', executionTimeMs: Date.now() - startTime };
127
+ suggestion: 'Try a smaller scope or use /codex-review', executionTimeMs: Date.now() - startTime };
166
128
  }
167
129
  if (err.message === 'MAX_TIMEOUT') {
168
130
  return { success: false, error: { type: 'timeout', message: 'Task exceeded 60 minute maximum' },
@@ -182,7 +144,7 @@ export class GeminiAdapter {
182
144
  }
183
145
  getSuggestion(error) {
184
146
  switch (error.type) {
185
- case 'rate_limit': return 'Wait and retry, or use /codex instead';
147
+ case 'rate_limit': return 'Wait and retry, or use /codex-review instead';
186
148
  case 'auth_error': return 'Run `gemini` and follow auth prompts, or set GEMINI_API_KEY';
187
149
  case 'cli_not_found': return 'Install with: npm install -g @google/gemini-cli';
188
150
  default: return 'Check the error message and try again';
@@ -1,13 +1,12 @@
1
1
  /**
2
2
  * Shared module for slash command installation
3
3
  *
4
- * Used by both:
5
- * - setup.ts (manual CLI tool: npx cc-reviewer-setup)
6
- * - index.ts (auto-install on MCP server startup)
4
+ * Used by index.ts (auto-install on MCP server startup and `update` subcommand)
7
5
  */
8
6
  export interface InstallResult {
9
7
  success: boolean;
10
8
  installed: string[];
9
+ removed: string[];
11
10
  error?: string;
12
11
  }
13
12
  /**
package/dist/commands.js CHANGED
@@ -1,16 +1,24 @@
1
1
  /**
2
2
  * Shared module for slash command installation
3
3
  *
4
- * Used by both:
5
- * - setup.ts (manual CLI tool: npx cc-reviewer-setup)
6
- * - index.ts (auto-install on MCP server startup)
4
+ * Used by index.ts (auto-install on MCP server startup and `update` subcommand)
7
5
  */
8
- import { existsSync, mkdirSync, copyFileSync, readdirSync, statSync } from 'fs';
6
+ import { existsSync, mkdirSync, copyFileSync, readdirSync, statSync, unlinkSync } from 'fs';
9
7
  import { join, dirname } from 'path';
10
8
  import { homedir } from 'os';
11
9
  import { fileURLToPath } from 'url';
12
10
  const __filename = fileURLToPath(import.meta.url);
13
11
  const __dirname = dirname(__filename);
12
+ /** Old command filenames that should be pruned on upgrade */
13
+ const DEPRECATED_COMMANDS = [
14
+ 'codex.md',
15
+ 'gemini.md',
16
+ 'multi.md',
17
+ 'codex-xhigh.md',
18
+ 'ask-codex.md',
19
+ 'ask-gemini.md',
20
+ 'ask-multi.md',
21
+ ];
14
22
  /**
15
23
  * Get source and target paths for command files
16
24
  */
@@ -29,13 +37,13 @@ export function installCommands() {
29
37
  const { source, target } = getCommandPaths();
30
38
  // Check source exists
31
39
  if (!existsSync(source)) {
32
- return { success: false, installed: [], error: 'Commands directory not found' };
40
+ return { success: false, installed: [], removed: [], error: 'Commands directory not found' };
33
41
  }
34
42
  // Create target directory, handle errors (not a dir, permission denied)
35
43
  try {
36
44
  if (existsSync(target)) {
37
45
  if (!statSync(target).isDirectory()) {
38
- return { success: false, installed: [], error: `${target} exists but is not a directory` };
46
+ return { success: false, installed: [], removed: [], error: `${target} exists but is not a directory` };
39
47
  }
40
48
  }
41
49
  else {
@@ -44,13 +52,27 @@ export function installCommands() {
44
52
  }
45
53
  catch (err) {
46
54
  const msg = err instanceof Error ? err.message : String(err);
47
- return { success: false, installed: [], error: `Cannot create target directory: ${msg}` };
55
+ return { success: false, installed: [], removed: [], error: `Cannot create target directory: ${msg}` };
48
56
  }
49
57
  const files = readdirSync(source).filter(f => f.endsWith('.md'));
50
58
  if (files.length === 0) {
51
- return { success: false, installed: [], error: 'No command files found' };
59
+ return { success: false, installed: [], removed: [], error: 'No command files found' };
52
60
  }
53
- // Copy files, handle errors
61
+ // Prune deprecated commands from target
62
+ const removed = [];
63
+ for (const oldFile of DEPRECATED_COMMANDS) {
64
+ const oldPath = join(target, oldFile);
65
+ if (existsSync(oldPath)) {
66
+ try {
67
+ unlinkSync(oldPath);
68
+ removed.push(oldFile.replace('.md', ''));
69
+ }
70
+ catch {
71
+ // Best-effort removal — don't fail the install
72
+ }
73
+ }
74
+ }
75
+ // Copy current files
54
76
  const installed = [];
55
77
  try {
56
78
  for (const file of files) {
@@ -60,7 +82,7 @@ export function installCommands() {
60
82
  }
61
83
  catch (err) {
62
84
  const msg = err instanceof Error ? err.message : String(err);
63
- return { success: false, installed, error: `Copy failed: ${msg}` };
85
+ return { success: false, installed, removed, error: `Copy failed: ${msg}` };
64
86
  }
65
- return { success: true, installed };
87
+ return { success: true, installed, removed };
66
88
  }
package/dist/handoff.d.ts CHANGED
@@ -229,17 +229,3 @@ export declare function buildSimpleHandoff(workingDir: string, ccOutput: string,
229
229
  * CC should call this to add its specific concerns
230
230
  */
231
231
  export declare function enhanceHandoff(handoff: Handoff, uncertainties?: Uncertainty[], questions?: Question[], decisions?: Decision[]): Handoff;
232
- export interface PeerPromptOptions {
233
- workingDir: string;
234
- prompt: string;
235
- taskType?: string;
236
- relevantFiles?: string[];
237
- context?: string;
238
- focusAreas?: FocusArea[];
239
- customInstructions?: string;
240
- }
241
- /**
242
- * Build a prompt for general-purpose peer assistance (not review).
243
- * No output format constraints — peer responds naturally, CC interprets.
244
- */
245
- export declare function buildPeerPrompt(options: PeerPromptOptions): string;
package/dist/handoff.js CHANGED
@@ -168,7 +168,9 @@ export function buildHandoffPrompt(options) {
168
168
 
169
169
  Review recent work in \`${handoff.workingDir}\`.
170
170
 
171
- **Summary:** ${handoff.summary}${handoff.confidence !== undefined && handoff.confidence < 0.9 ? `\n**CC Confidence:** ${Math.round(handoff.confidence * 100)}% — verify weak areas` : ''}`);
171
+ **Summary:** ${handoff.summary}${handoff.confidence !== undefined && handoff.confidence < 0.9 ? `\n**CC Confidence:** ${Math.round(handoff.confidence * 100)}% — verify weak areas` : ''}
172
+
173
+ **IMPORTANT: This is a READ-ONLY review. Do NOT create, modify, or delete any files. Only read files to verify claims.**`);
172
174
  // SECTION 3: CC'S UNCERTAINTIES
173
175
  if (handoff.uncertainties && handoff.uncertainties.length > 0) {
174
176
  sections.push(`## CC'S UNCERTAINTIES
@@ -227,35 +229,3 @@ export function enhanceHandoff(handoff, uncertainties, questions, decisions) {
227
229
  decisions: decisions || handoff.decisions,
228
230
  };
229
231
  }
230
- /**
231
- * Build a prompt for general-purpose peer assistance (not review).
232
- * No output format constraints — peer responds naturally, CC interprets.
233
- */
234
- export function buildPeerPrompt(options) {
235
- const { workingDir, prompt, taskType, relevantFiles, context, focusAreas, customInstructions } = options;
236
- const role = selectRole(focusAreas);
237
- const sections = [];
238
- // SECTION 1: ROLE
239
- sections.push(`# ROLE: ${role.name} — Peer Engineer
240
-
241
- ${role.systemPrompt}
242
- Be direct and actionable.`);
243
- // SECTION 2: TASK
244
- const taskLabel = taskType ? ` [${taskType.toUpperCase()}]` : '';
245
- sections.push(`## YOUR TASK${taskLabel}
246
-
247
- **Request:** ${prompt}${context ? `\n**Context:** ${context}` : ''}`);
248
- // SECTION 3: RELEVANT FILES
249
- if (relevantFiles && relevantFiles.length > 0) {
250
- sections.push(`## RELEVANT FILES\n${relevantFiles.map(f => `- \`${f}\``).join('\n')}`);
251
- }
252
- // SECTION 4: FOCUS AREAS
253
- if (focusAreas && focusAreas.length > 0) {
254
- sections.push(`## FOCUS AREAS\n\n${focusAreas.join(', ')}`);
255
- }
256
- // SECTION 5: CUSTOM INSTRUCTIONS
257
- if (customInstructions) {
258
- sections.push(`## ADDITIONAL INSTRUCTIONS\n\n${customInstructions}`);
259
- }
260
- return sections.join('\n\n');
261
- }
package/dist/index.d.ts CHANGED
@@ -13,6 +13,6 @@
13
13
  *
14
14
  * Usage:
15
15
  * - npx cc-reviewer # Run MCP server (normal usage)
16
- * - npx cc-reviewer --setup # Install slash commands only
16
+ * - npx cc-reviewer update # Install/update slash commands
17
17
  */
18
18
  import './adapters/index.js';
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 --setup # Install slash commands only
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
- // Handle --setup flag: install commands and exit
27
- if (process.argv.includes('--setup') || process.argv.includes('--commands')) {
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(`✓ Installed ${result.installed.length} slash commands: ${result.installed.join(', ')}`);
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: '2.0.0',
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: [{