feat(core): share file list patterns between glob and grep tools (#6359)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Arya Gummadi <aryagummadi@google.com>
This commit is contained in:
sangwook
2025-08-23 13:35:00 +09:00
committed by GitHub
parent f55b294570
commit 494a996ff8
13 changed files with 727 additions and 97 deletions

View File

@@ -21,6 +21,7 @@ import { makeRelative, shortenPath } from '../utils/paths.js';
import { getErrorMessage, isNodeError } from '../utils/errors.js';
import { isGitRepository } from '../utils/gitUtils.js';
import { Config } from '../config/config.js';
import { FileExclusions } from '../utils/ignorePatterns.js';
import { ToolErrorType } from './tool-error.js';
// --- Interfaces ---
@@ -58,11 +59,14 @@ class GrepToolInvocation extends BaseToolInvocation<
GrepToolParams,
ToolResult
> {
private readonly fileExclusions: FileExclusions;
constructor(
private readonly config: Config,
params: GrepToolParams,
) {
super(params);
this.fileExclusions = config.getFileExclusions();
}
/**
@@ -281,7 +285,6 @@ class GrepToolInvocation extends BaseToolInvocation<
/**
* Gets a description of the grep operation
* @param params Parameters for the grep operation
* @returns A string describing the grep
*/
getDescription(): string {
@@ -391,7 +394,27 @@ class GrepToolInvocation extends BaseToolInvocation<
if (grepAvailable) {
strategyUsed = 'system grep';
const grepArgs = ['-r', '-n', '-H', '-E'];
const commonExcludes = ['.git', 'node_modules', 'bower_components'];
// Extract directory names from exclusion patterns for grep --exclude-dir
const globExcludes = this.fileExclusions.getGlobExcludes();
const commonExcludes = globExcludes
.map((pattern) => {
let dir = pattern;
if (dir.startsWith('**/')) {
dir = dir.substring(3);
}
if (dir.endsWith('/**')) {
dir = dir.slice(0, -3);
} else if (dir.endsWith('/')) {
dir = dir.slice(0, -1);
}
// Only consider patterns that are likely directories. This filters out file patterns.
if (dir && !dir.includes('/') && !dir.includes('*')) {
return dir;
}
return null;
})
.filter((dir): dir is string => !!dir);
commonExcludes.forEach((dir) => grepArgs.push(`--exclude-dir=${dir}`));
if (include) {
grepArgs.push(`--include=${include}`);
@@ -474,13 +497,7 @@ class GrepToolInvocation extends BaseToolInvocation<
);
strategyUsed = 'javascript fallback';
const globPattern = include ? include : '**/*';
const ignorePatterns = [
'.git/**',
'node_modules/**',
'bower_components/**',
'.svn/**',
'.hg/**',
]; // Use glob patterns for ignores here
const ignorePatterns = this.fileExclusions.getGlobExcludes();
const filesStream = globStream(globPattern, {
cwd: absolutePath,