cc-reviewer 1.5.3 → 1.8.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 CHANGED
@@ -11,7 +11,7 @@ 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`) are automatically installed.
14
+ The MCP tools and slash commands (`/codex`, `/gemini`, `/multi`, `/ask-codex`, `/ask-gemini`, `/ask-multi`) are automatically installed.
15
15
 
16
16
  **Manual command install** (if needed):
17
17
  ```bash
@@ -51,11 +51,16 @@ gemini # follow auth prompts
51
51
 
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
- **When to use:**
54
+ **Review tools** (external second-opinion on your work):
55
55
  - `/codex` or "review with codex" - Get external Codex review
56
56
  - `/gemini` or "review with gemini" - Get external Gemini review
57
57
  - `/multi` - Get parallel reviews from both CLIs
58
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
63
+
59
64
  **For regular reviews:** Just say "review" and Claude Code will use its native capabilities. These external tools are only invoked when explicitly requested.
60
65
 
61
66
  ## Slash Commands
@@ -63,14 +68,18 @@ These tools provide **external second-opinion reviews** from Codex and Gemini CL
63
68
  These commands are available after restart:
64
69
 
65
70
  ```bash
71
+ # Review tools
66
72
  /codex # Review with Codex
67
73
  /codex security # Focus on security
68
74
  /codex-xhigh # Codex with xhigh reasoning effort
69
-
70
75
  /gemini # Review with Gemini
71
76
  /gemini architecture # Focus on architecture
72
-
73
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
74
83
  ```
75
84
 
76
85
  ## How It Works
@@ -99,23 +108,33 @@ CC does work → User: /codex → External CLI reviews → CC synthesizes → Up
99
108
 
100
109
  ## MCP Tools
101
110
 
102
- The plugin exposes three MCP tools:
111
+ The plugin exposes six MCP tools:
103
112
 
104
113
  | Tool | Description |
105
114
  |------|-------------|
106
115
  | `codex_review` | Get Codex review (correctness, edge cases, performance) |
107
116
  | `gemini_review` | Get Gemini review (design patterns, scalability, tech debt) |
108
117
  | `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 |
109
121
 
110
122
  ## Output Format
111
123
 
112
- External CLIs return structured JSON feedback with:
124
+ **Review tools** return structured JSON feedback with:
113
125
  - **Findings**: Issues with severity, confidence, location, and suggestions
114
126
  - **Agreements**: Validations of CC's correct assessments
115
127
  - **Disagreements**: Challenges to CC's claims with corrections
116
128
  - **Alternatives**: Different approaches with tradeoffs
117
129
  - **Risk Assessment**: Overall risk level with top concerns
118
130
 
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
+
119
138
  ## Development
120
139
 
121
140
  ```bash
@@ -130,9 +149,18 @@ npm start # Run server
130
149
 
131
150
  ## Publishing
132
151
 
133
- Uses npm Trusted Publishing (OIDC, no tokens):
152
+ Release-based publish via npm Trusted Publishing (OIDC, no tokens needed).
153
+ CI triggers on GitHub Release, validates the tag matches `package.json`.
154
+
134
155
  ```bash
135
- gh workflow run publish.yml -f version=patch # or minor/major
156
+ # 1. Bump version in package.json
157
+ # 2. Rebuild and test
158
+ npm run build && npm test
159
+ # 3. Commit, tag, push, release
160
+ git add -A && git commit -m "v1.x.x"
161
+ git tag v1.x.x
162
+ git push && git push --tags
163
+ gh release create v1.x.x --title "v1.x.x" --generate-notes
136
164
  ```
137
165
 
138
166
  ## License
@@ -0,0 +1,35 @@
1
+ # Ask Codex
2
+
3
+ Ask OpenAI Codex CLI for help as a peer engineer.
4
+
5
+ ## Arguments
6
+ - `$ARGUMENTS` - Your question or request
7
+
8
+ ## Codex Strengths
9
+ - **Correctness**: Logic errors, edge cases, bugs
10
+ - **Performance**: Efficiency, complexity analysis
11
+ - **Security**: Vulnerability detection
12
+
13
+ ## Tool Invocation
14
+
15
+ Call `ask_codex` with:
16
+
17
+ ```json
18
+ {
19
+ "workingDir": "<current directory>",
20
+ "prompt": "<your question or request from $ARGUMENTS>",
21
+ "taskType": "<infer from request: plan|debug|explain|question|fix|explore|general>",
22
+ "relevantFiles": ["<files related to the question>"],
23
+ "context": "<any error messages or prior analysis>"
24
+ }
25
+ ```
26
+
27
+ ## After Receiving Response
28
+
29
+ 1. **Read the answer** and key points
30
+ 2. **Check file references** — verify they exist
31
+ 3. **Evaluate suggested actions** — do they make sense?
32
+ 4. **Apply your judgment** — you may disagree
33
+ 5. **Act on the suggestions** or ask follow-up questions
34
+
35
+ $ARGUMENTS
@@ -0,0 +1,35 @@
1
+ # Ask Gemini
2
+
3
+ Ask Google Gemini CLI for help as a peer engineer.
4
+
5
+ ## Arguments
6
+ - `$ARGUMENTS` - Your question or request
7
+
8
+ ## Gemini Strengths
9
+ - **Architecture**: Design patterns, structure
10
+ - **Scalability**: Load handling, bottlenecks
11
+ - **Maintainability**: Code clarity, tech debt
12
+
13
+ ## Tool Invocation
14
+
15
+ Call `ask_gemini` with:
16
+
17
+ ```json
18
+ {
19
+ "workingDir": "<current directory>",
20
+ "prompt": "<your question or request from $ARGUMENTS>",
21
+ "taskType": "<infer from request: plan|debug|explain|question|fix|explore|general>",
22
+ "relevantFiles": ["<files related to the question>"],
23
+ "context": "<any error messages or prior analysis>"
24
+ }
25
+ ```
26
+
27
+ ## After Receiving Response
28
+
29
+ 1. **Read the answer** and key points
30
+ 2. **Check file references** — verify they exist
31
+ 3. **Evaluate suggested actions** — do they make sense?
32
+ 4. **Apply your judgment** — you may disagree
33
+ 5. **Act on the suggestions** or ask follow-up questions
34
+
35
+ $ARGUMENTS
@@ -0,0 +1,38 @@
1
+ # Ask Multi
2
+
3
+ Ask both Codex and Gemini for help in parallel — get multiple perspectives.
4
+
5
+ ## Arguments
6
+ - `$ARGUMENTS` - Your question or request
7
+
8
+ ## When to Use
9
+
10
+ Use `/ask-multi` when you want perspectives from both models on the same question.
11
+
12
+ ## Tool Invocation
13
+
14
+ Call `ask_multi` with:
15
+
16
+ ```json
17
+ {
18
+ "workingDir": "<current directory>",
19
+ "prompt": "<your question or request from $ARGUMENTS>",
20
+ "taskType": "<infer from request: plan|debug|explain|question|fix|explore|general>",
21
+ "relevantFiles": ["<files related to the question>"],
22
+ "context": "<any error messages or prior analysis>"
23
+ }
24
+ ```
25
+
26
+ ## After Receiving Responses
27
+
28
+ You will receive separate responses from each model.
29
+
30
+ ### Synthesize
31
+
32
+ 1. **Find agreements** — both models say the same thing (higher confidence)
33
+ 2. **Identify conflicts** — they disagree (YOU decide who's right)
34
+ 3. **Note unique insights** — findings only one model provided
35
+ 4. **Verify file references** — check they exist
36
+ 5. **Make YOUR recommendation** — don't just relay, apply judgment
37
+
38
+ $ARGUMENTS
@@ -5,8 +5,8 @@
5
5
  * Makes it easy to add new models (Ollama, Azure, etc.) without
6
6
  * changing the core orchestration logic.
7
7
  */
8
- import { ReviewOutput } from '../schema.js';
9
- import { FocusArea, OutputType, ReasoningEffort } from '../types.js';
8
+ import { ReviewOutput, PeerOutput } from '../schema.js';
9
+ import { FocusArea, OutputType, ReasoningEffort, TaskType } from '../types.js';
10
10
  export interface ReviewerCapabilities {
11
11
  /** Display name for this reviewer */
12
12
  name: string;
@@ -43,6 +43,24 @@ export interface ReviewRequest {
43
43
  /** Expert role configuration (optional override) */
44
44
  expertRole?: ExpertRole;
45
45
  }
46
+ export interface PeerRequest {
47
+ /** Working directory containing the code */
48
+ workingDir: string;
49
+ /** The question or request from CC */
50
+ prompt: string;
51
+ /** Hint about the type of task */
52
+ taskType?: TaskType;
53
+ /** Files the peer should focus on */
54
+ relevantFiles?: string[];
55
+ /** Additional context (error messages, prior analysis) */
56
+ context?: string;
57
+ /** Areas to focus on */
58
+ focusAreas?: FocusArea[];
59
+ /** Custom instructions from the user */
60
+ customPrompt?: string;
61
+ /** Reasoning effort level (for models that support it) */
62
+ reasoningEffort?: ReasoningEffort;
63
+ }
46
64
  export interface ExpertRole {
47
65
  name: string;
48
66
  description: string;
@@ -74,6 +92,20 @@ export interface ReviewError {
74
92
  message: string;
75
93
  details?: Record<string, unknown>;
76
94
  }
95
+ export interface PeerSuccess {
96
+ success: true;
97
+ output: PeerOutput;
98
+ rawOutput?: string;
99
+ executionTimeMs: number;
100
+ }
101
+ export interface PeerFailure {
102
+ success: false;
103
+ error: ReviewError;
104
+ suggestion?: string;
105
+ rawOutput?: string;
106
+ executionTimeMs: number;
107
+ }
108
+ export type PeerResult = PeerSuccess | PeerFailure;
77
109
  /**
78
110
  * Base interface that all reviewer adapters must implement.
79
111
  * This allows easy addition of new AI CLIs without changing orchestration logic.
@@ -87,6 +119,8 @@ export interface ReviewerAdapter {
87
119
  isAvailable(): Promise<boolean>;
88
120
  /** Run a review and return structured output */
89
121
  runReview(request: ReviewRequest): Promise<ReviewResult>;
122
+ /** Run a general-purpose peer request and return structured output */
123
+ runPeerRequest(request: PeerRequest): Promise<PeerResult>;
90
124
  /**
91
125
  * Optional: Run peer review of another model's output
92
126
  * Future capability - not currently implemented by any adapter
@@ -4,13 +4,15 @@
4
4
  * Implements the ReviewerAdapter interface for OpenAI's Codex CLI.
5
5
  * Specializes in correctness, edge cases, and performance analysis.
6
6
  */
7
- import { ReviewerAdapter, ReviewerCapabilities, ReviewRequest, ReviewResult } from './base.js';
7
+ import { ReviewerAdapter, ReviewerCapabilities, ReviewRequest, ReviewResult, PeerRequest, PeerResult } from './base.js';
8
8
  export declare class CodexAdapter implements ReviewerAdapter {
9
9
  readonly id = "codex";
10
10
  getCapabilities(): ReviewerCapabilities;
11
11
  isAvailable(): Promise<boolean>;
12
12
  runReview(request: ReviewRequest): Promise<ReviewResult>;
13
13
  private runWithRetry;
14
+ runPeerRequest(request: PeerRequest): Promise<PeerResult>;
15
+ private runPeerWithRetry;
14
16
  private runCli;
15
17
  private categorizeError;
16
18
  private getSuggestion;
@@ -9,8 +9,8 @@ import { existsSync, writeFileSync, unlinkSync, mkdtempSync } from 'fs';
9
9
  import { tmpdir } from 'os';
10
10
  import { join } from 'path';
11
11
  import { registerAdapter, } from './base.js';
12
- import { parseReviewOutput, parseLegacyMarkdownOutput, getReviewOutputJsonSchema } from '../schema.js';
13
- import { buildSimpleHandoff, buildHandoffPrompt, selectRole, } from '../handoff.js';
12
+ import { parseReviewOutput, parseLegacyMarkdownOutput, getReviewOutputJsonSchema, getPeerOutputJsonSchema, parsePeerOutput } from '../schema.js';
13
+ import { buildSimpleHandoff, buildHandoffPrompt, buildPeerPrompt, selectRole, } from '../handoff.js';
14
14
  // =============================================================================
15
15
  // CONFIGURATION
16
16
  // =============================================================================
@@ -89,7 +89,7 @@ export class CodexAdapter {
89
89
  (previousOutput ? `\nPrevious output (for reference):\n${previousOutput.slice(0, 500)}...` : '');
90
90
  }
91
91
  // Run the CLI
92
- const result = await this.runCli(prompt, request.workingDir, request.reasoningEffort || 'high');
92
+ const result = await this.runCli(prompt, request.workingDir, request.reasoningEffort || 'high', getReviewOutputJsonSchema);
93
93
  // Handle CLI errors
94
94
  if (result.exitCode !== 0) {
95
95
  const error = this.categorizeError(result.stderr);
@@ -214,14 +214,105 @@ export class CodexAdapter {
214
214
  };
215
215
  }
216
216
  }
217
- runCli(prompt, workingDir, reasoningEffort) {
217
+ async runPeerRequest(request) {
218
+ const startTime = Date.now();
219
+ if (!existsSync(request.workingDir)) {
220
+ return {
221
+ success: false,
222
+ error: {
223
+ type: 'cli_error',
224
+ message: `Working directory does not exist: ${request.workingDir}`,
225
+ },
226
+ suggestion: 'Check that the working directory path is correct',
227
+ executionTimeMs: Date.now() - startTime,
228
+ };
229
+ }
230
+ return this.runPeerWithRetry(request, 0, startTime);
231
+ }
232
+ async runPeerWithRetry(request, attempt, startTime, previousError, previousOutput) {
233
+ try {
234
+ let prompt = buildPeerPrompt({
235
+ workingDir: request.workingDir,
236
+ prompt: request.prompt,
237
+ taskType: request.taskType,
238
+ relevantFiles: request.relevantFiles,
239
+ context: request.context,
240
+ focusAreas: request.focusAreas,
241
+ customInstructions: request.customPrompt,
242
+ outputFormat: 'json',
243
+ });
244
+ if (attempt > 0) {
245
+ prompt += `\n\n---\n\n# RETRY ATTEMPT ${attempt + 1}\n\n` +
246
+ `Previous output had issues: ${previousError}\n` +
247
+ `Please fix these issues and provide valid JSON output.\n` +
248
+ (previousOutput ? `\nPrevious output (for reference):\n${previousOutput.slice(0, 500)}...` : '');
249
+ }
250
+ const result = await this.runCli(prompt, request.workingDir, request.reasoningEffort || 'high', getPeerOutputJsonSchema);
251
+ if (result.exitCode !== 0) {
252
+ const error = this.categorizeError(result.stderr);
253
+ return {
254
+ success: false,
255
+ error,
256
+ suggestion: this.getSuggestion(error),
257
+ rawOutput: result.stderr,
258
+ executionTimeMs: Date.now() - startTime,
259
+ };
260
+ }
261
+ if (result.truncated) {
262
+ return {
263
+ success: false,
264
+ error: { type: 'cli_error', message: 'Output exceeded maximum buffer size (1MB)' },
265
+ suggestion: 'Try a more focused request',
266
+ executionTimeMs: Date.now() - startTime,
267
+ };
268
+ }
269
+ const output = parsePeerOutput(result.stdout);
270
+ if (!output) {
271
+ if (attempt < MAX_RETRIES) {
272
+ return this.runPeerWithRetry(request, attempt + 1, startTime, 'Output did not match expected JSON schema', result.stdout);
273
+ }
274
+ return {
275
+ success: false,
276
+ error: { type: 'parse_error', message: 'Failed to parse peer output after retries',
277
+ details: { rawOutput: result.stdout.slice(0, 1000) } },
278
+ suggestion: 'The model may not be following the output format.',
279
+ rawOutput: result.stdout,
280
+ executionTimeMs: Date.now() - startTime,
281
+ };
282
+ }
283
+ return {
284
+ success: true,
285
+ output,
286
+ rawOutput: result.stdout,
287
+ executionTimeMs: Date.now() - startTime,
288
+ };
289
+ }
290
+ catch (error) {
291
+ const err = error;
292
+ if (err.code === 'ENOENT') {
293
+ return { success: false, error: { type: 'cli_not_found', message: 'Codex CLI not found' },
294
+ suggestion: 'Install with: npm install -g @openai/codex', executionTimeMs: Date.now() - startTime };
295
+ }
296
+ if (err.message === 'TIMEOUT') {
297
+ return { success: false, error: { type: 'timeout', message: 'No output for 2 minutes' },
298
+ suggestion: 'Try a simpler request', executionTimeMs: Date.now() - startTime };
299
+ }
300
+ if (err.message === 'MAX_TIMEOUT') {
301
+ return { success: false, error: { type: 'timeout', message: 'Task exceeded 60 minute maximum' },
302
+ suggestion: 'Try a smaller scope', executionTimeMs: Date.now() - startTime };
303
+ }
304
+ return { success: false, error: { type: 'cli_error', message: err.message },
305
+ executionTimeMs: Date.now() - startTime };
306
+ }
307
+ }
308
+ runCli(prompt, workingDir, reasoningEffort, schemaGetter) {
218
309
  return new Promise((resolve, reject) => {
219
310
  // Create temp schema file for structured output
220
311
  let schemaFile = null;
221
312
  try {
222
313
  const tempDir = mkdtempSync(join(tmpdir(), 'codex-schema-'));
223
314
  schemaFile = join(tempDir, 'schema.json');
224
- const schema = getReviewOutputJsonSchema();
315
+ const schema = schemaGetter();
225
316
  writeFileSync(schemaFile, JSON.stringify(schema, null, 2), 'utf-8');
226
317
  }
227
318
  catch (err) {
@@ -4,13 +4,15 @@
4
4
  * Implements the ReviewerAdapter interface for Google's Gemini CLI.
5
5
  * Specializes in architecture, design patterns, and large-context analysis.
6
6
  */
7
- import { ReviewerAdapter, ReviewerCapabilities, ReviewRequest, ReviewResult } from './base.js';
7
+ import { ReviewerAdapter, ReviewerCapabilities, ReviewRequest, ReviewResult, PeerRequest, PeerResult } from './base.js';
8
8
  export declare class GeminiAdapter implements ReviewerAdapter {
9
9
  readonly id = "gemini";
10
10
  getCapabilities(): ReviewerCapabilities;
11
11
  isAvailable(): Promise<boolean>;
12
12
  runReview(request: ReviewRequest): Promise<ReviewResult>;
13
13
  private runWithRetry;
14
+ runPeerRequest(request: PeerRequest): Promise<PeerResult>;
15
+ private runPeerWithRetry;
14
16
  private runCli;
15
17
  private categorizeError;
16
18
  private getSuggestion;
@@ -7,8 +7,8 @@
7
7
  import { spawn } from 'child_process';
8
8
  import { existsSync } from 'fs';
9
9
  import { registerAdapter, } from './base.js';
10
- import { parseReviewOutput, parseLegacyMarkdownOutput } from '../schema.js';
11
- import { buildSimpleHandoff, buildHandoffPrompt, selectRole, } from '../handoff.js';
10
+ import { parseReviewOutput, parseLegacyMarkdownOutput, parsePeerOutput } from '../schema.js';
11
+ import { buildSimpleHandoff, buildHandoffPrompt, buildPeerPrompt, selectRole, } from '../handoff.js';
12
12
  // =============================================================================
13
13
  // CONFIGURATION
14
14
  // =============================================================================
@@ -212,6 +212,92 @@ export class GeminiAdapter {
212
212
  };
213
213
  }
214
214
  }
215
+ async runPeerRequest(request) {
216
+ const startTime = Date.now();
217
+ if (!existsSync(request.workingDir)) {
218
+ return {
219
+ success: false,
220
+ error: { type: 'cli_error', message: `Working directory does not exist: ${request.workingDir}` },
221
+ suggestion: 'Check that the working directory path is correct',
222
+ executionTimeMs: Date.now() - startTime,
223
+ };
224
+ }
225
+ return this.runPeerWithRetry(request, 0, startTime);
226
+ }
227
+ async runPeerWithRetry(request, attempt, startTime, previousError, previousOutput) {
228
+ try {
229
+ let prompt = buildPeerPrompt({
230
+ workingDir: request.workingDir,
231
+ prompt: request.prompt,
232
+ taskType: request.taskType,
233
+ relevantFiles: request.relevantFiles,
234
+ context: request.context,
235
+ focusAreas: request.focusAreas,
236
+ customInstructions: request.customPrompt,
237
+ outputFormat: 'json',
238
+ });
239
+ if (attempt > 0) {
240
+ prompt += `\n\n---\n\n# RETRY ATTEMPT ${attempt + 1}\n\n` +
241
+ `Previous output had issues: ${previousError}\n` +
242
+ `Please fix these issues and provide valid JSON output.\n` +
243
+ (previousOutput ? `\nPrevious output (for reference):\n${previousOutput.slice(0, 500)}...` : '');
244
+ }
245
+ const result = await this.runCli(prompt, request.workingDir);
246
+ if (result.exitCode !== 0) {
247
+ const error = this.categorizeError(result.stderr);
248
+ return {
249
+ success: false, error,
250
+ suggestion: this.getSuggestion(error),
251
+ rawOutput: result.stderr,
252
+ executionTimeMs: Date.now() - startTime,
253
+ };
254
+ }
255
+ if (result.truncated) {
256
+ return {
257
+ success: false,
258
+ error: { type: 'cli_error', message: 'Output exceeded maximum buffer size (1MB)' },
259
+ suggestion: 'Try a more focused request',
260
+ executionTimeMs: Date.now() - startTime,
261
+ };
262
+ }
263
+ const output = parsePeerOutput(result.stdout);
264
+ if (!output) {
265
+ if (attempt < MAX_RETRIES) {
266
+ return this.runPeerWithRetry(request, attempt + 1, startTime, 'Output did not match expected JSON schema', result.stdout);
267
+ }
268
+ return {
269
+ success: false,
270
+ error: { type: 'parse_error', message: 'Failed to parse peer output after retries',
271
+ details: { rawOutput: result.stdout.slice(0, 1000) } },
272
+ suggestion: 'The model may not be following the output format.',
273
+ rawOutput: result.stdout,
274
+ executionTimeMs: Date.now() - startTime,
275
+ };
276
+ }
277
+ return {
278
+ success: true, output,
279
+ rawOutput: result.stdout,
280
+ executionTimeMs: Date.now() - startTime,
281
+ };
282
+ }
283
+ catch (error) {
284
+ const err = error;
285
+ if (err.code === 'ENOENT') {
286
+ return { success: false, error: { type: 'cli_not_found', message: 'Gemini CLI not found' },
287
+ suggestion: 'Install with: npm install -g @google/gemini-cli', executionTimeMs: Date.now() - startTime };
288
+ }
289
+ if (err.message === 'TIMEOUT') {
290
+ return { success: false, error: { type: 'timeout', message: 'No output for 10 minutes' },
291
+ suggestion: 'Try a simpler request', executionTimeMs: Date.now() - startTime };
292
+ }
293
+ if (err.message === 'MAX_TIMEOUT') {
294
+ return { success: false, error: { type: 'timeout', message: 'Task exceeded 60 minute maximum' },
295
+ suggestion: 'Try a smaller scope', executionTimeMs: Date.now() - startTime };
296
+ }
297
+ return { success: false, error: { type: 'cli_error', message: err.message },
298
+ executionTimeMs: Date.now() - startTime };
299
+ }
300
+ }
215
301
  runCli(prompt, workingDir) {
216
302
  return new Promise((resolve, reject) => {
217
303
  // Gemini CLI uses --yolo for auto-approval, prompt passed via stdin
package/dist/handoff.d.ts CHANGED
@@ -230,3 +230,18 @@ export declare function buildSimpleHandoff(workingDir: string, ccOutput: string,
230
230
  * CC should call this to add its specific concerns
231
231
  */
232
232
  export declare function enhanceHandoff(handoff: Handoff, uncertainties?: Uncertainty[], questions?: Question[], decisions?: Decision[]): Handoff;
233
+ export interface PeerPromptOptions {
234
+ workingDir: string;
235
+ prompt: string;
236
+ taskType?: string;
237
+ relevantFiles?: string[];
238
+ context?: string;
239
+ focusAreas?: FocusArea[];
240
+ customInstructions?: string;
241
+ outputFormat: 'json';
242
+ }
243
+ /**
244
+ * Build a prompt for general-purpose peer assistance (not review).
245
+ * The peer acts as a collaborative coworker, not a critic.
246
+ */
247
+ export declare function buildPeerPrompt(options: PeerPromptOptions): string;