feat: full implementation for .geminiignore in settings and respective tool calls (#3727)

This commit is contained in:
Pyush Sinha
2025-07-20 00:55:33 -07:00
committed by GitHub
parent 76b935d598
commit a01b1219a3
19 changed files with 803 additions and 116 deletions

View File

@@ -10,7 +10,7 @@ import { BaseTool, Icon, ToolResult } from './tools.js';
import { Type } from '@google/genai';
import { SchemaValidator } from '../utils/schemaValidator.js';
import { makeRelative, shortenPath } from '../utils/paths.js';
import { Config } from '../config/config.js';
import { Config, DEFAULT_FILE_FILTERING_OPTIONS } from '../config/config.js';
import { isWithinRoot } from '../utils/fileUtils.js';
/**
@@ -28,9 +28,12 @@ export interface LSToolParams {
ignore?: string[];
/**
* Whether to respect .gitignore patterns (optional, defaults to true)
* Whether to respect .gitignore and .geminiignore patterns (optional, defaults to true)
*/
respect_git_ignore?: boolean;
file_filtering_options?: {
respect_git_ignore?: boolean;
respect_gemini_ignore?: boolean;
};
}
/**
@@ -89,10 +92,22 @@ export class LSTool extends BaseTool<LSToolParams, ToolResult> {
},
type: Type.ARRAY,
},
respect_git_ignore: {
file_filtering_options: {
description:
'Optional: Whether to respect .gitignore patterns when listing files. Only available in git repositories. Defaults to true.',
type: Type.BOOLEAN,
'Optional: Whether to respect ignore patterns from .gitignore or .geminiignore',
type: Type.OBJECT,
properties: {
respect_git_ignore: {
description:
'Optional: Whether to respect .gitignore patterns when listing files. Only available in git repositories. Defaults to true.',
type: Type.BOOLEAN,
},
respect_gemini_ignore: {
description:
'Optional: Whether to respect .geminiignore patterns when listing files. Defaults to true.',
type: Type.BOOLEAN,
},
},
},
},
required: ['path'],
@@ -199,14 +214,25 @@ export class LSTool extends BaseTool<LSToolParams, ToolResult> {
const files = fs.readdirSync(params.path);
const defaultFileIgnores =
this.config.getFileFilteringOptions() ?? DEFAULT_FILE_FILTERING_OPTIONS;
const fileFilteringOptions = {
respectGitIgnore:
params.file_filtering_options?.respect_git_ignore ??
defaultFileIgnores.respectGitIgnore,
respectGeminiIgnore:
params.file_filtering_options?.respect_gemini_ignore ??
defaultFileIgnores.respectGeminiIgnore,
};
// Get centralized file discovery service
const respectGitIgnore =
params.respect_git_ignore ??
this.config.getFileFilteringRespectGitIgnore();
const fileDiscovery = this.config.getFileService();
const entries: FileEntry[] = [];
let gitIgnoredCount = 0;
let geminiIgnoredCount = 0;
if (files.length === 0) {
// Changed error message to be more neutral for LLM
@@ -227,14 +253,21 @@ export class LSTool extends BaseTool<LSToolParams, ToolResult> {
fullPath,
);
// Check if this file should be git-ignored (only in git repositories)
// Check if this file should be ignored based on git or gemini ignore rules
if (
respectGitIgnore &&
fileFilteringOptions.respectGitIgnore &&
fileDiscovery.shouldGitIgnoreFile(relativePath)
) {
gitIgnoredCount++;
continue;
}
if (
fileFilteringOptions.respectGeminiIgnore &&
fileDiscovery.shouldGeminiIgnoreFile(relativePath)
) {
geminiIgnoredCount++;
continue;
}
try {
const stats = fs.statSync(fullPath);
@@ -265,13 +298,21 @@ export class LSTool extends BaseTool<LSToolParams, ToolResult> {
.join('\n');
let resultMessage = `Directory listing for ${params.path}:\n${directoryContent}`;
const ignoredMessages = [];
if (gitIgnoredCount > 0) {
resultMessage += `\n\n(${gitIgnoredCount} items were git-ignored)`;
ignoredMessages.push(`${gitIgnoredCount} git-ignored`);
}
if (geminiIgnoredCount > 0) {
ignoredMessages.push(`${geminiIgnoredCount} gemini-ignored`);
}
if (ignoredMessages.length > 0) {
resultMessage += `\n\n(${ignoredMessages.join(', ')})`;
}
let displayMessage = `Listed ${entries.length} item(s).`;
if (gitIgnoredCount > 0) {
displayMessage += ` (${gitIgnoredCount} git-ignored)`;
if (ignoredMessages.length > 0) {
displayMessage += ` (${ignoredMessages.join(', ')})`;
}
return {