From d506ae0d44e35f17d57a1fad4658d4bae9383993 Mon Sep 17 00:00:00 2001 From: T0mSIlver Date: Sat, 27 Jun 2026 00:44:15 +0000 Subject: [PATCH] docs(grep): fix malformed glob examples The example globs in grep.md were written as '.js' and '**/.tsx', which match literal dotfiles rather than files by extension. Correct them to '*.js' and '**/*.tsx' so the model copies a working pattern, and add a test asserting the examples are valid and that '*.js' matches by extension. --- src/fastcontext/agent/tool/grep.md | 2 +- tests/test_grep_glob_examples.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/test_grep_glob_examples.py diff --git a/src/fastcontext/agent/tool/grep.md b/src/fastcontext/agent/tool/grep.md index dd3f6e5..fe6c4fc 100644 --- a/src/fastcontext/agent/tool/grep.md +++ b/src/fastcontext/agent/tool/grep.md @@ -2,7 +2,7 @@ A powerful search tool built on ripgrep Usage: - Prefer using Grep for search tasks when you know the exact symbols or strings to search for. Whenever possible, use this tool instead of invoking grep or rg as a terminal command. - Supports full regex syntax (e.g., "log.*Error", "function\s+\w+") -- Filter files with glob parameter (e.g., ".js", "**/.tsx") or type parameter (e.g., "js", "py", "rust") +- Filter files with glob parameter (e.g., "*.js", "**/*.tsx") or type parameter (e.g., "js", "py", "rust") - Output modes: "content" shows matching lines (default), "files_with_matches" shows only file paths, "count" shows match counts - Pattern syntax: Uses ripgrep (not grep) - literal braces need escaping (use interface\{\} to find interface{} in Go code) - Multiline matching: By default patterns match within single lines only. For cross-line patterns like struct \{[\s\S]*?field, use multiline: true diff --git a/tests/test_grep_glob_examples.py b/tests/test_grep_glob_examples.py new file mode 100644 index 0000000..9e2bc45 --- /dev/null +++ b/tests/test_grep_glob_examples.py @@ -0,0 +1,30 @@ +import asyncio +import json +import tempfile +from pathlib import Path + +from fastcontext.agent.tool.glob import GlobTool +from fastcontext.agent.tool.grep import GrepTool + + +def test_grep_doc_glob_examples_are_valid(): + """The glob examples in the Grep description must be extension globs, not + the malformed dotfile patterns '.js' / '**/.tsx'.""" + desc = GrepTool().description + assert '"*.js"' in desc and '"**/*.tsx"' in desc + # The old malformed examples must be gone. + assert '(e.g., ".js"' not in desc + assert '"**/.tsx"' not in desc + + +def test_documented_extension_glob_actually_matches(): + """Sanity-check that the documented '*.js' pattern matches by extension + (the malformed '.js' would only match a literal dotfile).""" + glob = GlobTool() + with tempfile.TemporaryDirectory() as cwd: + (Path(cwd) / "app.js").write_text("x", encoding="utf-8") + (Path(cwd) / "readme.md").write_text("x", encoding="utf-8") + + out = asyncio.run(glob.call(json.dumps({"directory": cwd, "pattern": "*.js"}), cwd=cwd)) + names = {Path(line).name for line in out.splitlines()} + assert names == {"app.js"}