How Jcode's Agent Grep Tool Works With File Structure

Jcode's agentgrep tool resolves user-provided paths against the workspace root, executes one of four search modes (grep, find, outline, or trace), and filters results to specific files when exact paths are provided, enabling precise code-aware searches within repository structures.

The agentgrep tool in the 1jehuang/jcode repository serves as the primary code-aware search mechanism. It processes JSON payloads to perform intelligent searches across the file structure while respecting workspace boundaries and .gitignore patterns.

Input Parsing and Path Resolution

The tool begins by deserializing incoming JSON into the AgentGrepInput struct. All parameters are optional, with mode defaulting to "grep" via default_agentgrep_mode.

Path resolution happens through resolve_path_arg, which converts user strings into absolute PathBuf objects relative to the session root using ToolContext::resolve_path. This ensures all searches remain sandboxed within the repository tree.

In src/tool/agentgrep.rs, the resolution logic appears as:

// Lines 25-28: Convert relative paths to absolute workspace paths
let path = resolve_path_arg(&input.path, ctx)?;

Exact File Detection and Filtering

When users specify a concrete file path, the system extracts the filename via exact_search_file_path. For example, "src/main.rs" resolves to "main.rs". This flag enables targeted filtering after the search completes.

The filtering occurs through mode-specific functions:

  • filter_grep_result_to_exact_file (lines 40-53)
  • filter_find_result_to_exact_file (lines 54-64)
  • filter_smart_result_to_exact_file (lines 66-78)

These helpers discard any entries whose path doesn't match the exact filename, making agentgrep behave like a targeted file-level search while still traversing the full tree.

Search Modes and Execution Flow

The tool supports four distinct search modes, each built through dedicated argument constructors:

  1. grep - Regex-based content search
  2. find - Filename and glob matching
  3. outline - Code structure analysis
  4. trace - Dependency and reference tracing

Each mode calls into the external agentgrep crate (run_grep, run_find, run_outline, run_smart) with arguments built by the corresponding build_*_args helpers. The search root is determined by resolve_search_root, respecting the session's working directory.

Directory Traversal and Binary Protection

The underlying implementation uses ignore::WalkBuilder for parallel filesystem traversal (up to 8 threads) while honoring .gitignore, .ignore, and hidden-file settings.

Binary file protection prevents searching non-text files. The is_binary_extension function in src/tool/grep.rs (lines 40-50) rejects common binary extensions including images, archives, and compiled objects.

When no exact file is specified, the search walks the full tree subject to optional include glob patterns. The helper normalized_agentgrep_glob treats *, **, or empty strings as "match everything" to avoid unnecessary pattern overhead.

Result Limits and Output Formatting

Both agentgrep and the fallback grep tool enforce strict limits:

  • MAX_LINE_LEN = 2000 - truncates over-long lines with ellipsis
  • MAX_RESULTS = 100 - caps total matches to prevent output flooding

After filtering, results pass through render_*_output functions to generate human-readable strings wrapped in ToolOutput with titles like "agentgrep grep".

Fallback Lightweight Grep

When the model requests file_grep, the registry in src/tool/mod.rs (lines 458-473) resolves this alias to the lightweight grep implementation. This fallback walks the filesystem using ignore::WalkBuilder, skips binary files via is_binary_extension, respects optional include globs, and applies the same 100-match cap.

The core algorithm in src/tool/grep.rs (lines 17-38) handles plain regex searches without the advanced filtering of agentgrep.

Practical Usage Examples

Searching a Specific File

{
  "tool": "agentgrep",
  "parameters": {
    "mode": "grep",
    "query": "TODO",
    "path": "src/tool/grep.rs"
  }
}

The path parameter resolves to the workspace file, exact_search_file_path extracts "grep.rs", and filter_grep_result_to_exact_file ensures only matches from that file appear in results.

{
  "tool": "agentgrep",
  "parameters": {
    "mode": "find",
    "glob": "**/*.rs",
    "max_files": 5
  }
}

The glob normalizes through normalized_agentgrep_glob and passes to the agentgrep library with the max_files limit applied to the output.

Using the Fallback Grep

{
  "tool": "file_grep",
  "parameters": {
    "pattern": "TODO",
    "path": "src"
  }
}

The registry maps "file_grep" to "grep", triggering the lightweight implementation in src/tool/grep.rs that walks src/, skips binaries, and truncates results to 100 matches.

Summary

  • Path Resolution: resolve_path_arg and ToolContext::resolve_path sandbox searches within the workspace root
  • Exact File Filtering: exact_search_file_path and filter_*_result_to_exact_file prune results to specific files when concrete paths are provided
  • Search Modes: Four modes (grep, find, outline, trace) dispatch to the external agentgrep crate via dedicated argument builders
  • Traversal: ignore::WalkBuilder provides parallel, .gitignore-aware directory walking with binary file exclusion via is_binary_extension
  • Safety Limits: Hard caps at 100 results and 2000 characters per line prevent resource exhaustion
  • Registry Mapping: file_grep aliases to the lightweight grep tool for simple regex searches without advanced filtering

Frequently Asked Questions

How does jcode's agent grep handle relative paths?

The tool converts all relative paths to absolute PathBuf objects using ToolContext::resolve_path, ensuring searches remain confined to the workspace directory regardless of the current working directory. This happens in src/tool/agentgrep.rs through the resolve_path_arg helper before any search execution begins.

What is the difference between agentgrep and the file_grep tool?

agentgrep provides code-aware searching with four specialized modes (grep, find, outline, trace) and exact-file filtering through the external agentgrep crate. The file_grep tool (accessed via alias in src/tool/mod.rs) offers a lightweight fallback that performs simple regex searches using ignore::WalkBuilder without the advanced filtering infrastructure, making it suitable for quick pattern matching across directory trees.

Why does agentgrep traverse the entire tree when searching a specific file?

The tool uses ignore::WalkBuilder to walk the full directory tree while respecting .gitignore patterns, then applies filter_grep_result_to_exact_file (or mode-specific variants) to discard non-matching results. This approach avoids the complexity of custom per-file walkers while still delivering targeted results, as the filtering step is computationally cheap compared to building specialized traversal logic for individual files.

How does the tool prevent searching binary files?

The is_binary_extension function in src/tool/grep.rs maintains a denylist of common binary extensions including images, archives, and compiled objects. Both the lightweight grep and agentgrep tools invoke this check during directory traversal to skip non-text files, ensuring searches only process readable source code and documentation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →