Search Tool
Reference for the search default tool: search and count_matches, with ripgrep acceleration.
Search Tool
Script: powers/search.py
Dependencies: pydantic
Search file contents by pattern (regex or literal) with structured output including file paths, line numbers, and surrounding context. Automatically uses ripgrep when available for significantly faster searches.
search
Search for a pattern across files in a directory. Returns structured matches with file paths, line numbers, and optional context lines.
Input
| Field | Type | Default | Description |
|---|---|---|---|
pattern | str | required | Search pattern (regex or literal string) |
path | str | "." | Directory or file to search in |
glob | str | "*" | File glob pattern to filter (e.g., *.py, *.ts) |
regex | bool | false | Treat pattern as regex (default: literal string match) |
case_sensitive | bool | true | Case-sensitive search |
context_lines | int | 0 | Number of context lines before and after each match (0-5) |
max_results | int | 100 | Maximum number of matches to return |
include_hidden | bool | false | Include hidden files/directories (starting with .) |
multiline | bool | false | Enable multiline matching (requires ripgrep) |
Output
| Field | Type | Description |
|---|---|---|
ok | bool | true if search completed |
matches | list | Array of match objects (see below) |
total_matches | int | Number of matches found |
files_searched | int | Number of files searched |
truncated | bool | true if max_results was reached |
error | str | Error message on failure |
Each match object:
| Field | Type | Description |
|---|---|---|
file | str | File path (relative to search root) |
line_number | int | 1-based line number |
line | str | The matching line content |
context_before | list | Lines before the match (if context_lines > 0) |
context_after | list | Lines after the match (if context_lines > 0) |
Examples
// Find all function definitions in Python files
{"pattern": "def main", "path": "src", "glob": "*.py"}
// Case-insensitive search with context
{"pattern": "TODO", "path": ".", "context_lines": 2, "case_sensitive": false}
// Regex search for import patterns
{"pattern": "import.*json", "regex": true, "glob": "*.py"}
// Search in a single file
{"pattern": "class User", "path": "src/models.py"}
// Multiline pattern (requires ripgrep)
{"pattern": "class.*\\{[\\s\\S]*?constructor", "regex": true, "multiline": true, "glob": "*.ts"}Ripgrep Acceleration
When rg (ripgrep) is available on the system PATH, the search tool uses it automatically for significantly faster results. The fallback Python implementation is used when ripgrep is not installed.
Ripgrep benefits:
- 10-100x faster on large codebases
- Supports multiline matching (
multiline: true) - Respects
.gitignorerules - Better Unicode handling
Auto-Skipped Content
The following are automatically skipped:
- Directories:
__pycache__,node_modules,.git,.venv,venv,.tox,.mypy_cache,.pytest_cache,dist,build,.egg-info,.eggs - Binary files:
.pyc,.so,.png,.jpg,.zip,.pdf,.exe,.woff,.sqlite, and many more
count_matches
Count occurrences of a pattern across files, broken down by file. Useful for getting an overview before doing a detailed search.
Input
| Field | Type | Default | Description |
|---|---|---|---|
pattern | str | required | Pattern to count (literal or regex) |
path | str | "." | Directory or file to search |
glob | str | "*" | File glob filter |
regex | bool | false | Treat pattern as regex |
case_sensitive | bool | true | Case-sensitive search |
Output
| Field | Type | Description |
|---|---|---|
ok | bool | true if count completed |
total | int | Total number of matches across all files |
by_file | list | Array of {file, count} objects, sorted by count descending |
files_searched | int | Number of files searched |
error | str | Error message on failure |
Examples
// Count TODOs in Python files
{"pattern": "TODO", "glob": "*.py"}
// -> {"ok": true, "total": 23, "by_file": [{"file": "main.py", "count": 8}, ...]}
// Count console.log statements
{"pattern": "console\\.log", "regex": true, "glob": "*.ts"}
// Case-insensitive count
{"pattern": "error", "case_sensitive": false, "glob": "*.log"}Tips
- Use
count_matchesfirst to get an overview, thensearchwithcontext_linesfor details - Literal string matching (default) is more predictable than regex -- only use
regex: truewhen you need pattern matching - Set
globto filter by file type for faster and more relevant results - The
max_results: 100default prevents overwhelming output -- increase it only when needed - Install ripgrep (
brew install ripgreporapt install ripgrep) for dramatically faster searches on large codebases