From 1de9052758dc09ea090d4fb49e327f43c867074b Mon Sep 17 00:00:00 2001 From: "gemini-cli[bot]" Date: Wed, 29 Apr 2026 22:47:00 +0000 Subject: [PATCH] # Fix: Inconsistent Case-Sensitivity in GrepTool This PR fixes an inconsistency in the `GrepTool` where the system grep strategy was case-sensitive, while the `git grep` and JavaScript fallback strategies were case-insensitive. ## Changes - Added the `-i` flag to the `grepArgs` array in the system grep strategy within `packages/core/src/tools/grep.ts`. - Added a unit test in `packages/core/src/tools/grep.test.ts` to verify that the `-i` flag is correctly passed to the system `grep` command. ## Impact All search strategies in `GrepTool` now behave consistently with regard to case-sensitivity (defaulting to case-insensitive). ## Verification - Ran `npm test -w @google/gemini-cli-core -- src/tools/grep.test.ts`. - Verified that the `-i` flag is correctly passed to the `grep` command. --- packages/core/src/tools/grep.test.ts | 28 ++++++++++++++++++++++++++++ packages/core/src/tools/grep.ts | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/core/src/tools/grep.test.ts b/packages/core/src/tools/grep.test.ts index 4af684b1cd..860169c02d 100644 --- a/packages/core/src/tools/grep.test.ts +++ b/packages/core/src/tools/grep.test.ts @@ -314,6 +314,34 @@ describe('GrepTool', () => { ); }, 30000); + it('should pass -i flag to system grep for case-insensitivity', async () => { + vi.mocked(execStreaming).mockImplementationOnce(() => + createLineGenerator(['fileA.txt:1:hello world']), + ); + + const params: GrepToolParams = { pattern: 'HELLO' }; + const invocation = grepTool.build(params) as unknown as { + isCommandAvailable: (command: string) => Promise; + execute: (options: ExecuteOptions) => Promise; + }; + // Force system grep strategy by mocking isCommandAvailable and ensuring git grep is not used + invocation.isCommandAvailable = vi.fn(async (command: string) => { + if (command === 'git') return false; + if (command === 'grep') return true; + return false; + }); + + await invocation.execute({ abortSignal }); + + expect(execStreaming).toHaveBeenCalledWith( + 'grep', + expect.arrayContaining(['-i']), + expect.objectContaining({ + cwd: expect.any(String), + }), + ); + }); + it('should throw an error if params are invalid', async () => { const params = { dir_path: '.' } as unknown as GrepToolParams; // Invalid: pattern missing expect(() => grepTool.build(params)).toThrow( diff --git a/packages/core/src/tools/grep.ts b/packages/core/src/tools/grep.ts index 34be588573..d89da94aab 100644 --- a/packages/core/src/tools/grep.ts +++ b/packages/core/src/tools/grep.ts @@ -465,7 +465,7 @@ class GrepToolInvocation extends BaseToolInvocation< const grepAvailable = await this.isCommandAvailable('grep'); if (grepAvailable) { strategyUsed = 'system grep'; - const grepArgs = ['-r', '-n', '-H', '-E', '-I']; + const grepArgs = ['-r', '-n', '-H', '-E', '-I', '-i']; // Extract directory names from exclusion patterns for grep --exclude-dir const globExcludes = this.fileExclusions.getGlobExcludes(); const commonExcludes = globExcludes