From 69ac6cfa337b9a22e376ec16b01ab5be6148f404 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 15:58:17 +0000 Subject: [PATCH 1/3] Initial plan From 81049c9d9e9abef5e466dbe1ef1cea0b27edd704 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 16:01:03 +0000 Subject: [PATCH 2/3] docs: document get_file_diff tool and file_details in list_chunks Co-authored-by: peteretelej <2271973+peteretelej@users.noreply.github.com> --- README.md | 26 ++++++++++++++++++++------ docs/design.md | 31 ++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2f6ccd2..89350f2 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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. @@ -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:** @@ -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 diff --git a/docs/design.md b/docs/design.md index c543061..9eea088 100644 --- a/docs/design.md +++ b/docs/design.md @@ -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) @@ -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 + +**Returns:** Formatted string with the `diff --git` header and all hunks for the specified file. +Raises `ValueError` if the pattern matches zero or more than one file. + ### get_current_overview ```python @@ -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: @@ -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: From 5f12130f18fe75941cabe05f6a79556bf7ae2e0e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 21:55:21 +0000 Subject: [PATCH 3/3] docs: document empty/whitespace ValueError for get_file_diff file_path Co-authored-by: peteretelej <2271973+peteretelej@users.noreply.github.com> --- docs/design.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/design.md b/docs/design.md index 9eea088..1dd73fc 100644 --- a/docs/design.md +++ b/docs/design.md @@ -77,10 +77,10 @@ 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 +- `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 the pattern matches zero or more than one 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