# How Jcode's Agent Grep Tool Works With File Structure

> Discover how jcode’s agent grep tool navigates file structures, executes precise searches like grep or trace, and filters results for efficient code exploration in your repository.

- Repository: [Jeremy Huang/jcode](https://github.com/1jehuang/jcode)
- Tags: how-to-guide
- Published: 2026-04-30

---

**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](https://github.com/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`](https://github.com/1jehuang/jcode/blob/main/src/tool/agentgrep.rs), the resolution logic appears as:

```rust
// 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`](https://github.com/1jehuang/jcode/blob/main/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`](https://github.com/1jehuang/jcode/blob/main/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`](https://github.com/1jehuang/jcode/blob/main/src/tool/grep.rs) (lines 17-38) handles plain regex searches without the advanced filtering of `agentgrep`.

## Practical Usage Examples

### Searching a Specific File

```json
{
  "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.

### Repository-Wide Glob Search

```json
{
  "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

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

```

The registry maps `"file_grep"` to `"grep"`, triggering the lightweight implementation in [`src/tool/grep.rs`](https://github.com/1jehuang/jcode/blob/main/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`](https://github.com/1jehuang/jcode/blob/main/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`](https://github.com/1jehuang/jcode/blob/main/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`](https://github.com/1jehuang/jcode/blob/main/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.