From 519cd8c7712fc2ca6d2ca1d356d7f52cbd6d5808 Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Tue, 1 Sep 2026 21:27:37 -0500 Subject: [PATCH] feat(core): add grep matching options (#46716) --- packages/core/src/filesystem.ts | 2 ++ packages/core/src/ripgrep.ts | 4 ++++ packages/core/src/tool/plugin/grep.ts | 14 ++++++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/core/src/filesystem.ts b/packages/core/src/filesystem.ts index 93ef8cfb29e..280740b858d 100644 --- a/packages/core/src/filesystem.ts +++ b/packages/core/src/filesystem.ts @@ -44,6 +44,8 @@ export class GrepInput extends Schema.Class("FileSystem.GrepInput")({ pattern: Schema.String, path: Schema.optionalKey(RelativePath), include: Schema.optionalKey(Schema.String), + literal: Schema.optionalKey(Schema.Boolean), + caseSensitive: Schema.optionalKey(Schema.Boolean), limit: Schema.optionalKey(PositiveInt), }) {} diff --git a/packages/core/src/ripgrep.ts b/packages/core/src/ripgrep.ts index 669982f236f..c40b2936918 100644 --- a/packages/core/src/ripgrep.ts +++ b/packages/core/src/ripgrep.ts @@ -74,6 +74,8 @@ export interface GrepInput { readonly pattern: string readonly file?: string readonly include?: string + readonly literal?: boolean + readonly caseSensitive?: boolean readonly limit: number readonly signal?: AbortSignal } @@ -220,6 +222,8 @@ const layer = Layer.effect( "--json", "--hidden", "--no-messages", + ...(input.literal ? ["--fixed-strings"] : []), + ...(input.caseSensitive === false ? ["--ignore-case"] : []), ...(input.include ? [`--glob=${input.include}`] : []), "--glob=!**/.git/**", "--", diff --git a/packages/core/src/tool/plugin/grep.ts b/packages/core/src/tool/plugin/grep.ts index 9b205b0d0cc..08f9bc71ee9 100644 --- a/packages/core/src/tool/plugin/grep.ts +++ b/packages/core/src/tool/plugin/grep.ts @@ -18,7 +18,7 @@ export const Input = Schema.Struct({ pattern: FileSystem.GrepInput.fields.pattern .check(Schema.isMinLength(1, { message: "Pattern must not be empty" })) .annotate({ - description: "Regular expression to search for in file contents (ripgrep syntax)", + description: "Regular expression or literal text to match in file contents.", }), path: Schema.optionalKey(RelativePath).annotate({ description: "File or directory to search. Defaults to the current working directory.", @@ -26,6 +26,12 @@ export const Input = Schema.Struct({ include: FileSystem.GrepInput.fields.include.annotate({ description: 'Glob pattern to filter files (for example, "*.js" or "*.{ts,tsx}")', }), + literal: FileSystem.GrepInput.fields.literal.annotate({ + description: "Treat `pattern` as exact text instead of a regular expression (default: false).", + }), + caseSensitive: FileSystem.GrepInput.fields.caseSensitive.annotate({ + description: "Use case-sensitive matching (default: true).", + }), limit: FileSystem.GrepInput.fields.limit.annotate({ description: `Maximum number of matching lines to return (default: ${FileSystem.DEFAULT_SEARCH_LIMIT})`, }), @@ -70,7 +76,7 @@ export const Plugin = { name, options: { codemode: false }, description: - "Search file contents using regular expressions. Use it to locate specific code, symbols, or text patterns, and narrow searches with `path` or `include`. Returns matching file paths, line numbers, and line previews.", + "Search file contents using ripgrep's regular expression syntax or literal text matching. Use it to locate specific code, symbols, or text patterns, and narrow searches with `path` or `include`. Returns matching file paths, line numbers, and line previews.", input: Input, output: Output, execute: (input, context) => @@ -92,6 +98,8 @@ export const Plugin = { root: ".", path: input.path, include: input.include, + literal: input.literal, + caseSensitive: input.caseSensitive, limit: input.limit, }, sessionID: context.sessionID, @@ -112,6 +120,8 @@ export const Plugin = { pattern: input.pattern, file: type === "file" ? path.basename(root) : undefined, include: input.include, + literal: input.literal, + caseSensitive: input.caseSensitive, limit: limit + 1, }) .pipe(