gemini-executor 0.1.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.
@@ -0,0 +1,309 @@
1
+ /**
2
+ * Gemini Executor SubAgent
3
+ *
4
+ * This is a specialized agent that executes Gemini CLI commands and returns results.
5
+ * It is invoked programmatically by Claude via the Task tool.
6
+ *
7
+ * Design Pattern: Universal SubAgent
8
+ * - Handles all Gemini CLI interactions
9
+ * - Provides error handling and retry logic
10
+ * - Sanitizes inputs for security
11
+ * - Isolates context from main conversation
12
+ */
13
+
14
+ import { exec } from 'child_process';
15
+ import { promisify } from 'util';
16
+ import * as path from 'path';
17
+ import * as fs from 'fs';
18
+
19
+ const execAsync = promisify(exec);
20
+
21
+ /**
22
+ * Configuration for Gemini CLI execution
23
+ */
24
+ interface GeminiConfig {
25
+ /** Path to Gemini CLI executable */
26
+ cliPath: string;
27
+ /** Default model to use */
28
+ defaultModel: string;
29
+ /** Maximum retries on failure */
30
+ maxRetries: number;
31
+ /** Timeout in milliseconds */
32
+ timeout: number;
33
+ /** Enable YOLO mode (auto-confirm) */
34
+ yolo: boolean;
35
+ }
36
+
37
+ /**
38
+ * Options for executing Gemini CLI
39
+ */
40
+ interface ExecutionOptions {
41
+ /** Query or prompt to send to Gemini */
42
+ query: string;
43
+ /** Specific model to use (overrides default) */
44
+ model?: string;
45
+ /** Output format: 'text', 'json', or 'stream-json' */
46
+ outputFormat?: 'text' | 'json' | 'stream-json';
47
+ /** File paths to include in the prompt */
48
+ files?: string[];
49
+ /** Working directory for file references */
50
+ workingDir?: string;
51
+ /** Enable interactive mode */
52
+ interactive?: boolean;
53
+ }
54
+
55
+ /**
56
+ * Result from Gemini CLI execution
57
+ */
58
+ interface ExecutionResult {
59
+ /** Success status */
60
+ success: boolean;
61
+ /** Output from Gemini */
62
+ output?: string;
63
+ /** Error message if failed */
64
+ error?: string;
65
+ /** Execution metadata */
66
+ metadata: {
67
+ model: string;
68
+ retries: number;
69
+ duration: number;
70
+ };
71
+ }
72
+
73
+ /**
74
+ * Default configuration
75
+ */
76
+ const DEFAULT_CONFIG: GeminiConfig = {
77
+ cliPath: '/opt/homebrew/bin/gemini',
78
+ defaultModel: 'gemini-2.0-flash',
79
+ maxRetries: 3,
80
+ timeout: 120000, // 2 minutes
81
+ yolo: true
82
+ };
83
+
84
+ /**
85
+ * Security: Sensitive file patterns to detect
86
+ */
87
+ const SENSITIVE_FILE_PATTERNS = [
88
+ /\.env$/,
89
+ /\.env\./,
90
+ /credentials\.json$/,
91
+ /secrets\.yaml$/,
92
+ /\.key$/,
93
+ /\.pem$/,
94
+ /id_rsa$/,
95
+ /\.ssh\//
96
+ ];
97
+
98
+ /**
99
+ * Check if a file path contains sensitive information
100
+ */
101
+ function isSensitiveFile(filePath: string): boolean {
102
+ return SENSITIVE_FILE_PATTERNS.some(pattern => pattern.test(filePath));
103
+ }
104
+
105
+ /**
106
+ * Sanitize user input to prevent command injection
107
+ */
108
+ function sanitizeInput(input: string): string {
109
+ // Remove or escape dangerous characters
110
+ return input
111
+ .replace(/[;&|`$()]/g, '')
112
+ .replace(/\\/g, '\\\\')
113
+ .replace(/"/g, '\\"');
114
+ }
115
+
116
+ /**
117
+ * Validate file paths to prevent directory traversal
118
+ */
119
+ function validateFilePath(filePath: string, workingDir?: string): string {
120
+ // Resolve to absolute path
121
+ const absolutePath = path.resolve(workingDir || process.cwd(), filePath);
122
+
123
+ // Check for directory traversal attempts
124
+ if (absolutePath.includes('..')) {
125
+ throw new Error(`Invalid file path: directory traversal detected in ${filePath}`);
126
+ }
127
+
128
+ // Check if file exists
129
+ if (!fs.existsSync(absolutePath)) {
130
+ throw new Error(`File not found: ${absolutePath}`);
131
+ }
132
+
133
+ // Check for sensitive files
134
+ if (isSensitiveFile(absolutePath)) {
135
+ console.warn(`⚠️ Warning: Potentially sensitive file detected: ${absolutePath}`);
136
+ // In production, you might want to require explicit confirmation
137
+ }
138
+
139
+ return absolutePath;
140
+ }
141
+
142
+ /**
143
+ * Build Gemini CLI command
144
+ */
145
+ function buildCommand(options: ExecutionOptions, config: GeminiConfig): string {
146
+ const parts: string[] = [config.cliPath];
147
+
148
+ // Add model flag if specified
149
+ if (options.model || config.defaultModel) {
150
+ parts.push('-m', options.model || config.defaultModel);
151
+ }
152
+
153
+ // Add output format flag
154
+ if (options.outputFormat && options.outputFormat !== 'text') {
155
+ parts.push('-o', options.outputFormat);
156
+ }
157
+
158
+ // Add YOLO flag for non-interactive mode
159
+ if (config.yolo && !options.interactive) {
160
+ parts.push('-y');
161
+ }
162
+
163
+ // Add interactive flag if requested
164
+ if (options.interactive) {
165
+ parts.push('-i');
166
+ }
167
+
168
+ // Add file references in the prompt (not as CLI args)
169
+ let query = sanitizeInput(options.query);
170
+ if (options.files && options.files.length > 0) {
171
+ const fileList = options.files
172
+ .map(f => validateFilePath(f, options.workingDir))
173
+ .join(', ');
174
+ query = `${query}\n\nFiles to analyze: ${fileList}`;
175
+ }
176
+
177
+ // Add the query (properly quoted)
178
+ parts.push(`"${query}"`);
179
+
180
+ return parts.join(' ');
181
+ }
182
+
183
+ /**
184
+ * Execute Gemini CLI with retry logic
185
+ */
186
+ async function executeWithRetry(
187
+ command: string,
188
+ config: GeminiConfig,
189
+ model: string,
190
+ attempt: number = 1
191
+ ): Promise<ExecutionResult> {
192
+ const startTime = Date.now();
193
+
194
+ try {
195
+ const { stdout, stderr } = await execAsync(command, {
196
+ timeout: config.timeout,
197
+ maxBuffer: 10 * 1024 * 1024 // 10MB buffer for large outputs
198
+ });
199
+
200
+ const duration = Date.now() - startTime;
201
+
202
+ if (stderr && !stdout) {
203
+ throw new Error(stderr);
204
+ }
205
+
206
+ return {
207
+ success: true,
208
+ output: stdout?.trim() || '',
209
+ metadata: {
210
+ model: model,
211
+ retries: attempt - 1,
212
+ duration
213
+ }
214
+ };
215
+ } catch (error: any) {
216
+ const duration = Date.now() - startTime;
217
+
218
+ // Check if we should retry
219
+ if (attempt < config.maxRetries) {
220
+ console.log(`Retry attempt ${attempt}/${config.maxRetries} after error: ${error.message}`);
221
+ await new Promise(resolve => setTimeout(resolve, 1000 * attempt)); // Exponential backoff
222
+ return executeWithRetry(command, config, model, attempt + 1);
223
+ }
224
+
225
+ return {
226
+ success: false,
227
+ error: error.message || 'Unknown error occurred',
228
+ metadata: {
229
+ model: model,
230
+ retries: attempt - 1,
231
+ duration
232
+ }
233
+ };
234
+ }
235
+ }
236
+
237
+ /**
238
+ * Main execution function for Gemini CLI
239
+ *
240
+ * This is the entry point called by Claude Code's Task tool.
241
+ *
242
+ * @param options Execution options
243
+ * @param config Optional configuration overrides
244
+ * @returns Execution result
245
+ */
246
+ export async function execute(
247
+ options: ExecutionOptions,
248
+ config: Partial<GeminiConfig> = {}
249
+ ): Promise<ExecutionResult> {
250
+ const finalConfig: GeminiConfig = { ...DEFAULT_CONFIG, ...config };
251
+
252
+ // Validate inputs
253
+ if (!options.query || options.query.trim().length === 0) {
254
+ return {
255
+ success: false,
256
+ error: 'Query cannot be empty',
257
+ metadata: {
258
+ model: finalConfig.defaultModel,
259
+ retries: 0,
260
+ duration: 0
261
+ }
262
+ };
263
+ }
264
+
265
+ // Build command
266
+ let command: string;
267
+ try {
268
+ command = buildCommand(options, finalConfig);
269
+ } catch (error: any) {
270
+ return {
271
+ success: false,
272
+ error: `Failed to build command: ${error.message}`,
273
+ metadata: {
274
+ model: finalConfig.defaultModel,
275
+ retries: 0,
276
+ duration: 0
277
+ }
278
+ };
279
+ }
280
+
281
+ console.log(`Executing Gemini CLI: ${command.substring(0, 100)}...`);
282
+
283
+ // Determine the actual model being used
284
+ const actualModel = options.model || finalConfig.defaultModel;
285
+
286
+ // Execute with retry logic
287
+ return executeWithRetry(command, finalConfig, actualModel);
288
+ }
289
+
290
+ /**
291
+ * Check if Gemini CLI is installed and accessible
292
+ */
293
+ export async function checkGeminiCLI(config: Partial<GeminiConfig> = {}): Promise<boolean> {
294
+ const finalConfig: GeminiConfig = { ...DEFAULT_CONFIG, ...config };
295
+
296
+ try {
297
+ await execAsync(`${finalConfig.cliPath} --version`);
298
+ return true;
299
+ } catch {
300
+ return false;
301
+ }
302
+ }
303
+
304
+ // Export types for external use
305
+ export type {
306
+ GeminiConfig,
307
+ ExecutionOptions,
308
+ ExecutionResult
309
+ };
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Gemini Executor SubAgent
3
+ *
4
+ * This is a specialized agent that executes Gemini CLI commands and returns results.
5
+ * It is invoked programmatically by Claude via the Task tool.
6
+ *
7
+ * Design Pattern: Universal SubAgent
8
+ * - Handles all Gemini CLI interactions
9
+ * - Provides error handling and retry logic
10
+ * - Sanitizes inputs for security
11
+ * - Isolates context from main conversation
12
+ */
13
+ /**
14
+ * Configuration for Gemini CLI execution
15
+ */
16
+ interface GeminiConfig {
17
+ /** Path to Gemini CLI executable */
18
+ cliPath: string;
19
+ /** Default model to use */
20
+ defaultModel: string;
21
+ /** Maximum retries on failure */
22
+ maxRetries: number;
23
+ /** Timeout in milliseconds */
24
+ timeout: number;
25
+ /** Enable YOLO mode (auto-confirm) */
26
+ yolo: boolean;
27
+ }
28
+ /**
29
+ * Options for executing Gemini CLI
30
+ */
31
+ interface ExecutionOptions {
32
+ /** Query or prompt to send to Gemini */
33
+ query: string;
34
+ /** Specific model to use (overrides default) */
35
+ model?: string;
36
+ /** Output format: 'text', 'json', or 'stream-json' */
37
+ outputFormat?: 'text' | 'json' | 'stream-json';
38
+ /** File paths to include in the prompt */
39
+ files?: string[];
40
+ /** Working directory for file references */
41
+ workingDir?: string;
42
+ /** Enable interactive mode */
43
+ interactive?: boolean;
44
+ }
45
+ /**
46
+ * Result from Gemini CLI execution
47
+ */
48
+ interface ExecutionResult {
49
+ /** Success status */
50
+ success: boolean;
51
+ /** Output from Gemini */
52
+ output?: string;
53
+ /** Error message if failed */
54
+ error?: string;
55
+ /** Execution metadata */
56
+ metadata: {
57
+ model: string;
58
+ retries: number;
59
+ duration: number;
60
+ };
61
+ }
62
+ /**
63
+ * Main execution function for Gemini CLI
64
+ *
65
+ * This is the entry point called by Claude Code's Task tool.
66
+ *
67
+ * @param options Execution options
68
+ * @param config Optional configuration overrides
69
+ * @returns Execution result
70
+ */
71
+ export declare function execute(options: ExecutionOptions, config?: Partial<GeminiConfig>): Promise<ExecutionResult>;
72
+ /**
73
+ * Check if Gemini CLI is installed and accessible
74
+ */
75
+ export declare function checkGeminiCLI(config?: Partial<GeminiConfig>): Promise<boolean>;
76
+ export type { GeminiConfig, ExecutionOptions, ExecutionResult };
77
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../agents/gemini-executor/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH;;GAEG;AACH,UAAU,YAAY;IACpB,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,UAAU,gBAAgB;IACxB,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;IAC/C,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,UAAU,eAAe;IACvB,qBAAqB;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,yBAAyB;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAsKD;;;;;;;;GAQG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,gBAAgB,EACzB,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM,GACjC,OAAO,CAAC,eAAe,CAAC,CAuC1B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASzF;AAGD,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,eAAe,EAChB,CAAC"}
@@ -0,0 +1,249 @@
1
+ "use strict";
2
+ /**
3
+ * Gemini Executor SubAgent
4
+ *
5
+ * This is a specialized agent that executes Gemini CLI commands and returns results.
6
+ * It is invoked programmatically by Claude via the Task tool.
7
+ *
8
+ * Design Pattern: Universal SubAgent
9
+ * - Handles all Gemini CLI interactions
10
+ * - Provides error handling and retry logic
11
+ * - Sanitizes inputs for security
12
+ * - Isolates context from main conversation
13
+ */
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.execute = execute;
49
+ exports.checkGeminiCLI = checkGeminiCLI;
50
+ const child_process_1 = require("child_process");
51
+ const util_1 = require("util");
52
+ const path = __importStar(require("path"));
53
+ const fs = __importStar(require("fs"));
54
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
55
+ /**
56
+ * Default configuration
57
+ */
58
+ const DEFAULT_CONFIG = {
59
+ cliPath: '/opt/homebrew/bin/gemini',
60
+ defaultModel: 'gemini-2.0-flash',
61
+ maxRetries: 3,
62
+ timeout: 120000, // 2 minutes
63
+ yolo: true
64
+ };
65
+ /**
66
+ * Security: Sensitive file patterns to detect
67
+ */
68
+ const SENSITIVE_FILE_PATTERNS = [
69
+ /\.env$/,
70
+ /\.env\./,
71
+ /credentials\.json$/,
72
+ /secrets\.yaml$/,
73
+ /\.key$/,
74
+ /\.pem$/,
75
+ /id_rsa$/,
76
+ /\.ssh\//
77
+ ];
78
+ /**
79
+ * Check if a file path contains sensitive information
80
+ */
81
+ function isSensitiveFile(filePath) {
82
+ return SENSITIVE_FILE_PATTERNS.some(pattern => pattern.test(filePath));
83
+ }
84
+ /**
85
+ * Sanitize user input to prevent command injection
86
+ */
87
+ function sanitizeInput(input) {
88
+ // Remove or escape dangerous characters
89
+ return input
90
+ .replace(/[;&|`$()]/g, '')
91
+ .replace(/\\/g, '\\\\')
92
+ .replace(/"/g, '\\"');
93
+ }
94
+ /**
95
+ * Validate file paths to prevent directory traversal
96
+ */
97
+ function validateFilePath(filePath, workingDir) {
98
+ // Resolve to absolute path
99
+ const absolutePath = path.resolve(workingDir || process.cwd(), filePath);
100
+ // Check for directory traversal attempts
101
+ if (absolutePath.includes('..')) {
102
+ throw new Error(`Invalid file path: directory traversal detected in ${filePath}`);
103
+ }
104
+ // Check if file exists
105
+ if (!fs.existsSync(absolutePath)) {
106
+ throw new Error(`File not found: ${absolutePath}`);
107
+ }
108
+ // Check for sensitive files
109
+ if (isSensitiveFile(absolutePath)) {
110
+ console.warn(`⚠️ Warning: Potentially sensitive file detected: ${absolutePath}`);
111
+ // In production, you might want to require explicit confirmation
112
+ }
113
+ return absolutePath;
114
+ }
115
+ /**
116
+ * Build Gemini CLI command
117
+ */
118
+ function buildCommand(options, config) {
119
+ const parts = [config.cliPath];
120
+ // Add model flag if specified
121
+ if (options.model || config.defaultModel) {
122
+ parts.push('-m', options.model || config.defaultModel);
123
+ }
124
+ // Add output format flag
125
+ if (options.outputFormat && options.outputFormat !== 'text') {
126
+ parts.push('-o', options.outputFormat);
127
+ }
128
+ // Add YOLO flag for non-interactive mode
129
+ if (config.yolo && !options.interactive) {
130
+ parts.push('-y');
131
+ }
132
+ // Add interactive flag if requested
133
+ if (options.interactive) {
134
+ parts.push('-i');
135
+ }
136
+ // Add file references in the prompt (not as CLI args)
137
+ let query = sanitizeInput(options.query);
138
+ if (options.files && options.files.length > 0) {
139
+ const fileList = options.files
140
+ .map(f => validateFilePath(f, options.workingDir))
141
+ .join(', ');
142
+ query = `${query}\n\nFiles to analyze: ${fileList}`;
143
+ }
144
+ // Add the query (properly quoted)
145
+ parts.push(`"${query}"`);
146
+ return parts.join(' ');
147
+ }
148
+ /**
149
+ * Execute Gemini CLI with retry logic
150
+ */
151
+ async function executeWithRetry(command, config, model, attempt = 1) {
152
+ const startTime = Date.now();
153
+ try {
154
+ const { stdout, stderr } = await execAsync(command, {
155
+ timeout: config.timeout,
156
+ maxBuffer: 10 * 1024 * 1024 // 10MB buffer for large outputs
157
+ });
158
+ const duration = Date.now() - startTime;
159
+ if (stderr && !stdout) {
160
+ throw new Error(stderr);
161
+ }
162
+ return {
163
+ success: true,
164
+ output: stdout?.trim() || '',
165
+ metadata: {
166
+ model: model,
167
+ retries: attempt - 1,
168
+ duration
169
+ }
170
+ };
171
+ }
172
+ catch (error) {
173
+ const duration = Date.now() - startTime;
174
+ // Check if we should retry
175
+ if (attempt < config.maxRetries) {
176
+ console.log(`Retry attempt ${attempt}/${config.maxRetries} after error: ${error.message}`);
177
+ await new Promise(resolve => setTimeout(resolve, 1000 * attempt)); // Exponential backoff
178
+ return executeWithRetry(command, config, model, attempt + 1);
179
+ }
180
+ return {
181
+ success: false,
182
+ error: error.message || 'Unknown error occurred',
183
+ metadata: {
184
+ model: model,
185
+ retries: attempt - 1,
186
+ duration
187
+ }
188
+ };
189
+ }
190
+ }
191
+ /**
192
+ * Main execution function for Gemini CLI
193
+ *
194
+ * This is the entry point called by Claude Code's Task tool.
195
+ *
196
+ * @param options Execution options
197
+ * @param config Optional configuration overrides
198
+ * @returns Execution result
199
+ */
200
+ async function execute(options, config = {}) {
201
+ const finalConfig = { ...DEFAULT_CONFIG, ...config };
202
+ // Validate inputs
203
+ if (!options.query || options.query.trim().length === 0) {
204
+ return {
205
+ success: false,
206
+ error: 'Query cannot be empty',
207
+ metadata: {
208
+ model: finalConfig.defaultModel,
209
+ retries: 0,
210
+ duration: 0
211
+ }
212
+ };
213
+ }
214
+ // Build command
215
+ let command;
216
+ try {
217
+ command = buildCommand(options, finalConfig);
218
+ }
219
+ catch (error) {
220
+ return {
221
+ success: false,
222
+ error: `Failed to build command: ${error.message}`,
223
+ metadata: {
224
+ model: finalConfig.defaultModel,
225
+ retries: 0,
226
+ duration: 0
227
+ }
228
+ };
229
+ }
230
+ console.log(`Executing Gemini CLI: ${command.substring(0, 100)}...`);
231
+ // Determine the actual model being used
232
+ const actualModel = options.model || finalConfig.defaultModel;
233
+ // Execute with retry logic
234
+ return executeWithRetry(command, finalConfig, actualModel);
235
+ }
236
+ /**
237
+ * Check if Gemini CLI is installed and accessible
238
+ */
239
+ async function checkGeminiCLI(config = {}) {
240
+ const finalConfig = { ...DEFAULT_CONFIG, ...config };
241
+ try {
242
+ await execAsync(`${finalConfig.cliPath} --version`);
243
+ return true;
244
+ }
245
+ catch {
246
+ return false;
247
+ }
248
+ }
249
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../agents/gemini-executor/index.ts"],"names":[],"mappings":"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"}