@maxanatsko/gemini-mcp-tool 2.3.2 → 3.0.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 +10 -5
- package/dist/backends/codex.d.ts +37 -0
- package/dist/backends/codex.d.ts.map +1 -0
- package/dist/backends/codex.js +413 -0
- package/dist/backends/codex.js.map +1 -0
- package/dist/backends/gemini.d.ts +16 -0
- package/dist/backends/gemini.d.ts.map +1 -0
- package/dist/backends/gemini.js +214 -0
- package/dist/backends/gemini.js.map +1 -0
- package/dist/backends/index.d.ts +8 -0
- package/dist/backends/index.d.ts.map +1 -0
- package/dist/backends/index.js +9 -0
- package/dist/backends/index.js.map +1 -0
- package/dist/backends/registry.d.ts +33 -0
- package/dist/backends/registry.d.ts.map +1 -0
- package/dist/backends/registry.js +80 -0
- package/dist/backends/registry.js.map +1 -0
- package/dist/backends/types.d.ts +61 -0
- package/dist/backends/types.d.ts.map +1 -0
- package/dist/backends/types.js +5 -0
- package/dist/backends/types.js.map +1 -0
- package/dist/constants.d.ts +66 -3
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +72 -3
- package/dist/constants.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/tools/ask-gemini.tool.js +1 -1
- package/dist/tools/ask-gemini.tool.js.map +1 -1
- package/dist/tools/ask.tool.d.ts +4 -0
- package/dist/tools/ask.tool.d.ts.map +1 -0
- package/dist/tools/ask.tool.js +107 -0
- package/dist/tools/ask.tool.js.map +1 -0
- package/dist/tools/brainstorm.tool.d.ts.map +1 -1
- package/dist/tools/brainstorm.tool.js +59 -19
- package/dist/tools/brainstorm.tool.js.map +1 -1
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +8 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/registry.d.ts +1 -1
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/review-code.tool.d.ts.map +1 -1
- package/dist/tools/review-code.tool.js +52 -16
- package/dist/tools/review-code.tool.js.map +1 -1
- package/dist/utils/askSessionManager.d.ts +59 -0
- package/dist/utils/askSessionManager.d.ts.map +1 -0
- package/dist/utils/askSessionManager.js +123 -0
- package/dist/utils/askSessionManager.js.map +1 -0
- package/dist/utils/brainstormSessionManager.d.ts +2 -2
- package/dist/utils/brainstormSessionManager.d.ts.map +1 -1
- package/dist/utils/brainstormSessionManager.js +12 -3
- package/dist/utils/brainstormSessionManager.js.map +1 -1
- package/dist/utils/changeModeParser.d.ts +1 -1
- package/dist/utils/changeModeParser.d.ts.map +1 -1
- package/dist/utils/changeModeParser.js +22 -8
- package/dist/utils/changeModeParser.js.map +1 -1
- package/dist/utils/reviewPromptBuilder.d.ts +1 -1
- package/dist/utils/reviewPromptBuilder.js +1 -1
- package/dist/utils/reviewResponseParser.d.ts +3 -3
- package/dist/utils/reviewResponseParser.d.ts.map +1 -1
- package/dist/utils/reviewResponseParser.js +11 -11
- package/dist/utils/reviewResponseParser.js.map +1 -1
- package/dist/utils/reviewSessionCache.d.ts +1 -1
- package/dist/utils/reviewSessionCache.d.ts.map +1 -1
- package/dist/utils/sessionManager.d.ts.map +1 -1
- package/dist/utils/sessionManager.js +5 -0
- package/dist/utils/sessionManager.js.map +1 -1
- package/dist/utils/sessionSchemas.d.ts +23 -6
- package/dist/utils/sessionSchemas.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
```
|
|
6
6
|
┌─────────────────────────────────────────────────────────────────┐
|
|
7
7
|
│ │
|
|
8
|
-
│ Model Context Protocol server for
|
|
8
|
+
│ Model Context Protocol server for Gemini CLI + Codex CLI │
|
|
9
9
|
│ │
|
|
10
10
|
│ Claude ──────────────── Gemini │
|
|
11
11
|
│ │
|
|
@@ -153,7 +153,8 @@ use gemini sandbox to install numpy
|
|
|
153
153
|
|
|
154
154
|
| Tool | Description |
|
|
155
155
|
|:-----|:------------|
|
|
156
|
-
| `ask
|
|
156
|
+
| `ask` | Query Gemini or Codex with `@` file references |
|
|
157
|
+
| `ask-gemini` | Backward-compatible alias for `ask` |
|
|
157
158
|
| `brainstorm` | Creative ideation with frameworks |
|
|
158
159
|
| `review-code` | Interactive code review sessions |
|
|
159
160
|
| `ping` | Connection test |
|
|
@@ -165,13 +166,17 @@ use gemini sandbox to install numpy
|
|
|
165
166
|
|
|
166
167
|
<br>
|
|
167
168
|
|
|
168
|
-
**ask-gemini
|
|
169
|
+
**ask** (or `ask-gemini`)
|
|
169
170
|
|
|
170
171
|
```
|
|
171
172
|
prompt Required Analysis request with @ syntax
|
|
172
|
-
|
|
173
|
-
|
|
173
|
+
backend Optional gemini (default) | codex
|
|
174
|
+
model Optional Backend-specific override
|
|
175
|
+
reasoningEffort Optional Codex-only: low|medium|high|xhigh
|
|
176
|
+
sandbox Optional Gemini sandbox / Codex workspace-write
|
|
177
|
+
sandboxMode Optional Codex-only: read-only|workspace-write|danger-full-access
|
|
174
178
|
session Optional Conversation continuity
|
|
179
|
+
includeHistory Optional Include previous rounds
|
|
175
180
|
changeMode Optional Structured edit suggestions
|
|
176
181
|
```
|
|
177
182
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex Backend - Executes prompts via OpenAI's Codex CLI
|
|
3
|
+
*
|
|
4
|
+
* Uses `codex exec` for non-interactive execution mode.
|
|
5
|
+
* Supports native session resume via thread_id from JSON output.
|
|
6
|
+
* Codex CLI does not support @file syntax, so files must be read and inlined.
|
|
7
|
+
*/
|
|
8
|
+
import { BackendExecutor, BackendConfig, BackendType, BackendResult } from './types.js';
|
|
9
|
+
export declare class CodexBackend implements BackendExecutor {
|
|
10
|
+
name: BackendType;
|
|
11
|
+
execute(prompt: string, config: BackendConfig, onProgress?: (output: string) => void): Promise<BackendResult>;
|
|
12
|
+
isAvailable(): Promise<boolean>;
|
|
13
|
+
getModels(): string[];
|
|
14
|
+
supportsFileRefs(): boolean;
|
|
15
|
+
getFileRefSyntax(): string;
|
|
16
|
+
private buildArgs;
|
|
17
|
+
/**
|
|
18
|
+
* Validate that a resolved path is within the allowed workspace
|
|
19
|
+
* Prevents path traversal attacks
|
|
20
|
+
*/
|
|
21
|
+
private isPathWithinWorkspace;
|
|
22
|
+
/**
|
|
23
|
+
* Translate @file references to inline content
|
|
24
|
+
* Codex doesn't support @ syntax, so we read files and include their content
|
|
25
|
+
* Handles paths with dots, slashes, dashes, underscores, and relative paths like @../src/file.ts
|
|
26
|
+
* Includes path traversal protection to prevent reading files outside workspace
|
|
27
|
+
*/
|
|
28
|
+
private translateFileRefs;
|
|
29
|
+
private applyChangeModeInstructions;
|
|
30
|
+
/**
|
|
31
|
+
* Parse JSONL output from Codex CLI
|
|
32
|
+
* Extracts thread_id from thread.started event and response text from message events
|
|
33
|
+
*/
|
|
34
|
+
private parseJsonOutput;
|
|
35
|
+
private executeCommand;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=codex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/backends/codex.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAUxF,qBAAa,YAAa,YAAW,eAAe;IAClD,IAAI,EAAE,WAAW,CAAW;IAEtB,OAAO,CACX,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,aAAa,EACrB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GACpC,OAAO,CAAC,aAAa,CAAC;IAuBnB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAQrC,SAAS,IAAI,MAAM,EAAE;IAUrB,gBAAgB,IAAI,OAAO;IAI3B,gBAAgB,IAAI,MAAM;IAI1B,OAAO,CAAC,SAAS;IAkDjB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;;;;OAKG;YACW,iBAAiB;IAmL/B,OAAO,CAAC,2BAA2B;IAwBnC;;;OAGG;IACH,OAAO,CAAC,eAAe;IAwEvB,OAAO,CAAC,cAAc;CA4EvB"}
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex Backend - Executes prompts via OpenAI's Codex CLI
|
|
3
|
+
*
|
|
4
|
+
* Uses `codex exec` for non-interactive execution mode.
|
|
5
|
+
* Supports native session resume via thread_id from JSON output.
|
|
6
|
+
* Codex CLI does not support @file syntax, so files must be read and inlined.
|
|
7
|
+
*/
|
|
8
|
+
import { spawn } from 'child_process';
|
|
9
|
+
import * as fs from 'fs/promises';
|
|
10
|
+
import { constants as fsConstants } from 'fs';
|
|
11
|
+
import * as path from 'path';
|
|
12
|
+
import { Logger } from '../utils/logger.js';
|
|
13
|
+
import { CODEX_CLI, CODEX_FILE_REF, CODEX_MODELS, ERROR_MESSAGES } from '../constants.js';
|
|
14
|
+
export class CodexBackend {
|
|
15
|
+
name = 'codex';
|
|
16
|
+
async execute(prompt, config, onProgress) {
|
|
17
|
+
// Translate @file references to inline content since Codex doesn't support them
|
|
18
|
+
const processedPrompt = await this.translateFileRefs(prompt, config.cwd);
|
|
19
|
+
// Apply changeMode instructions if enabled
|
|
20
|
+
const finalPrompt = config.changeMode
|
|
21
|
+
? this.applyChangeModeInstructions(processedPrompt)
|
|
22
|
+
: processedPrompt;
|
|
23
|
+
// Build args - use resume if we have an existing threadId
|
|
24
|
+
const args = this.buildArgs(config);
|
|
25
|
+
// Execute and parse JSON output
|
|
26
|
+
const result = await this.executeCommand(args, finalPrompt, onProgress, config.cwd);
|
|
27
|
+
return {
|
|
28
|
+
response: result.response,
|
|
29
|
+
backend: this.name,
|
|
30
|
+
model: config.model ?? CODEX_MODELS.DEFAULT,
|
|
31
|
+
codexThreadId: result.threadId,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
async isAvailable() {
|
|
35
|
+
return new Promise((resolve) => {
|
|
36
|
+
const child = spawn('which', ['codex'], { shell: true });
|
|
37
|
+
child.on('close', (code) => resolve(code === 0));
|
|
38
|
+
child.on('error', () => resolve(false));
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
getModels() {
|
|
42
|
+
return [
|
|
43
|
+
CODEX_MODELS.GPT_5_2_CODEX,
|
|
44
|
+
CODEX_MODELS.GPT_5_1_CODEX_MINI,
|
|
45
|
+
CODEX_MODELS.GPT_5_1_CODEX_MAX,
|
|
46
|
+
CODEX_MODELS.GPT_5_2,
|
|
47
|
+
CODEX_MODELS.GPT_5_1,
|
|
48
|
+
];
|
|
49
|
+
}
|
|
50
|
+
supportsFileRefs() {
|
|
51
|
+
return false; // Codex reads files directly, doesn't use @ syntax
|
|
52
|
+
}
|
|
53
|
+
getFileRefSyntax() {
|
|
54
|
+
return ''; // No file ref syntax
|
|
55
|
+
}
|
|
56
|
+
buildArgs(config) {
|
|
57
|
+
const args = [];
|
|
58
|
+
// Use resume command if we have an existing thread ID
|
|
59
|
+
// `codex resume <threadId>` is a separate top-level command, not a subcommand of exec
|
|
60
|
+
if (config.codexThreadId) {
|
|
61
|
+
args.push(CODEX_CLI.COMMANDS.RESUME, config.codexThreadId);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
args.push(CODEX_CLI.COMMANDS.EXEC);
|
|
65
|
+
}
|
|
66
|
+
if (config.model) {
|
|
67
|
+
args.push(CODEX_CLI.FLAGS.MODEL, config.model);
|
|
68
|
+
}
|
|
69
|
+
// Approval mode
|
|
70
|
+
if (config.approvalMode) {
|
|
71
|
+
args.push(CODEX_CLI.FLAGS.APPROVAL, config.approvalMode);
|
|
72
|
+
}
|
|
73
|
+
else if (config.fullAuto) {
|
|
74
|
+
args.push(CODEX_CLI.FLAGS.FULL_AUTO);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// Default to on-request for safety
|
|
78
|
+
args.push(CODEX_CLI.FLAGS.APPROVAL, CODEX_CLI.APPROVAL_MODES.ON_REQUEST);
|
|
79
|
+
}
|
|
80
|
+
// Sandbox mode
|
|
81
|
+
const sandboxMode = config.sandboxMode ??
|
|
82
|
+
(config.sandbox ? CODEX_CLI.SANDBOX_MODES.WORKSPACE_WRITE : CODEX_CLI.SANDBOX_MODES.READ_ONLY);
|
|
83
|
+
if (sandboxMode === CODEX_CLI.SANDBOX_MODES.FULL_ACCESS) {
|
|
84
|
+
Logger.warn('⚠️ SECURITY: Codex full filesystem access enabled (danger-full-access)');
|
|
85
|
+
}
|
|
86
|
+
args.push(CODEX_CLI.FLAGS.SANDBOX, sandboxMode);
|
|
87
|
+
// Reasoning effort (defaults to medium if not specified)
|
|
88
|
+
if (config.reasoningEffort) {
|
|
89
|
+
args.push(CODEX_CLI.FLAGS.REASONING_EFFORT, config.reasoningEffort);
|
|
90
|
+
}
|
|
91
|
+
// Enable JSON output to capture thread_id
|
|
92
|
+
args.push(CODEX_CLI.FLAGS.JSON);
|
|
93
|
+
// Read prompt from stdin
|
|
94
|
+
args.push(CODEX_CLI.FLAGS.STDIN);
|
|
95
|
+
return args;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Validate that a resolved path is within the allowed workspace
|
|
99
|
+
* Prevents path traversal attacks
|
|
100
|
+
*/
|
|
101
|
+
isPathWithinWorkspace(resolvedPath, workingDir) {
|
|
102
|
+
// Normalize both paths to handle any .. or . components
|
|
103
|
+
const normalizedPath = path.normalize(resolvedPath);
|
|
104
|
+
const normalizedWorkDir = path.normalize(workingDir);
|
|
105
|
+
// Check if the resolved path starts with the working directory
|
|
106
|
+
return normalizedPath.startsWith(normalizedWorkDir + path.sep) ||
|
|
107
|
+
normalizedPath === normalizedWorkDir;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Translate @file references to inline content
|
|
111
|
+
* Codex doesn't support @ syntax, so we read files and include their content
|
|
112
|
+
* Handles paths with dots, slashes, dashes, underscores, and relative paths like @../src/file.ts
|
|
113
|
+
* Includes path traversal protection to prevent reading files outside workspace
|
|
114
|
+
*/
|
|
115
|
+
async translateFileRefs(prompt, cwd) {
|
|
116
|
+
const workingDir = cwd || process.cwd();
|
|
117
|
+
const lexicalWorkDir = path.resolve(workingDir);
|
|
118
|
+
const canonicalWorkDir = await fs.realpath(workingDir).catch(() => lexicalWorkDir);
|
|
119
|
+
// Match @file references - handles:
|
|
120
|
+
// - Relative paths: @../src/file.ts, @./file.ts
|
|
121
|
+
// - Absolute paths: @/home/user/file.ts
|
|
122
|
+
// - Paths with special chars: @src/file-name.test.ts
|
|
123
|
+
// Stops at whitespace or another @ symbol
|
|
124
|
+
const fileRefs = prompt.match(/@(?:\.\.?\/)?[^\s@]+/g) || [];
|
|
125
|
+
if (fileRefs.length === 0) {
|
|
126
|
+
return prompt;
|
|
127
|
+
}
|
|
128
|
+
let translated = prompt;
|
|
129
|
+
const missingFiles = [];
|
|
130
|
+
const deniedFiles = [];
|
|
131
|
+
// Max file size: 10MB to prevent memory exhaustion
|
|
132
|
+
let totalInlinedBytes = 0;
|
|
133
|
+
const alreadyProcessedRefs = new Set();
|
|
134
|
+
const alreadyProcessedTargets = new Map();
|
|
135
|
+
for (const ref of fileRefs) {
|
|
136
|
+
const filePath = ref.substring(1); // Remove @ prefix
|
|
137
|
+
// Avoid re-reading/re-inlining the same @reference multiple times.
|
|
138
|
+
// Replace duplicates with a small pointer to the first inlined instance.
|
|
139
|
+
if (alreadyProcessedRefs.has(ref)) {
|
|
140
|
+
translated = translated.replace(ref, `\n--- Duplicate @reference: ${filePath} (see earlier in prompt) ---\n`);
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
alreadyProcessedRefs.add(ref);
|
|
144
|
+
const absolutePath = path.isAbsolute(filePath)
|
|
145
|
+
? filePath
|
|
146
|
+
: path.join(workingDir, filePath);
|
|
147
|
+
// Resolve for basic path normalization (does not follow symlinks)
|
|
148
|
+
const resolvedPath = path.resolve(absolutePath);
|
|
149
|
+
// Security check: Ensure path is within workspace
|
|
150
|
+
if (!this.isPathWithinWorkspace(resolvedPath, lexicalWorkDir)) {
|
|
151
|
+
deniedFiles.push(filePath);
|
|
152
|
+
Logger.warn(`Path traversal blocked for @reference: ${filePath} (resolved to ${resolvedPath})`);
|
|
153
|
+
translated = translated.replace(ref, `${ERROR_MESSAGES.ACCESS_DENIED_OUTSIDE_WORKSPACE} (${filePath})`);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
try {
|
|
158
|
+
await fs.access(absolutePath, fsConstants.F_OK);
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// Extra security: if file doesn't exist and path contains .., deny access.
|
|
162
|
+
// This prevents potential TOCTOU attacks where file is created after check.
|
|
163
|
+
if (filePath.includes('..')) {
|
|
164
|
+
deniedFiles.push(filePath);
|
|
165
|
+
Logger.warn(`Path traversal blocked for non-existent path with ..: ${filePath}`);
|
|
166
|
+
translated = translated.replace(ref, ERROR_MESSAGES.ACCESS_DENIED_PATH_TRAVERSAL);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
missingFiles.push(filePath);
|
|
170
|
+
Logger.warn(`File not found for @reference: ${filePath}`);
|
|
171
|
+
translated = translated.replace(ref, `${ERROR_MESSAGES.FILE_NOT_FOUND}: ${filePath}`);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
// Canonicalize to prevent parent-directory symlink traversal (e.g., workspace/subdir -> /etc)
|
|
175
|
+
const canonicalTargetPath = await fs.realpath(absolutePath);
|
|
176
|
+
const isSymlinkedPath = path.normalize(canonicalTargetPath) !== path.normalize(path.resolve(absolutePath));
|
|
177
|
+
if (!this.isPathWithinWorkspace(canonicalTargetPath, canonicalWorkDir)) {
|
|
178
|
+
deniedFiles.push(filePath);
|
|
179
|
+
Logger.warn(`Symlink traversal blocked for @reference: ${filePath} (realpath: ${canonicalTargetPath})`);
|
|
180
|
+
translated = translated.replace(ref, `${isSymlinkedPath ? ERROR_MESSAGES.ACCESS_DENIED_SYMLINK_OUTSIDE_WORKSPACE : ERROR_MESSAGES.ACCESS_DENIED_OUTSIDE_WORKSPACE} (${filePath})`);
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
if (alreadyProcessedTargets.has(canonicalTargetPath)) {
|
|
184
|
+
translated = translated.replace(ref, `\n--- Duplicate @reference: ${filePath} (see earlier in prompt) ---\n`);
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const stat = await fs.stat(canonicalTargetPath);
|
|
188
|
+
if (stat.isDirectory()) {
|
|
189
|
+
// For directories, list files but don't inline all content (bounded)
|
|
190
|
+
const fileNames = [];
|
|
191
|
+
let truncated = false;
|
|
192
|
+
const dir = await fs.opendir(canonicalTargetPath);
|
|
193
|
+
try {
|
|
194
|
+
while (true) {
|
|
195
|
+
const dirent = await dir.read();
|
|
196
|
+
if (!dirent)
|
|
197
|
+
break;
|
|
198
|
+
if (fileNames.length < CODEX_FILE_REF.MAX_DIR_ENTRIES) {
|
|
199
|
+
fileNames.push(dirent.name);
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
truncated = true;
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
finally {
|
|
207
|
+
await dir.close();
|
|
208
|
+
}
|
|
209
|
+
const suffix = truncated ? `, ... (showing first ${CODEX_FILE_REF.MAX_DIR_ENTRIES})` : '';
|
|
210
|
+
const directoryListing = `\n--- Directory: ${filePath} ---\nFiles: ${fileNames.join(', ')}${suffix}\n--- end directory ---\n`;
|
|
211
|
+
const listingBytes = Buffer.byteLength(directoryListing, 'utf8');
|
|
212
|
+
if (totalInlinedBytes + listingBytes > CODEX_FILE_REF.MAX_TOTAL_BYTES) {
|
|
213
|
+
Logger.warn(`Inline limit reached while listing directory: ${filePath}`);
|
|
214
|
+
translated = translated.replace(ref, `${ERROR_MESSAGES.INLINE_LIMIT_REACHED}: ${filePath}`);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
totalInlinedBytes += listingBytes;
|
|
218
|
+
alreadyProcessedTargets.set(canonicalTargetPath, directoryListing);
|
|
219
|
+
translated = translated.replace(ref, directoryListing);
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
// Check file size before reading
|
|
223
|
+
if (stat.size > CODEX_FILE_REF.MAX_FILE_BYTES) {
|
|
224
|
+
Logger.warn(`File too large for @reference: ${filePath} (${(stat.size / 1024 / 1024).toFixed(2)}MB > 10MB limit)`);
|
|
225
|
+
translated = translated.replace(ref, `${ERROR_MESSAGES.FILE_TOO_LARGE}: ${filePath} (${(stat.size / 1024 / 1024).toFixed(2)}MB exceeds 10MB limit)`);
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
if (totalInlinedBytes + stat.size > CODEX_FILE_REF.MAX_TOTAL_BYTES) {
|
|
229
|
+
Logger.warn(`Inline limit reached; skipping file: ${filePath} (${stat.size} bytes)`);
|
|
230
|
+
translated = translated.replace(ref, `${ERROR_MESSAGES.INLINE_LIMIT_REACHED}: ${filePath}`);
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
const content = await fs.readFile(canonicalTargetPath, 'utf-8');
|
|
234
|
+
const fileBlock = `\n--- File: ${filePath} ---\n${content}\n--- end file: ${filePath} ---\n`;
|
|
235
|
+
totalInlinedBytes += stat.size;
|
|
236
|
+
alreadyProcessedTargets.set(canonicalTargetPath, fileBlock);
|
|
237
|
+
translated = translated.replace(ref, fileBlock);
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
241
|
+
Logger.error(`Error reading file ${filePath}: ${errMsg}`);
|
|
242
|
+
translated = translated.replace(ref, `${ERROR_MESSAGES.ERROR_READING_FILE}: ${filePath}`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// Log warnings for security and missing files
|
|
246
|
+
if (deniedFiles.length > 0) {
|
|
247
|
+
Logger.warn(`Security: Blocked access to ${deniedFiles.length} file(s) outside workspace`);
|
|
248
|
+
}
|
|
249
|
+
if (missingFiles.length > 0) {
|
|
250
|
+
Logger.warn(`Missing file references: ${missingFiles.join(', ')}`);
|
|
251
|
+
}
|
|
252
|
+
return translated;
|
|
253
|
+
}
|
|
254
|
+
applyChangeModeInstructions(prompt) {
|
|
255
|
+
return `
|
|
256
|
+
[CHANGEMODE INSTRUCTIONS]
|
|
257
|
+
You are generating code modifications. Output changes in a structured format that can be applied programmatically.
|
|
258
|
+
|
|
259
|
+
OUTPUT FORMAT (follow exactly):
|
|
260
|
+
**FILE: [filename]:[line_number]**
|
|
261
|
+
\`\`\`
|
|
262
|
+
OLD:
|
|
263
|
+
[exact code to be replaced]
|
|
264
|
+
NEW:
|
|
265
|
+
[new code to insert]
|
|
266
|
+
\`\`\`
|
|
267
|
+
|
|
268
|
+
REQUIREMENTS:
|
|
269
|
+
1. The OLD section must match the file content EXACTLY
|
|
270
|
+
2. Include enough context to make the match unique
|
|
271
|
+
3. Provide complete, functional replacement code
|
|
272
|
+
|
|
273
|
+
USER REQUEST:
|
|
274
|
+
${prompt}
|
|
275
|
+
`;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Parse JSONL output from Codex CLI
|
|
279
|
+
* Extracts thread_id from thread.started event and response text from message events
|
|
280
|
+
*/
|
|
281
|
+
parseJsonOutput(jsonlOutput) {
|
|
282
|
+
const lines = jsonlOutput.trim().split('\n');
|
|
283
|
+
let threadId;
|
|
284
|
+
const responseChunks = [];
|
|
285
|
+
for (const line of lines) {
|
|
286
|
+
if (!line.trim())
|
|
287
|
+
continue;
|
|
288
|
+
try {
|
|
289
|
+
const event = JSON.parse(line);
|
|
290
|
+
// Extract thread_id from thread.started event
|
|
291
|
+
if (event.type === 'thread.started' && event.thread_id) {
|
|
292
|
+
threadId = event.thread_id;
|
|
293
|
+
Logger.debug(`Codex thread started: ${threadId}`);
|
|
294
|
+
}
|
|
295
|
+
// Extract response text from various event types
|
|
296
|
+
// Agent messages contain the actual response
|
|
297
|
+
if (event.type === 'item.agent_message' && event.content) {
|
|
298
|
+
responseChunks.push(event.content);
|
|
299
|
+
}
|
|
300
|
+
// Also check for message content in turn.completed
|
|
301
|
+
if (event.type === 'turn.completed' && event.output) {
|
|
302
|
+
if (typeof event.output === 'string') {
|
|
303
|
+
responseChunks.push(event.output);
|
|
304
|
+
}
|
|
305
|
+
else if (event.output.content) {
|
|
306
|
+
responseChunks.push(event.output.content);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// Handle item.message for direct message content
|
|
310
|
+
if (event.type === 'item.message' && event.content) {
|
|
311
|
+
if (Array.isArray(event.content)) {
|
|
312
|
+
for (const part of event.content) {
|
|
313
|
+
if (part.type === 'text' && part.text) {
|
|
314
|
+
responseChunks.push(part.text);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
else if (typeof event.content === 'string') {
|
|
319
|
+
responseChunks.push(event.content);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
catch (parseError) {
|
|
324
|
+
// Not all lines may be valid JSON, skip them
|
|
325
|
+
Logger.debug(`Skipping non-JSON line: ${line.substring(0, 50)}...`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// Join all response chunks
|
|
329
|
+
const response = responseChunks.join('\n').trim();
|
|
330
|
+
// If no response extracted from events, use raw output minus JSON structure
|
|
331
|
+
if (!response) {
|
|
332
|
+
Logger.warn('No structured response found in Codex JSON output, using raw text extraction');
|
|
333
|
+
// Try to extract any text content from the raw output
|
|
334
|
+
const textMatch = jsonlOutput.match(/"text"\s*:\s*"([^"]+)"/g);
|
|
335
|
+
if (textMatch) {
|
|
336
|
+
const extractedTexts = textMatch.map(m => {
|
|
337
|
+
const match = m.match(/"text"\s*:\s*"([^"]+)"/);
|
|
338
|
+
return match ? match[1] : '';
|
|
339
|
+
}).filter(Boolean);
|
|
340
|
+
return { response: extractedTexts.join('\n'), threadId };
|
|
341
|
+
}
|
|
342
|
+
return { response: jsonlOutput, threadId };
|
|
343
|
+
}
|
|
344
|
+
return { response, threadId };
|
|
345
|
+
}
|
|
346
|
+
executeCommand(args, prompt, onProgress, cwd) {
|
|
347
|
+
return new Promise((resolve, reject) => {
|
|
348
|
+
const startTime = Date.now();
|
|
349
|
+
Logger.commandExecution('codex', args, startTime);
|
|
350
|
+
const childProcess = spawn('codex', args, {
|
|
351
|
+
env: process.env,
|
|
352
|
+
shell: false,
|
|
353
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
354
|
+
cwd: cwd || process.cwd(),
|
|
355
|
+
});
|
|
356
|
+
// Write prompt to stdin
|
|
357
|
+
childProcess.stdin.write(prompt);
|
|
358
|
+
childProcess.stdin.end();
|
|
359
|
+
let stdout = '';
|
|
360
|
+
let stderr = '';
|
|
361
|
+
let isResolved = false;
|
|
362
|
+
childProcess.stdout.on('data', (data) => {
|
|
363
|
+
stdout += data.toString();
|
|
364
|
+
// For JSON output, try to parse and report progress from events
|
|
365
|
+
if (onProgress) {
|
|
366
|
+
const newLines = data.toString().split('\n');
|
|
367
|
+
for (const line of newLines) {
|
|
368
|
+
if (!line.trim())
|
|
369
|
+
continue;
|
|
370
|
+
try {
|
|
371
|
+
const event = JSON.parse(line);
|
|
372
|
+
// Report agent messages as progress
|
|
373
|
+
if (event.type === 'item.agent_message' && event.content) {
|
|
374
|
+
onProgress(event.content);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
catch {
|
|
378
|
+
// Skip non-JSON lines
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
childProcess.stderr.on('data', (data) => {
|
|
384
|
+
stderr += data.toString();
|
|
385
|
+
});
|
|
386
|
+
childProcess.on('error', (error) => {
|
|
387
|
+
if (!isResolved) {
|
|
388
|
+
isResolved = true;
|
|
389
|
+
Logger.error('Process error:', error);
|
|
390
|
+
reject(new Error(`Failed to spawn codex command: ${error.message}`));
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
childProcess.on('close', (code) => {
|
|
394
|
+
if (!isResolved) {
|
|
395
|
+
isResolved = true;
|
|
396
|
+
if (code === 0) {
|
|
397
|
+
Logger.commandComplete(startTime, code, stdout.length);
|
|
398
|
+
// Parse JSON output to extract thread_id and response
|
|
399
|
+
const result = this.parseJsonOutput(stdout);
|
|
400
|
+
resolve(result);
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
Logger.commandComplete(startTime, code);
|
|
404
|
+
Logger.error(`Codex failed with exit code ${code}`);
|
|
405
|
+
const errorMessage = stderr.trim() || 'Unknown error';
|
|
406
|
+
reject(new Error(`Codex command failed with exit code ${code}: ${errorMessage}`));
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
//# sourceMappingURL=codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/backends/codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini Backend - Executes prompts via Google's Gemini CLI
|
|
3
|
+
*/
|
|
4
|
+
import { BackendExecutor, BackendConfig, BackendType, BackendResult } from './types.js';
|
|
5
|
+
export declare class GeminiBackend implements BackendExecutor {
|
|
6
|
+
name: BackendType;
|
|
7
|
+
execute(prompt: string, config: BackendConfig, onProgress?: (output: string) => void): Promise<BackendResult>;
|
|
8
|
+
isAvailable(): Promise<boolean>;
|
|
9
|
+
getModels(): string[];
|
|
10
|
+
supportsFileRefs(): boolean;
|
|
11
|
+
getFileRefSyntax(): string;
|
|
12
|
+
private buildArgs;
|
|
13
|
+
private applyChangeModeInstructions;
|
|
14
|
+
private executeCommand;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=gemini.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/backends/gemini.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AASxF,qBAAa,aAAc,YAAW,eAAe;IACnD,IAAI,EAAE,WAAW,CAAY;IAEvB,OAAO,CACX,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,aAAa,EACrB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GACpC,OAAO,CAAC,aAAa,CAAC;IAmDnB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAQrC,SAAS,IAAI,MAAM,EAAE;IASrB,gBAAgB,IAAI,OAAO;IAI3B,gBAAgB,IAAI,MAAM;IAI1B,OAAO,CAAC,SAAS;IA4BjB,OAAO,CAAC,2BAA2B;IAiEnC,OAAO,CAAC,cAAc;CAgEvB"}
|