0
# Services and Utilities
1
2
Comprehensive service layer providing file discovery, git operations, shell execution, chat recording, and system integration capabilities.
3
4
## Capabilities
5
6
### FileDiscoveryService
7
8
Service for discovering, filtering, and managing files within projects with support for ignore patterns and filtering options.
9
10
```typescript { .api }
11
/**
12
* File discovery and filtering service with ignore pattern support
13
*/
14
class FileDiscoveryService {
15
constructor(projectRoot?: string);
16
17
/**
18
* Filter file paths based on provided options
19
* @param filePaths - Array of file paths to filter
20
* @param options - Filtering options
21
* @returns Filtered array of file paths
22
*/
23
filterFiles(filePaths: string[], options?: FilterFilesOptions): string[];
24
25
/**
26
* Check if file should be ignored by git
27
* @param filePath - Path to check
28
* @returns True if file should be git ignored
29
*/
30
shouldGitIgnoreFile(filePath: string): boolean;
31
32
/**
33
* Check if file should be ignored by Gemini
34
* @param filePath - Path to check
35
* @returns True if file should be Gemini ignored
36
*/
37
shouldGeminiIgnoreFile(filePath: string): boolean;
38
39
/**
40
* Check if file should be ignored based on options
41
* @param filePath - Path to check
42
* @param options - Filtering options
43
* @returns True if file should be ignored
44
*/
45
shouldIgnoreFile(filePath: string, options?: FilterFilesOptions): boolean;
46
47
/**
48
* Get Gemini-specific ignore patterns
49
* @returns Array of ignore patterns
50
*/
51
getGeminiIgnorePatterns(): string[];
52
}
53
54
/**
55
* File filtering options
56
*/
57
interface FilterFilesOptions {
58
excludePatterns?: string[];
59
includePatterns?: string[];
60
maxFileSize?: number;
61
excludeHidden?: boolean;
62
respectGitIgnore?: boolean;
63
respectGeminiIgnore?: boolean;
64
fileTypes?: string[];
65
}
66
```
67
68
### Git Service
69
70
Service for git repository operations including status checking, commit operations, and repository information.
71
72
```typescript { .api }
73
/**
74
* Git repository operations service
75
*/
76
class GitService {
77
constructor(repositoryPath: string);
78
79
// Repository information
80
isGitRepository(): Promise<boolean>;
81
getCurrentBranch(): Promise<string>;
82
getRemoteUrl(): Promise<string | null>;
83
getRootPath(): Promise<string>;
84
85
// Status operations
86
getStatus(): Promise<GitStatus>;
87
getUnstagedFiles(): Promise<string[]>;
88
getStagedFiles(): Promise<string[]>;
89
getUntrackedFiles(): Promise<string[]>;
90
91
// File operations
92
addFiles(files: string[]): Promise<void>;
93
commitFiles(message: string, files?: string[]): Promise<string>;
94
95
// History operations
96
getCommitHistory(maxCount?: number): Promise<GitCommit[]>;
97
getFileHistory(filePath: string, maxCount?: number): Promise<GitCommit[]>;
98
99
// Diff operations
100
getDiff(ref1?: string, ref2?: string): Promise<string>;
101
getFileDiff(filePath: string, ref?: string): Promise<string>;
102
}
103
104
/**
105
* Git repository status
106
*/
107
interface GitStatus {
108
current: string | null;
109
tracking: string | null;
110
ahead: number;
111
behind: number;
112
staged: GitFileStatus[];
113
unstaged: GitFileStatus[];
114
untracked: string[];
115
}
116
117
/**
118
* Git file status
119
*/
120
interface GitFileStatus {
121
path: string;
122
index: string;
123
workingTree: string;
124
}
125
126
/**
127
* Git commit information
128
*/
129
interface GitCommit {
130
hash: string;
131
date: Date;
132
message: string;
133
author: GitAuthor;
134
refs: string[];
135
}
136
137
/**
138
* Git author information
139
*/
140
interface GitAuthor {
141
name: string;
142
email: string;
143
}
144
```
145
146
### Chat Recording Service
147
148
Service for recording, storing, and managing chat conversations and interactions.
149
150
```typescript { .api }
151
/**
152
* Service for recording and managing chat conversations
153
*/
154
class ChatRecordingService {
155
constructor(config: Config, storage: Storage);
156
157
// Recording management
158
startRecording(sessionId: string): Promise<void>;
159
stopRecording(): Promise<void>;
160
isRecording(): boolean;
161
162
// Message recording
163
recordUserMessage(message: string, timestamp?: Date): Promise<void>;
164
recordAssistantMessage(message: string, timestamp?: Date): Promise<void>;
165
recordSystemMessage(message: string, timestamp?: Date): Promise<void>;
166
167
// Tool call recording
168
recordToolCall(
169
toolName: string,
170
parameters: any,
171
result?: any,
172
timestamp?: Date
173
): Promise<void>;
174
175
// History management
176
getRecordedHistory(sessionId: string): Promise<ChatRecord[]>;
177
getAllSessions(): Promise<string[]>;
178
deleteSession(sessionId: string): Promise<boolean>;
179
180
// Export operations
181
exportSession(sessionId: string, format: 'json' | 'markdown'): Promise<string>;
182
exportAllSessions(format: 'json' | 'markdown'): Promise<string>;
183
}
184
185
/**
186
* Chat record entry
187
*/
188
interface ChatRecord {
189
id: string;
190
sessionId: string;
191
timestamp: Date;
192
type: 'user' | 'assistant' | 'system' | 'tool_call';
193
content: string;
194
metadata?: any;
195
}
196
```
197
198
### File System Service
199
200
Abstract file system service interface with concrete implementations for different environments.
201
202
```typescript { .api }
203
/**
204
* Abstract file system service interface
205
*/
206
abstract class FileSystemService {
207
// File operations
208
abstract readFile(path: string): Promise<string>;
209
abstract writeFile(path: string, content: string): Promise<void>;
210
abstract appendFile(path: string, content: string): Promise<void>;
211
abstract deleteFile(path: string): Promise<void>;
212
213
// Directory operations
214
abstract readDir(path: string): Promise<string[]>;
215
abstract createDir(path: string, recursive?: boolean): Promise<void>;
216
abstract deleteDir(path: string, recursive?: boolean): Promise<void>;
217
218
// Path operations
219
abstract exists(path: string): Promise<boolean>;
220
abstract isFile(path: string): Promise<boolean>;
221
abstract isDirectory(path: string): Promise<boolean>;
222
abstract getStats(path: string): Promise<FileStats>;
223
224
// Utility operations
225
abstract copy(src: string, dest: string): Promise<void>;
226
abstract move(src: string, dest: string): Promise<void>;
227
abstract glob(pattern: string, options?: GlobOptions): Promise<string[]>;
228
}
229
230
/**
231
* Node.js file system service implementation
232
*/
233
class NodeFileSystemService extends FileSystemService {
234
constructor();
235
236
// Implements all FileSystemService abstract methods
237
readFile(path: string): Promise<string>;
238
writeFile(path: string, content: string): Promise<void>;
239
// ... other implementations
240
}
241
242
/**
243
* File statistics
244
*/
245
interface FileStats {
246
size: number;
247
created: Date;
248
modified: Date;
249
accessed: Date;
250
isFile: boolean;
251
isDirectory: boolean;
252
permissions: FilePermissions;
253
}
254
255
/**
256
* File permissions
257
*/
258
interface FilePermissions {
259
readable: boolean;
260
writable: boolean;
261
executable: boolean;
262
}
263
264
/**
265
* Glob options
266
*/
267
interface GlobOptions {
268
cwd?: string;
269
ignore?: string[];
270
dot?: boolean;
271
absolute?: boolean;
272
}
273
```
274
275
### Shell Execution Service
276
277
Service for executing shell commands and managing command execution environments.
278
279
```typescript { .api }
280
/**
281
* Service for executing shell commands and managing execution environments
282
*/
283
class ShellExecutionService {
284
constructor(config?: ShellExecutionConfig);
285
286
/**
287
* Execute a shell command
288
* @param command - Command to execute
289
* @param options - Execution options
290
* @returns Execution result
291
*/
292
execute(
293
command: string,
294
options?: ShellExecutionOptions
295
): Promise<ShellExecutionResult>;
296
297
/**
298
* Execute command with streaming output
299
* @param command - Command to execute
300
* @param options - Execution options
301
* @returns Async generator for streaming output
302
*/
303
executeStream(
304
command: string,
305
options?: ShellExecutionOptions
306
): AsyncGenerator<ShellOutputChunk>;
307
308
/**
309
* Execute multiple commands in sequence
310
* @param commands - Commands to execute
311
* @param options - Execution options
312
* @returns Array of execution results
313
*/
314
executeBatch(
315
commands: string[],
316
options?: ShellExecutionOptions
317
): Promise<ShellExecutionResult[]>;
318
319
/**
320
* Check if command exists in PATH
321
* @param command - Command name to check
322
* @returns True if command exists
323
*/
324
commandExists(command: string): Promise<boolean>;
325
326
/**
327
* Get current working directory
328
* @returns Current working directory path
329
*/
330
getCwd(): Promise<string>;
331
332
/**
333
* Set working directory for future executions
334
* @param path - New working directory
335
*/
336
setCwd(path: string): Promise<void>;
337
}
338
339
/**
340
* Shell execution configuration
341
*/
342
interface ShellExecutionConfig {
343
defaultTimeout?: number;
344
defaultCwd?: string;
345
defaultEnv?: Record<string, string>;
346
shell?: string;
347
encoding?: string;
348
}
349
350
/**
351
* Shell execution options
352
*/
353
interface ShellExecutionOptions {
354
cwd?: string;
355
env?: Record<string, string>;
356
timeout?: number;
357
input?: string;
358
shell?: string;
359
killSignal?: string;
360
}
361
362
/**
363
* Shell execution result
364
*/
365
interface ShellExecutionResult {
366
stdout: string;
367
stderr: string;
368
exitCode: number;
369
signal: string | null;
370
command: string;
371
duration: number;
372
}
373
374
/**
375
* Shell output chunk for streaming
376
*/
377
interface ShellOutputChunk {
378
type: 'stdout' | 'stderr';
379
data: string;
380
timestamp: Date;
381
}
382
```
383
384
### Loop Detection Service
385
386
Service for detecting and preventing infinite loops in AI agent interactions.
387
388
```typescript { .api }
389
/**
390
* Service for detecting and preventing infinite loops in AI interactions
391
*/
392
class LoopDetectionService {
393
constructor(config: LoopDetectionConfig);
394
395
/**
396
* Check if current interaction might be part of a loop
397
* @param interaction - Current interaction data
398
* @returns Loop detection result
399
*/
400
checkForLoop(interaction: InteractionData): LoopDetectionResult;
401
402
/**
403
* Record an interaction for loop detection analysis
404
* @param interaction - Interaction to record
405
*/
406
recordInteraction(interaction: InteractionData): void;
407
408
/**
409
* Reset loop detection state
410
*/
411
reset(): void;
412
413
/**
414
* Get current loop detection statistics
415
* @returns Loop detection statistics
416
*/
417
getStats(): LoopDetectionStats;
418
}
419
420
/**
421
* Loop detection configuration
422
*/
423
interface LoopDetectionConfig {
424
maxRepeats: number;
425
windowSize: number;
426
similarityThreshold: number;
427
enabled: boolean;
428
}
429
430
/**
431
* Interaction data for loop detection
432
*/
433
interface InteractionData {
434
id: string;
435
type: string;
436
content: string;
437
timestamp: Date;
438
metadata?: any;
439
}
440
441
/**
442
* Loop detection result
443
*/
444
interface LoopDetectionResult {
445
isLoop: boolean;
446
confidence: number;
447
similarInteractions: InteractionData[];
448
recommendation: 'continue' | 'break' | 'modify';
449
}
450
451
/**
452
* Loop detection statistics
453
*/
454
interface LoopDetectionStats {
455
totalInteractions: number;
456
detectedLoops: number;
457
averageConfidence: number;
458
lastDetection: Date | null;
459
}
460
```
461
462
**Usage Examples:**
463
464
```typescript
465
import {
466
FileDiscoveryService,
467
GitService,
468
ChatRecordingService,
469
ShellExecutionService,
470
Storage,
471
Config
472
} from '@google/gemini-cli-core';
473
474
// File discovery and filtering
475
const fileDiscovery = new FileDiscoveryService('/project/root');
476
const allFiles = ['/src/main.ts', '/src/test.ts', '/node_modules/lib.js'];
477
const filteredFiles = fileDiscovery.filterFiles(allFiles, {
478
excludePatterns: ['node_modules/**', '*.test.ts'],
479
maxFileSize: 1024 * 1024 // 1MB
480
});
481
482
// Git operations
483
const gitService = new GitService('/project/root');
484
const isRepo = await gitService.isGitRepository();
485
if (isRepo) {
486
const status = await gitService.getStatus();
487
console.log(`Branch: ${status.current}`);
488
console.log(`Staged files: ${status.staged.length}`);
489
490
// Commit changes
491
await gitService.addFiles(['src/main.ts']);
492
const commitHash = await gitService.commitFiles('Update main functionality');
493
console.log(`Committed: ${commitHash}`);
494
}
495
496
// Chat recording
497
const config = new Config();
498
const storage = new Storage();
499
const chatRecording = new ChatRecordingService(config, storage);
500
501
await chatRecording.startRecording('session-123');
502
await chatRecording.recordUserMessage('What files are in the project?');
503
await chatRecording.recordAssistantMessage('I found 15 files in your project...');
504
await chatRecording.recordToolCall('ls', {path: '.'}, ['file1.ts', 'file2.ts']);
505
506
// Export chat history
507
const history = await chatRecording.exportSession('session-123', 'markdown');
508
console.log(history);
509
510
// Shell command execution
511
const shellService = new ShellExecutionService();
512
const result = await shellService.execute('git status --porcelain', {
513
cwd: '/project/root',
514
timeout: 10000
515
});
516
517
console.log('Git status output:', result.stdout);
518
console.log('Exit code:', result.exitCode);
519
520
// Streaming command execution
521
for await (const chunk of shellService.executeStream('npm install')) {
522
if (chunk.type === 'stdout') {
523
process.stdout.write(chunk.data);
524
} else {
525
process.stderr.write(chunk.data);
526
}
527
}
528
```