ai-cli-mcp 2.5.0 → 2.7.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/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # [2.7.0](https://github.com/mkXultra/claude-code-mcp/compare/v2.6.0...v2.7.0) (2026-03-01)
2
+
3
+
4
+ ### Features
5
+
6
+ * CLIラッパーとパーサーの追加(cli.run, cli.run.parse) ([330eacf](https://github.com/mkXultra/claude-code-mcp/commit/330eacf26e03484b389438522886448882f58289))
7
+
8
+ # [2.6.0](https://github.com/mkXultra/claude-code-mcp/compare/v2.5.0...v2.6.0) (2026-02-09)
9
+
10
+
11
+ ### Features
12
+
13
+ * update model support (gpt-5.3-codex, sonnet[1m], opusplan) and refactor README ([eb6574d](https://github.com/mkXultra/claude-code-mcp/commit/eb6574d3760269d4be96cd934bc03d94ccb3801f))
14
+
1
15
  # [2.5.0](https://github.com/mkXultra/claude-code-mcp/compare/v2.4.0...v2.5.0) (2026-01-24)
2
16
 
3
17
 
package/CONTRIBUTING.md CHANGED
@@ -38,6 +38,16 @@ npm run build
38
38
  npx @modelcontextprotocol/inspector node dist/server.js
39
39
  ```
40
40
 
41
+ ## CLI Direct Execution
42
+
43
+ Run AI CLI tools directly from the terminal (foreground, no MCP server):
44
+
45
+ ```bash
46
+ npm run -s cli.run -- --model sonnet --workFolder /tmp --prompt "hello"
47
+ ```
48
+
49
+ See [docs/development.md](docs/development.md#cli-direct-execution-clirun) for full options.
50
+
41
51
  ## Local Development with npm link
42
52
 
43
53
  ```bash
package/README.ja.md CHANGED
@@ -9,8 +9,6 @@ AI CLIツール(Claude, Codex, Gemini)をバックグラウンドプロセ
9
9
 
10
10
  Cursorなどのエディタが、複雑な手順を伴う編集や操作に苦戦していることに気づいたことはありませんか?このサーバーは、強力な統合 `run` ツールを提供し、複数のAIエージェントを活用してコーディングタスクをより効果的に処理できるようにします。
11
11
 
12
- <img src="assets/screenshot.png" width="300" alt="Screenshot">
13
-
14
12
  ## 概要
15
13
 
16
14
  このMCPサーバーは、LLMがAI CLIツールと対話するためのツールを提供します。MCPクライアントと統合することで、LLMは以下のことが可能になります:
@@ -19,8 +17,8 @@ Cursorなどのエディタが、複雑な手順を伴う編集や操作に苦
19
17
  - 自動承認モードでCodex CLIを実行(`--full-auto` を使用)
20
18
  - 自動承認モードでGemini CLIを実行(`-y` を使用)
21
19
  - 複数のAIモデルのサポート:
22
- - Claude (sonnet, opus, haiku)
23
- - Codex (gpt-5.2-codex, gpt-5.1-codex-mini, gpt-5.1-codex-max, など)
20
+ - Claude (sonnet, sonnet[1m], opus, opusplan, haiku)
21
+ - Codex (gpt-5.3-codex, gpt-5.2-codex, gpt-5.1-codex-mini, gpt-5.1-codex-max, など)
24
22
  - Gemini (gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview, gemini-3-flash-preview)
25
23
  - PID追跡によるバックグラウンドプロセスの管理
26
24
  - ツールからの構造化された出力の解析と返却
@@ -134,10 +132,10 @@ Claude CLI、Codex CLI、またはGemini CLIを使用してプロンプトを実
134
132
  - `workFolder` (string, 必須): CLIを実行する作業ディレクトリ。絶対パスである必要があります。
135
133
  - **モデル (Models):**
136
134
  - **Ultra エイリアス:** `claude-ultra`, `codex-ultra` (自動的に high-reasoning に設定), `gemini-ultra`
137
- - Claude: `sonnet`, `opus`, `haiku`
138
- - Codex: `gpt-5.2-codex`, `gpt-5.1-codex-mini`, `gpt-5.1-codex-max`, `gpt-5.2`, `gpt-5.1`, `gpt-5`
135
+ - Claude: `sonnet`, `sonnet[1m]`, `opus`, `opusplan`, `haiku`
136
+ - Codex: `gpt-5.3-codex`, `gpt-5.2-codex`, `gpt-5.1-codex-mini`, `gpt-5.1-codex-max`, `gpt-5.2`, `gpt-5.1`, `gpt-5`
139
137
  - Gemini: `gemini-2.5-pro`, `gemini-2.5-flash`, `gemini-3-pro-preview`, `gemini-3-flash-preview`
140
- - `reasoning_effort` (string, 任意): Codex専用。`model_reasoning_effort` を設定します(許容値: "low", "medium", "high")。
138
+ - `reasoning_effort` (string, 任意): Codex専用。`model_reasoning_effort` を設定します(許容値: "low", "medium", "high", "xhigh")。
141
139
  - `session_id` (string, 任意): 以前のセッションを再開するためのセッションID。対応モデル: haiku, sonnet, opus, gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview, gemini-3-flash-preview。
142
140
 
143
141
  ### `wait`
package/README.md CHANGED
@@ -11,8 +11,6 @@ An MCP (Model Context Protocol) server that allows running AI CLI tools (Claude,
11
11
 
12
12
  Did you notice that Cursor sometimes struggles with complex, multi-step edits or operations? This server, with its powerful unified `run` tool, enables multiple AI agents to handle your coding tasks more effectively.
13
13
 
14
- <img src="assets/screenshot.png" width="300" alt="Screenshot">
15
-
16
14
  ## Overview
17
15
 
18
16
  This MCP server provides tools that can be used by LLMs to interact with AI CLI tools. When integrated with MCP clients, it allows LLMs to:
@@ -20,7 +18,7 @@ This MCP server provides tools that can be used by LLMs to interact with AI CLI
20
18
  - Run Claude CLI with all permissions bypassed (using `--dangerously-skip-permissions`)
21
19
  - Execute Codex CLI with automatic approval mode (using `--full-auto`)
22
20
  - Execute Gemini CLI with automatic approval mode (using `-y`)
23
- - Support multiple AI models: Claude (sonnet, opus, haiku), Codex (gpt-5.2-codex, gpt-5.1-codex-mini, gpt-5.1-codex-max, gpt-5.2, gpt-5.1, gpt-5.1-codex, gpt-5-codex, gpt-5-codex-mini, gpt-5), and Gemini (gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview, gemini-3-flash-preview)
21
+ - Support multiple AI models: Claude (sonnet, sonnet[1m], opus, opusplan, haiku), Codex (gpt-5.3-codex, gpt-5.2-codex, gpt-5.1-codex-mini, gpt-5.1-codex-max, gpt-5.2, gpt-5.1, gpt-5.1-codex, gpt-5-codex, gpt-5-codex-mini, gpt-5), and Gemini (gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview, gemini-3-flash-preview)
24
22
  - Manage background processes with PID tracking
25
23
  - Parse and return structured outputs from both tools
26
24
 
@@ -133,10 +131,10 @@ Executes a prompt using Claude CLI, Codex CLI, or Gemini CLI. The appropriate CL
133
131
  - `workFolder` (string, required): The working directory for the CLI execution. Must be an absolute path.
134
132
  **Models:**
135
133
  - **Ultra Aliases:** `claude-ultra`, `codex-ultra` (defaults to high-reasoning), `gemini-ultra`
136
- - Claude: `sonnet`, `opus`, `haiku`
137
- - Codex: `gpt-5.2-codex`, `gpt-5.1-codex-mini`, `gpt-5.1-codex-max`, `gpt-5.2`, `gpt-5.1`, `gpt-5`
134
+ - Claude: `sonnet`, `sonnet[1m]`, `opus`, `opusplan`, `haiku`
135
+ - Codex: `gpt-5.3-codex`, `gpt-5.2-codex`, `gpt-5.1-codex-mini`, `gpt-5.1-codex-max`, `gpt-5.2`, `gpt-5.1`, `gpt-5`
138
136
  - Gemini: `gemini-2.5-pro`, `gemini-2.5-flash`, `gemini-3-pro-preview`, `gemini-3-flash-preview`
139
- - `reasoning_effort` (string, optional): Codex only. Sets `model_reasoning_effort` (allowed: "low", "medium", "high").
137
+ - `reasoning_effort` (string, optional): Codex only. Sets `model_reasoning_effort` (allowed: "low", "medium", "high", "xhigh").
140
138
  - `session_id` (string, optional): Optional session ID to resume a previous session. Supported for: haiku, sonnet, opus, gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview, gemini-3-flash-preview.
141
139
 
142
140
  ### `wait`
@@ -165,77 +163,6 @@ Terminates a running AI agent process by PID.
165
163
  **Arguments:**
166
164
  - `pid` (number, required): The process ID to terminate.
167
165
 
168
- ### Examples
169
-
170
- Here are some visual examples of the server in action:
171
-
172
- <img src="assets/claude_tool_git_example.png" alt="Claude Tool Git Example" width="50%">
173
-
174
- <img src="assets/additional_claude_screenshot.png" alt="Additional Claude Screenshot" width="50%">
175
-
176
- <img src="assets/cursor-screenshot.png" alt="Cursor Screenshot" width="50%">
177
-
178
- ### Fixing ESLint Setup
179
-
180
- Here's an example of using the Claude Code MCP tool to interactively fix an ESLint setup by deleting old configuration files and creating a new one:
181
-
182
- <img src="assets/eslint_example.png" alt="ESLint file operations example" width="50%">
183
-
184
- ### Listing Files Example
185
-
186
- Here's an example of the Claude Code tool listing files in a directory:
187
-
188
- <img src="assets/file_list_example.png" alt="File listing example" width="50%">
189
-
190
- ## Key Use Cases
191
-
192
- This server, through its unified `run` tool, unlocks a wide range of powerful capabilities by giving your AI direct access to both Claude and Codex CLI tools. Here are some examples of what you can achieve:
193
-
194
- 1. **Code Generation, Analysis & Refactoring:**
195
- - `"Generate a Python script to parse CSV data and output JSON."`
196
- - `"Analyze my_script.py for potential bugs and suggest improvements."`
197
-
198
- 2. **File System Operations (Create, Read, Edit, Manage):**
199
- - **Creating Files:** `"Your work folder is /Users/steipete/my_project\n\nCreate a new file named 'config.yml' in the 'app/settings' directory with the following content:\nport: 8080\ndatabase: main_db"`
200
- - **Editing Files:** `"Your work folder is /Users/steipete/my_project\n\nEdit file 'public/css/style.css': Add a new CSS rule at the end to make all 'h2' elements have a 'color: navy'."`
201
- - **Moving/Copying/Deleting:** `"Your work folder is /Users/steipete/my_project\n\nMove the file 'report.docx' from the 'drafts' folder to the 'final_reports' folder and rename it to 'Q1_Report_Final.docx'."`
202
-
203
- 3. **Version Control (Git):**
204
- - `"Your work folder is /Users/steipete/my_project\n\n1. Stage the file 'src/main.java'.\n2. Commit the changes with the message 'feat: Implement user authentication'.\n3. Push the commit to the 'develop' branch on origin."`
205
-
206
- 4. **Running Terminal Commands:**
207
- - `"Your work folder is /Users/steipete/my_project/frontend\n\nRun the command 'npm run build'."`
208
- - `"Open the URL https://developer.mozilla.org in my default web browser."`
209
-
210
- 5. **Web Search & Summarization:**
211
- - `"Search the web for 'benefits of server-side rendering' and provide a concise summary."`
212
-
213
- 6. **Complex Multi-Step Workflows:**
214
- - Automate version bumps, update changelogs, and tag releases: `"Your work folder is /Users/steipete/my_project\n\nFollow these steps: 1. Update the version in package.json to 2.5.0. 2. Add a new section to CHANGELOG.md for version 2.5.0 with the heading '### Added' and list 'New feature X'. 3. Stage package.json and CHANGELOG.md. 4. Commit with message 'release: version 2.5.0'. 5. Push the commit. 6. Create and push a git tag v2.5.0."`
215
-
216
- <img src="assets/multistep_example.png" alt="Complex multi-step operation example" width="50%">
217
-
218
- 7. **Repairing Files with Syntax Errors:**
219
- - `"Your work folder is /path/to/project\n\nThe file 'src/utils/parser.js' has syntax errors after a recent complex edit that broke its structure. Please analyze it, identify the syntax errors, and correct the file to make it valid JavaScript again, ensuring the original logic is preserved as much as possible."`
220
-
221
- 8. **Interacting with GitHub (e.g., Creating a Pull Request):**
222
- - `"Your work folder is /Users/steipete/my_project\n\nCreate a GitHub Pull Request in the repository 'owner/repo' from the 'feature-branch' to the 'main' branch. Title: 'feat: Implement new login flow'. Body: 'This PR adds a new and improved login experience for users.'"`
223
-
224
- 9. **Interacting with GitHub (e.g., Checking PR CI Status):**
225
- - `"Your work folder is /Users/steipete/my_project\n\nCheck the status of CI checks for Pull Request #42 in the GitHub repository 'owner/repo'. Report if they have passed, failed, or are still running."`
226
-
227
- ### Correcting GitHub Actions Workflow
228
-
229
- <img src="assets/github_actions_fix_example.png" alt="GitHub Actions workflow fix example" width="50%">
230
-
231
- ### Complex Multi-Step Operations
232
-
233
- This example illustrates the AI agent handling a more complex, multi-step task, such as preparing a release by creating a branch, updating multiple files (`package.json`, `CHANGELOG.md`), committing changes, and initiating a pull request, all within a single, coherent operation.
234
-
235
- <img src="assets/claude_code_multistep_example.png" alt="AI agent multi-step example" width="50%">
236
-
237
- **CRITICAL: Remember to provide Current Working Directory (CWD) context in your prompts for file system or git operations (e.g., `"Your work folder is /path/to/project\n\n...your command..."`).**
238
-
239
166
  ## Troubleshooting
240
167
 
241
168
  - **"Command not found" (claude-code-mcp):** If installed globally, ensure the npm global bin directory is in your system's PATH. If using `npx`, ensure `npx` itself is working.
@@ -244,76 +171,9 @@ This example illustrates the AI agent handling a more complex, multi-step task,
244
171
  - **JSON Errors from Server:** If `MCP_CLAUDE_DEBUG` is `true`, error messages or logs might interfere with MCP's JSON parsing. Set to `false` for normal operation.
245
172
  - **ESM/Import Errors:** Ensure you are using Node.js v20 or later.
246
173
 
247
- **For Developers: Local Setup & Contribution**
248
-
249
- If you want to develop or contribute to this server, or run it from a cloned repository for testing, please see our [Local Installation & Development Setup Guide](./docs/local_install.md).
250
-
251
- ## Testing
252
-
253
- The project includes comprehensive test suites:
254
-
255
- ```bash
256
- # Run all tests
257
- npm test
258
-
259
- # Run unit tests only
260
- npm run test:unit
261
-
262
- # Run e2e tests (with mocks)
263
- npm run test:e2e
264
-
265
- # Run e2e tests locally (requires Claude CLI)
266
- npm run test:e2e:local
267
-
268
- # Watch mode for development
269
- npm run test:watch
270
-
271
- # Coverage report
272
- npm run test:coverage
273
- ```
274
-
275
- For detailed testing documentation, see our [E2E Testing Guide](./docs/e2e-testing.md).
276
-
277
- ## Manual Testing with MCP Inspector
278
-
279
- You can manually test the MCP server using the Model Context Protocol Inspector:
280
-
281
- ```bash
282
- # Build the project first
283
- npm run build
284
-
285
- # Start the MCP Inspector with the server
286
- npx @modelcontextprotocol/inspector node dist/server.js
287
- ```
288
-
289
- This will open a web interface where you can:
290
- 1. View all available tools (`run`, `list_processes`, `get_result`, `kill_process`)
291
- 2. Test each tool with different parameters
292
- 3. Test different AI models including:
293
- - Claude models: `sonnet`, `opus`, `haiku`
294
- - Codex models: `gpt-5.2-codex`, `gpt-5.1-codex-mini`, `gpt-5.1-codex-max`, `gpt-5.2`, `gpt-5.1`, `gpt-5.1-codex`, `gpt-5-codex`, `gpt-5-codex-mini`, `gpt-5`
295
- - Gemini models: `gemini-2.5-pro`, `gemini-2.5-flash`, `gemini-3-pro-preview`, `gemini-3-flash-preview`
296
-
297
- Example test: Select the `run` tool and provide:
298
- - `prompt`: "What is 2+2?"
299
- - `workFolder`: "/tmp"
300
- - `model`: "gemini-2.5-flash"
301
-
302
- ## Configuration via Environment Variables
303
-
304
- The server's behavior can be customized using these environment variables:
305
-
306
- - `CLAUDE_CLI_PATH`: Absolute path to the Claude CLI executable.
307
- - Default: Checks `~/.claude/local/claude`, then falls back to `claude` (expecting it in PATH).
308
- - `MCP_CLAUDE_DEBUG`: Set to `true` for verbose debug logging from this MCP server. Default: `false`.
309
-
310
- These can be set in your shell environment or within the `env` block of your `mcp.json` server configuration (though the `env` block in `mcp.json` examples was removed for simplicity, it's still a valid way to set them for the server process if needed).
311
-
312
174
  ## Contributing
313
175
 
314
- Contributions are welcome! Please refer to the [Local Installation & Development Setup Guide](./docs/local_install.md) for details on setting up your environment.
315
-
316
- Submit issues and pull requests to the [GitHub repository](https://github.com/mkXultra/claude-code-mcp).
176
+ For development setup, testing, and contribution guidelines, see the [Development Guide](./docs/development.md).
317
177
 
318
178
  ## Advanced Configuration (Optional)
319
179
 
@@ -0,0 +1,278 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ // Mock dependencies
4
+ vi.mock('node:fs');
5
+ vi.mock('node:path', () => ({
6
+ resolve: vi.fn((...args) => args[args.length - 1]),
7
+ isAbsolute: vi.fn((p) => p.startsWith('/')),
8
+ }));
9
+ const mockExistsSync = vi.mocked(existsSync);
10
+ const mockReadFileSync = vi.mocked(readFileSync);
11
+ // Import after mocks
12
+ import { buildCliCommand, resolveModelAlias, getReasoningEffort, } from '../cli-builder.js';
13
+ const DEFAULT_CLI_PATHS = {
14
+ claude: '/usr/bin/claude',
15
+ codex: '/usr/bin/codex',
16
+ gemini: '/usr/bin/gemini',
17
+ };
18
+ describe('cli-builder', () => {
19
+ beforeEach(() => {
20
+ vi.clearAllMocks();
21
+ // By default, workFolder exists
22
+ mockExistsSync.mockReturnValue(true);
23
+ });
24
+ describe('resolveModelAlias', () => {
25
+ it('should resolve claude-ultra to opus', () => {
26
+ expect(resolveModelAlias('claude-ultra')).toBe('opus');
27
+ });
28
+ it('should resolve codex-ultra to gpt-5.3-codex', () => {
29
+ expect(resolveModelAlias('codex-ultra')).toBe('gpt-5.3-codex');
30
+ });
31
+ it('should resolve gemini-ultra to gemini-3-pro-preview', () => {
32
+ expect(resolveModelAlias('gemini-ultra')).toBe('gemini-3-pro-preview');
33
+ });
34
+ it('should pass through non-alias model names', () => {
35
+ expect(resolveModelAlias('sonnet')).toBe('sonnet');
36
+ expect(resolveModelAlias('gpt-5.2-codex')).toBe('gpt-5.2-codex');
37
+ });
38
+ it('should pass through empty string', () => {
39
+ expect(resolveModelAlias('')).toBe('');
40
+ });
41
+ });
42
+ describe('getReasoningEffort', () => {
43
+ it('should return empty string for non-string input', () => {
44
+ expect(getReasoningEffort('gpt-5.2', undefined)).toBe('');
45
+ expect(getReasoningEffort('gpt-5.2', null)).toBe('');
46
+ expect(getReasoningEffort('gpt-5.2', 123)).toBe('');
47
+ });
48
+ it('should return empty string for empty/whitespace input', () => {
49
+ expect(getReasoningEffort('gpt-5.2', '')).toBe('');
50
+ expect(getReasoningEffort('gpt-5.2', ' ')).toBe('');
51
+ });
52
+ it('should normalize to lowercase', () => {
53
+ expect(getReasoningEffort('gpt-5.2', 'HIGH')).toBe('high');
54
+ expect(getReasoningEffort('gpt-5.2', 'Low')).toBe('low');
55
+ });
56
+ it('should accept valid values', () => {
57
+ expect(getReasoningEffort('gpt-5.2', 'low')).toBe('low');
58
+ expect(getReasoningEffort('gpt-5.2', 'medium')).toBe('medium');
59
+ expect(getReasoningEffort('gpt-5.2', 'high')).toBe('high');
60
+ expect(getReasoningEffort('gpt-5.2', 'xhigh')).toBe('xhigh');
61
+ });
62
+ it('should throw for invalid reasoning effort value', () => {
63
+ expect(() => getReasoningEffort('gpt-5.2', 'ultra')).toThrow('Invalid reasoning_effort: ultra. Allowed values: low, medium, high, xhigh.');
64
+ });
65
+ it('should throw for non-codex models', () => {
66
+ expect(() => getReasoningEffort('sonnet', 'high')).toThrow('reasoning_effort is only supported for Codex models (gpt-*).');
67
+ });
68
+ });
69
+ describe('buildCliCommand', () => {
70
+ describe('validation', () => {
71
+ it('should throw when workFolder is missing', () => {
72
+ expect(() => buildCliCommand({
73
+ prompt: 'hello',
74
+ workFolder: '',
75
+ cliPaths: DEFAULT_CLI_PATHS,
76
+ })).toThrow('Missing or invalid required parameter: workFolder');
77
+ });
78
+ it('should throw when neither prompt nor prompt_file is provided', () => {
79
+ expect(() => buildCliCommand({
80
+ workFolder: '/tmp',
81
+ cliPaths: DEFAULT_CLI_PATHS,
82
+ })).toThrow('Either prompt or prompt_file must be provided');
83
+ });
84
+ it('should throw when both prompt and prompt_file are provided', () => {
85
+ expect(() => buildCliCommand({
86
+ prompt: 'hello',
87
+ prompt_file: '/tmp/prompt.txt',
88
+ workFolder: '/tmp',
89
+ cliPaths: DEFAULT_CLI_PATHS,
90
+ })).toThrow('Cannot specify both prompt and prompt_file');
91
+ });
92
+ it('should throw when prompt_file does not exist', () => {
93
+ mockExistsSync.mockImplementation((p) => {
94
+ if (p === '/tmp/nonexistent.txt')
95
+ return false;
96
+ return true; // workFolder exists
97
+ });
98
+ expect(() => buildCliCommand({
99
+ prompt_file: '/tmp/nonexistent.txt',
100
+ workFolder: '/tmp',
101
+ cliPaths: DEFAULT_CLI_PATHS,
102
+ })).toThrow('Prompt file does not exist');
103
+ });
104
+ it('should throw when workFolder does not exist', () => {
105
+ mockExistsSync.mockReturnValue(false);
106
+ expect(() => buildCliCommand({
107
+ prompt: 'hello',
108
+ workFolder: '/nonexistent',
109
+ cliPaths: DEFAULT_CLI_PATHS,
110
+ })).toThrow('Working folder does not exist');
111
+ });
112
+ it('should read prompt from file', () => {
113
+ mockExistsSync.mockReturnValue(true);
114
+ mockReadFileSync.mockReturnValue('prompt from file');
115
+ const cmd = buildCliCommand({
116
+ prompt_file: '/tmp/prompt.txt',
117
+ workFolder: '/tmp',
118
+ cliPaths: DEFAULT_CLI_PATHS,
119
+ });
120
+ expect(cmd.prompt).toBe('prompt from file');
121
+ });
122
+ });
123
+ describe('claude agent', () => {
124
+ it('should build claude command with default model', () => {
125
+ const cmd = buildCliCommand({
126
+ prompt: 'hello world',
127
+ workFolder: '/tmp',
128
+ cliPaths: DEFAULT_CLI_PATHS,
129
+ });
130
+ expect(cmd.agent).toBe('claude');
131
+ expect(cmd.cliPath).toBe('/usr/bin/claude');
132
+ expect(cmd.args).toEqual([
133
+ '--dangerously-skip-permissions',
134
+ '--output-format',
135
+ 'stream-json',
136
+ '--verbose',
137
+ '-p',
138
+ 'hello world',
139
+ ]);
140
+ expect(cmd.resolvedModel).toBe('');
141
+ });
142
+ it('should build claude command with model', () => {
143
+ const cmd = buildCliCommand({
144
+ prompt: 'test',
145
+ workFolder: '/tmp',
146
+ model: 'sonnet',
147
+ cliPaths: DEFAULT_CLI_PATHS,
148
+ });
149
+ expect(cmd.agent).toBe('claude');
150
+ expect(cmd.args).toContain('--model');
151
+ expect(cmd.args).toContain('sonnet');
152
+ expect(cmd.resolvedModel).toBe('sonnet');
153
+ });
154
+ it('should build claude command with session_id', () => {
155
+ const cmd = buildCliCommand({
156
+ prompt: 'test',
157
+ workFolder: '/tmp',
158
+ session_id: 'ses-123',
159
+ cliPaths: DEFAULT_CLI_PATHS,
160
+ });
161
+ expect(cmd.args).toContain('-r');
162
+ expect(cmd.args).toContain('ses-123');
163
+ });
164
+ it('should resolve claude-ultra alias to opus', () => {
165
+ const cmd = buildCliCommand({
166
+ prompt: 'test',
167
+ workFolder: '/tmp',
168
+ model: 'claude-ultra',
169
+ cliPaths: DEFAULT_CLI_PATHS,
170
+ });
171
+ expect(cmd.agent).toBe('claude');
172
+ expect(cmd.resolvedModel).toBe('opus');
173
+ expect(cmd.args).toContain('opus');
174
+ });
175
+ });
176
+ describe('codex agent', () => {
177
+ it('should build codex command', () => {
178
+ const cmd = buildCliCommand({
179
+ prompt: 'test',
180
+ workFolder: '/tmp',
181
+ model: 'gpt-5.2-codex',
182
+ cliPaths: DEFAULT_CLI_PATHS,
183
+ });
184
+ expect(cmd.agent).toBe('codex');
185
+ expect(cmd.cliPath).toBe('/usr/bin/codex');
186
+ expect(cmd.args).toContain('exec');
187
+ expect(cmd.args).toContain('--full-auto');
188
+ expect(cmd.args).toContain('--json');
189
+ expect(cmd.args).toContain('--model');
190
+ expect(cmd.args).toContain('gpt-5.2-codex');
191
+ });
192
+ it('should build codex command with session_id using exec resume', () => {
193
+ const cmd = buildCliCommand({
194
+ prompt: 'test',
195
+ workFolder: '/tmp',
196
+ model: 'gpt-5.2',
197
+ session_id: 'codex-ses-456',
198
+ cliPaths: DEFAULT_CLI_PATHS,
199
+ });
200
+ expect(cmd.args[0]).toBe('exec');
201
+ expect(cmd.args[1]).toBe('resume');
202
+ expect(cmd.args[2]).toBe('codex-ses-456');
203
+ });
204
+ it('should build codex command with reasoning_effort', () => {
205
+ const cmd = buildCliCommand({
206
+ prompt: 'test',
207
+ workFolder: '/tmp',
208
+ model: 'gpt-5.2-codex',
209
+ reasoning_effort: 'high',
210
+ cliPaths: DEFAULT_CLI_PATHS,
211
+ });
212
+ expect(cmd.args).toContain('-c');
213
+ expect(cmd.args).toContain('model_reasoning_effort=high');
214
+ });
215
+ it('should resolve codex-ultra and default to xhigh reasoning', () => {
216
+ const cmd = buildCliCommand({
217
+ prompt: 'test',
218
+ workFolder: '/tmp',
219
+ model: 'codex-ultra',
220
+ cliPaths: DEFAULT_CLI_PATHS,
221
+ });
222
+ expect(cmd.agent).toBe('codex');
223
+ expect(cmd.resolvedModel).toBe('gpt-5.3-codex');
224
+ expect(cmd.args).toContain('-c');
225
+ expect(cmd.args).toContain('model_reasoning_effort=xhigh');
226
+ });
227
+ it('should allow overriding reasoning_effort for codex-ultra', () => {
228
+ const cmd = buildCliCommand({
229
+ prompt: 'test',
230
+ workFolder: '/tmp',
231
+ model: 'codex-ultra',
232
+ reasoning_effort: 'low',
233
+ cliPaths: DEFAULT_CLI_PATHS,
234
+ });
235
+ expect(cmd.args).toContain('model_reasoning_effort=low');
236
+ expect(cmd.args).not.toContain('model_reasoning_effort=xhigh');
237
+ });
238
+ });
239
+ describe('gemini agent', () => {
240
+ it('should build gemini command', () => {
241
+ const cmd = buildCliCommand({
242
+ prompt: 'test',
243
+ workFolder: '/tmp',
244
+ model: 'gemini-2.5-pro',
245
+ cliPaths: DEFAULT_CLI_PATHS,
246
+ });
247
+ expect(cmd.agent).toBe('gemini');
248
+ expect(cmd.cliPath).toBe('/usr/bin/gemini');
249
+ expect(cmd.args).toContain('-y');
250
+ expect(cmd.args).toContain('--output-format');
251
+ expect(cmd.args).toContain('json');
252
+ expect(cmd.args).toContain('--model');
253
+ expect(cmd.args).toContain('gemini-2.5-pro');
254
+ });
255
+ it('should build gemini command with session_id', () => {
256
+ const cmd = buildCliCommand({
257
+ prompt: 'test',
258
+ workFolder: '/tmp',
259
+ model: 'gemini-2.5-pro',
260
+ session_id: 'gem-789',
261
+ cliPaths: DEFAULT_CLI_PATHS,
262
+ });
263
+ expect(cmd.args).toContain('-r');
264
+ expect(cmd.args).toContain('gem-789');
265
+ });
266
+ it('should resolve gemini-ultra alias', () => {
267
+ const cmd = buildCliCommand({
268
+ prompt: 'test',
269
+ workFolder: '/tmp',
270
+ model: 'gemini-ultra',
271
+ cliPaths: DEFAULT_CLI_PATHS,
272
+ });
273
+ expect(cmd.agent).toBe('gemini');
274
+ expect(cmd.resolvedModel).toBe('gemini-3-pro-preview');
275
+ });
276
+ });
277
+ });
278
+ });
@@ -652,7 +652,7 @@ describe('ClaudeCodeServer Unit Tests', () => {
652
652
  }
653
653
  });
654
654
  // Verify spawn was called with resolved model name
655
- expect(mockSpawn).toHaveBeenCalledWith(expect.any(String), expect.arrayContaining(['--model', 'claude-3-5-haiku-20241022']), expect.any(Object));
655
+ expect(mockSpawn).toHaveBeenCalledWith(expect.any(String), expect.arrayContaining(['--model', 'haiku']), expect.any(Object));
656
656
  // Verify PID is returned
657
657
  expect(result.content[0].text).toContain('"pid": 12345');
658
658
  });