Skip to content

fix(compat): slash-free grep/glob filters match by basename at any depth (#178)#200

Merged
OGtwelve merged 1 commit into
mainfrom
fix/grep-glob-basename-178
Jul 14, 2026
Merged

fix(compat): slash-free grep/glob filters match by basename at any depth (#178)#200
OGtwelve merged 1 commit into
mainfrom
fix/grep-glob-basename-178

Conversation

@OGtwelve

@OGtwelve OGtwelve commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Closes #178. XS P1 batch from the parity verification (#196).

Problem

globToRegExp anchored every pattern to the whole relative path (^…$), so a slash-free filter like glob: '*.ts' compiled to ^[^/]*\.ts$ and matched root-level files only — every nested file was silently dropped. ripgrep (the semantics this tool advertises) matches slash-free globs against the basename at any depth, and that is the shape models emit most often. Probe-verified: {pattern:'needle', glob:'*.ts'} over root.ts + src/nested.ts returned only root.ts.

Fix

A pattern with no / is prefixed with (?:^|.*/) (the same unanchored form gitignore.ts already uses), so *.ts matches root.ts AND src/nested.ts. A pattern containing / (src/*.ts, **/*.ts) keeps full-path anchoring — * still never crosses a directory boundary. Shared globToRegExp → grep and glob stay consistent. The grep glob field now documents the behavior.

Tests

  • slash-free matches nested (grep + glob tool), slashed stays anchored, the prior root-only assertion corrected to the ripgrep behavior.
  • Green: typecheck (both) + test:node (compat 255) + biome.

Part of #196.

Summary by CodeRabbit

  • New Features

    • Improved file search and filtering with slash-free patterns such as *.ts, which now match files in nested directories.
    • Preserved full-path matching for patterns containing slashes, such as src/*.ts.
    • Added clearer guidance for glob pattern behavior, including alternation support.
  • Bug Fixes

    • Corrected grep and file-listing results for nested files filtered by filename patterns.

…pth (#178)

globToRegExp anchored every pattern to the whole relative path (^...$), so a
slash-free filter like glob:'*.ts' compiled to ^[^/]*\.ts$ and matched
ROOT-LEVEL files only — every nested file was silently dropped. ripgrep (the
semantics this tool advertises) matches slash-free globs against the basename at
any depth, and that is the shape models emit most often.

- A pattern with no '/' is prefixed with (?:^|.*/) (the same unanchored form
  gitignore.ts already uses), so '*.ts' matches root.ts AND src/nested.ts. A
  pattern containing '/' ('src/*.ts', '**/*.ts') keeps full-path anchoring, so '*'
  still never crosses a directory boundary. Shared globToRegExp → grep and glob
  stay consistent.
- Document the behavior on the grep 'glob' field (slash-free = basename at any
  depth; slashed = whole worktree-relative path).

Tests: slash-free matches nested (grep + glob tool), slashed stays anchored, the
prior root-only assertion is corrected to the ripgrep behavior.

Part of #196.
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 16b1d45d-6fef-4215-b635-0321af62988a

📥 Commits

Reviewing files that changed from the base of the PR and between 8221395 and ae0db2e.

📒 Files selected for processing (2)
  • packages/ai-claude-compat/src/search-tools.test.ts
  • packages/ai-claude-compat/src/search-tools.ts

📝 Walkthrough

Walkthrough

The search tools now match slash-free globs against basenames at any directory depth, while slash-containing globs remain anchored to relative paths. The glob schema documents these semantics, and tests cover both globTool and grepTool.

Changes

Glob matching semantics

Layer / File(s) Summary
Update glob matching behavior
packages/ai-claude-compat/src/search-tools.ts
The glob schema describes slash-sensitive matching, and globToRegExp applies root-or-any-depth matching to slash-free patterns while preserving full-path anchoring for patterns containing /.
Validate glob and grep results
packages/ai-claude-compat/src/search-tools.test.ts
Tests verify nested basename matches, slash-containing path anchoring, and .ts filtering for both search tools.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: slash-free grep/glob filters matching by basename at any depth.
Linked Issues check ✅ Passed The PR implements basename matching for slash-free globs, preserves slashed anchoring, keeps grep/glob behavior aligned, and adds coverage.
Out of Scope Changes check ✅ Passed The changes stay focused on glob matching semantics, related docs, and tests; no unrelated edits are evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/grep-glob-basename-178

Comment @coderabbitai help to get the list of available commands.

@OGtwelve OGtwelve merged commit 277c344 into main Jul 14, 2026
4 checks passed
@OGtwelve OGtwelve deleted the fix/grep-glob-basename-178 branch July 14, 2026 07:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(compat): slash-free grep glob filters must match by basename at any depth

1 participant