Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ Large diffs exceed LLM context limits and waste tokens on irrelevant changes. A

## Solution

MCP server with 4 navigation tools:
MCP server with 5 navigation tools:

- `load_diff` - Parse diff file with custom settings (optional)
- `list_chunks` - Show chunk overview with file mappings (auto-loads)
- `list_chunks` - Show chunk overview with file mappings and per-file line counts (auto-loads)
- `get_chunk` - Retrieve specific chunk content (auto-loads)
- `find_chunks_for_files` - Locate chunks by file patterns (auto-loads)
- `get_file_diff` - Extract the complete diff for a single file (auto-loads)

## Setup

Expand Down Expand Up @@ -89,11 +90,12 @@ Create temporary diff files and tracking files as needed and clean up after anal
When you ask your AI assistant to analyze changes, it uses diffchunk's tools strategically:

1. **Creates the diff file** (e.g., `git diff main..develop > /tmp/changes.diff`) based on your question
2. **Uses `list_chunks`** to get an overview of the diff structure and total scope
2. **Uses `list_chunks`** to get an overview of the diff structure and total scope, including per-file line counts via `file_details`
3. **Uses `find_chunks_for_files`** to locate relevant sections when you ask about specific file types
4. **Uses `get_chunk`** to examine specific sections without loading the entire diff into context
5. **Tracks progress systematically** through large changesets, analyzing chunk by chunk
6. **Cleans up temporary files** after completing the analysis
4. **Uses `get_file_diff`** to fetch the complete diff for one specific file without loading an entire chunk
5. **Uses `get_chunk`** to examine specific sections without loading the entire diff into context
6. **Tracks progress systematically** through large changesets, analyzing chunk by chunk
7. **Cleans up temporary files** after completing the analysis

This lets your AI assistant handle massive diffs that would normally crash other tools, while providing thorough analysis without losing context.

Expand All @@ -104,6 +106,7 @@ This lets your AI assistant handle massive diffs that would normally crash other
```python
list_chunks("/tmp/changes.diff")
# → 5 chunks across 12 files, 3,847 total lines
# Each chunk includes file_details with per-file line counts
```

**Target specific files:**
Expand All @@ -116,6 +119,17 @@ get_chunk("/tmp/changes.diff", 1)
# → Content of first Python chunk
```

**Single-file diff:**

```python
get_file_diff("/tmp/changes.diff", "src/main.py")
# → Complete diff for src/main.py (header + all hunks)

# Glob patterns work when they match exactly one file
get_file_diff("/tmp/changes.diff", "*.config")
# → Complete diff for the single matching config file
```

**Systematic analysis:**

```python
Expand Down
31 changes: 30 additions & 1 deletion docs/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,22 @@ def load_diff(
def list_chunks(absolute_file_path: str) -> List[Dict[str, Any]]
```

**Returns:** Array of chunk metadata with files, line counts, summaries
**Returns:** Array of chunk metadata with files, line counts, summaries, and `file_details` (per-file line counts)

```json
[
{
"chunk": 1,
"files": ["src/main.py", "src/utils.py"],
"file_details": [
{"path": "src/main.py", "lines": 120},
{"path": "src/utils.py", "lines": 45}
],
"lines": 165,
"summary": "2 files, 165 lines"
}
]
```

### get_chunk (Auto-loading)

Expand All @@ -55,6 +70,18 @@ def find_chunks_for_files(absolute_file_path: str, pattern: str) -> List[int]

**Returns:** Array of chunk numbers matching glob pattern

### get_file_diff (Auto-loading)

```python
def get_file_diff(absolute_file_path: str, file_path: str) -> str
```

**Parameters:**
- `file_path` – Exact path or glob pattern that matches exactly one file in the diff. Must be a non-empty, non-whitespace string.

**Returns:** Formatted string with the `diff --git` header and all hunks for the specified file.
Raises `ValueError` if `file_path` is empty or whitespace-only, or if the pattern matches zero or more than one file.

### get_current_overview

```python
Expand All @@ -74,6 +101,7 @@ class DiffChunk:
line_count: int
parent_file: str | None = None # For large file sub-chunks
sub_chunk_index: int | None = None # Sub-chunk position
file_line_counts: Dict[str, int] = field(default_factory=dict) # Per-file line counts

@dataclass
class ChunkInfo:
Expand All @@ -83,6 +111,7 @@ class ChunkInfo:
summary: str
parent_file: str | None = None
sub_chunk_index: int | None = None
file_details: List[Dict[str, Any]] = field(default_factory=list) # [{"path": str, "lines": int}]

@dataclass
class DiffSession:
Expand Down