Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/core/src/filesystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export class GrepInput extends Schema.Class<GrepInput>("FileSystem.GrepInput")({
include: Schema.optionalKey(Schema.String),
literal: Schema.optionalKey(Schema.Boolean),
caseSensitive: Schema.optionalKey(Schema.Boolean),
pcre2: Schema.optionalKey(Schema.Boolean),
limit: Schema.optionalKey(PositiveInt),
}) {}

Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/ripgrep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ export interface GrepInput {
readonly include?: string
readonly literal?: boolean
readonly caseSensitive?: boolean
/** Enable ripgrep's PCRE2 engine so patterns may use look-around and backreferences. */
readonly pcre2?: boolean
readonly limit: number
readonly signal?: AbortSignal
}
Expand Down Expand Up @@ -228,6 +230,8 @@ const layer = Layer.effect(
...(input.caseSensitive === false ? ["--ignore-case"] : []),
...(input.include ? [`--glob=${input.include}`] : []),
"--glob=!**/.git/**",
// PCRE2 is opt-in; it is the only engine switch exposed because it enables look-around/backreferences.
...(input.pcre2 ? ["--pcre2"] : []),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With --pcre2, a malformed pattern makes ripgrep exit with code 2 and the message rg: PCRE2: error compiling pattern at offset …. isInvalidPattern only looks for regex parse error and error parsing regex, so this falls through to return code === 1 ? [] : rows. I tried (?<!x)log( with pcre2: true: it came back as a successful empty result, so the model sees "no matches" instead of an error it can fix. A ripgrep build without PCRE2 (PCRE2 is not available in this build of ripgrep) fails the same quiet way. Please make isInvalidPattern also recognise the PCRE2 error messages, or treat any exit code 2 from grep with pcre2 set as a failure.

"--",
input.pattern,
input.file ?? ".",
Expand Down
8 changes: 7 additions & 1 deletion packages/core/src/tool/plugin/grep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export const Input = Schema.Struct({
caseSensitive: FileSystem.GrepInput.fields.caseSensitive.annotate({
description: "Use case-sensitive matching (default: true).",
}),
pcre2: FileSystem.GrepInput.fields.pcre2.annotate({
description:
"Search with ripgrep's PCRE2 engine (default: false). Required when `pattern` uses look-around or backreferences.",
}),
limit: FileSystem.GrepInput.fields.limit.annotate({
description: `Maximum number of matching lines to return (default: ${FileSystem.DEFAULT_SEARCH_LIMIT})`,
}),
Expand Down Expand Up @@ -76,7 +80,7 @@ export const Plugin = {
name,
options: { codemode: false },
description:
"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.",
"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`. Patterns with look-around or backreferences need `pcre2: true`. Returns matching file paths, line numbers, and line previews.",
input: Input,
output: Output,
execute: (input, context) =>
Expand All @@ -94,6 +98,7 @@ export const Plugin = {
include: input.include,
literal: input.literal,
caseSensitive: input.caseSensitive,
pcre2: input.pcre2,
limit: input.limit,
},
sessionID: context.sessionID,
Expand All @@ -116,6 +121,7 @@ export const Plugin = {
include: input.include,
literal: input.literal,
caseSensitive: input.caseSensitive,
pcre2: input.pcre2,
limit: limit + 1,
})
.pipe(
Expand Down
Loading