codex-review-mcp 2.0.2 → 2.1.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.
@@ -34,6 +34,7 @@ export function buildPrompt({ diffText, context, focus, version, isStaticReview
34
34
  '- When project guidelines conflict with general best practices, prioritize the project guidelines',
35
35
  '- For accessibility audits: apply axe-core best practices and WCAG 2.1 Level AA guidelines',
36
36
  '- CRITICAL Z-INDEX WARNING: Be extremely cautious with z-index changes on modals, overlays, or components. Analyze the entire z-index hierarchy before suggesting changes. Flag any z-index modifications as HIGH RISK and verify they won\'t break stacking context upstream or downstream. Always check for existing z-index patterns in the codebase first.',
37
+ '- MATERIAL-UI/MUI SPACING: Use theme.spacing() for all margin, padding, and gap values instead of hardcoded px/rem/em values to avoid magic numbers (e.g., gap: theme.spacing(3) for 24px). Flag any hardcoded spacing values.',
37
38
  focusLine,
38
39
  '',
39
40
  'BEFORE making ANY suggestion, ask yourself:',
@@ -1,68 +1,20 @@
1
- import { Agent, run, tool } from '@openai/agents';
1
+ import { Agent, run } from '@openai/agents';
2
2
  import { debugLog } from '../util/debug.js';
3
- import { promises as fs } from 'node:fs';
4
- import { join } from 'node:path';
5
- import { z } from 'zod';
6
3
  export async function invokeAgent({ prompt, maxTokens, workspaceDir }) {
7
4
  const model = process.env.CODEX_MODEL || 'gpt-5-codex';
8
- const cwd = workspaceDir || process.cwd();
9
- // Allow configuring max turns via env var (default: 100)
10
- // Each tool call (read_file) counts as 1 turn
11
- // 100 allows agent to read many files if needed for thorough review
12
- const maxTurns = parseInt(process.env.CODEX_MAX_TURNS || '100', 10);
13
- // Tool: Read file from the codebase
14
- const readFileTool = tool({
15
- name: 'read_file',
16
- description: 'Read the contents of a file from the codebase to examine existing patterns, utilities, or configuration. Use this to check for existing code before suggesting changes.',
17
- parameters: z.object({
18
- path: z.string().describe('Relative path to the file from the repository root'),
19
- }),
20
- execute: async (params) => {
21
- try {
22
- // Basic path sandboxing to keep reads under cwd
23
- const requested = params.path.replace(/\\/g, '/');
24
- if (requested.includes('..')) {
25
- return 'Access denied: parent directory traversal is not allowed.';
26
- }
27
- const fullPath = join(cwd, requested);
28
- if (!fullPath.startsWith(cwd)) {
29
- return 'Access denied: path escapes workspace boundary.';
30
- }
31
- const content = await fs.readFile(fullPath, 'utf8');
32
- const MAX_RETURN = 50_000; // cap very large files
33
- const body = content.length > MAX_RETURN ? content.slice(0, MAX_RETURN) + '\n... [truncated]' : content;
34
- await debugLog(`Agent read file: ${params.path} (${content.length} chars)`);
35
- return `File: ${params.path}\n\n${body}`;
36
- }
37
- catch (error) {
38
- const errorMsg = `Unable to read ${params.path}: ${error.message}`;
39
- await debugLog(`Agent file read error: ${errorMsg}`);
40
- return errorMsg;
41
- }
42
- },
43
- });
44
5
  const agent = new Agent({
45
6
  name: 'Code Reviewer',
46
- instructions: 'You are a precise code-review agent. Follow the output contract exactly. Use minimal verbosity. When you need to examine existing code patterns, utilities, or configurations to provide accurate recommendations, use the read_file tool.',
7
+ instructions: 'You are a precise code-review agent. Follow the output contract exactly. Use minimal verbosity.',
47
8
  model,
48
- tools: [readFileTool],
49
9
  });
50
10
  try {
51
- const result = await run(agent, prompt, {
52
- maxTurns, // Configurable via CODEX_MAX_TURNS env var (default: 100)
53
- });
11
+ const result = await run(agent, prompt);
54
12
  const out = result.finalOutput ?? '';
55
- await debugLog(`Agent model=${model} maxTurns=${maxTurns} outputLen=${out.length}`);
13
+ await debugLog(`Agent model=${model} outputLen=${out.length}`);
56
14
  return out;
57
15
  }
58
16
  catch (error) {
59
17
  await debugLog(`Agent error: ${error?.message || String(error)}`);
60
- // If max turns exceeded, provide helpful error message
61
- if (error?.message?.includes('Max turns')) {
62
- throw new Error(`OpenAI API error: ${error.message}. ` +
63
- `The agent made too many tool calls (read_file). ` +
64
- `Current limit: ${maxTurns}. Increase with CODEX_MAX_TURNS env var.`);
65
- }
66
18
  throw new Error(`OpenAI API error: ${error?.message || 'Unknown error occurred'}`);
67
19
  }
68
20
  }
@@ -5,7 +5,6 @@ import { run } from '@openai/agents';
5
5
  vi.mock('@openai/agents', () => ({
6
6
  Agent: vi.fn().mockImplementation((config) => config),
7
7
  run: vi.fn(),
8
- tool: vi.fn().mockImplementation((config) => config),
9
8
  }));
10
9
  vi.mock('../util/debug', () => ({
11
10
  debugLog: vi.fn(),
@@ -75,26 +74,7 @@ describe('invokeAgent', () => {
75
74
  process.env.CODEX_MODEL = originalEnv;
76
75
  }
77
76
  });
78
- it('should create agent with read_file tool for examining codebase', async () => {
79
- vi.mocked(run).mockResolvedValue({
80
- finalOutput: '# Review',
81
- });
82
- await invokeAgent({
83
- prompt: 'Review this code',
84
- workspaceDir: '/test/workspace'
85
- });
86
- const { Agent, tool } = await import('@openai/agents');
87
- // Verify tool was created
88
- expect(tool).toHaveBeenCalledWith(expect.objectContaining({
89
- name: 'read_file',
90
- description: expect.stringContaining('examine existing patterns'),
91
- }));
92
- // Verify agent was created with tools
93
- expect(Agent).toHaveBeenCalledWith(expect.objectContaining({
94
- tools: expect.arrayContaining([expect.anything()]),
95
- }));
96
- });
97
- it('should pass workspaceDir to control file reading scope', async () => {
77
+ it('should pass workspaceDir parameter (for future use)', async () => {
98
78
  vi.mocked(run).mockResolvedValue({
99
79
  finalOutput: '# Review',
100
80
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-review-mcp",
3
- "version": "2.0.2",
3
+ "version": "2.1.1",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "build": "tsc",