fix(coding-agent): grep tool ignores ripgrep config via --no-config

The built-in grep tool spawned rg with the inherited environment, so
RIPGREP_CONFIG_PATH (e.g. a config containing --fixed-strings) silently
changed tool semantics: literal: false searches became literal and the
agent got incomplete results with no error.

Pass --no-config so the tool contract is deterministic. Users who want
custom rg behavior can use the bash tool or wrap grep in an extension.

closes #11203
This commit is contained in:
Petr Houška 2026-10-21 21:25:32 +02:00
parent bd3c9b8237
commit 8c4e873899
2 changed files with 28 additions and 1 deletions

View file

@ -159,7 +159,9 @@ export function createGrepToolDefinition(
return lines;
};
const args: string[] = ["--json", "--line-number", "--color=never", "--hidden"];
// --no-config: the tool contract (literal, glob, limit, ...) must not depend on
// ambient user config like RIPGREP_CONFIG_PATH. Users can customize via bash or extensions.
const args: string[] = ["--no-config", "--json", "--line-number", "--color=never", "--hidden"];
if (ignoreCase) args.push("--ignore-case");
if (literal) args.push("--fixed-strings");
if (glob) args.push("--glob", glob);

View file

@ -908,6 +908,31 @@ describe("Coding Agent Tools", () => {
expect(output).not.toContain("match two");
});
// https://github.com/earendil-works/pi/issues/11203
it("should ignore RIPGREP_CONFIG_PATH", async () => {
const configFile = join(testDir, "rg-config");
const testFile = join(testDir, "fixture.txt");
writeFileSync(configFile, "--fixed-strings\n");
writeFileSync(testFile, "aXb\na.b\n");
const previous = process.env.RIPGREP_CONFIG_PATH;
process.env.RIPGREP_CONFIG_PATH = configFile;
try {
const result = await grepTool.execute("test-call-rg-config", {
pattern: "a.b",
path: testFile,
literal: false,
});
const output = getTextOutput(result);
expect(output).toContain("fixture.txt:1: aXb");
expect(output).toContain("fixture.txt:2: a.b");
} finally {
if (previous === undefined) delete process.env.RIPGREP_CONFIG_PATH;
else process.env.RIPGREP_CONFIG_PATH = previous;
}
});
it("should treat flag-like patterns as search text", async () => {
const marker = join(testDir, "grep-injection-marker");
const payload = join(testDir, "payload.sh");