Skip to content

Improve file navigation for code review tools - #10

Merged
peteretelej merged 8 commits into
mainfrom
review-usefulness
Apr 9, 2026
Merged

Improve file navigation for code review tools#10
peteretelej merged 8 commits into
mainfrom
review-usefulness

Conversation

@peteretelej

@peteretelej peteretelej commented Apr 9, 2026

Copy link
Copy Markdown
Owner

Code review tools that use largefile mcp need to work around reading changed content. They currently have to call get_overview then manually correlate diff ranges with outline symbols, and estimate line ranges to read relevant definitions. This adds inbuilt capabilities for better navigation:

  • changed_lines accepts diff ranges (for example as available from diffchunk) and classifies each symbol in the outline, so review tools can immediately focus on what changed without a second pass.
  • read_enclosing uses tree-sitter to walk up the AST and return the complete enclosing definition for any line. Supports configurable nesting depth (e.g. depth=2 for the class containing a method) with a context-window fallback for unsupported languages.

Summary by CodeRabbit

  • New Features
    • Diff-aware overview: get_overview accepts changed line ranges and reports per-symbol change states; added read_enclosing to return enclosing definition or context for a given line.
  • Documentation
    • Updated API/design docs and examples with diff-aware overview usage and new tool specs; README badge line simplified.
  • Tests
    • Added integration and unit tests covering diff-aware behavior, read_enclosing, and enclosing-definition discovery.

Outline symbols can now be classified as added, modified, or removed based on
changed line ranges. This is the data model and algorithm layer; tool integration
follows in phase 2.
The get_overview tool now accepts an optional changed_lines parameter
that marks which outline symbols overlap with changed line ranges.
When omitted, behavior is identical to before; when provided, each
outline item includes a changes field and the response includes a
changed_symbols count.
Update get_overview docstring so FastMCP auto-generates the correct schema
for the new changed_lines parameter. Update API.md, design.md, and
examples.md with parameter details, response fields, and a diff-aware
code review workflow example.
Forward the changed_lines parameter from the MCP get_overview
tool definition to the underlying tools.get_overview function,
making diff-aware overview accessible to MCP clients.
Walks up the AST from a target line to find the nearest enclosing
function, class, or method definition, with configurable depth for
navigating nested scopes.
Wire up the tree-sitter enclosing definition lookup as a registered MCP
tool with fallback to a centered context window for unsupported languages
or top-level code.
Exercises the full tool path for enclosing definition lookup and
fallback context window on non-code files.
@coderabbitai

coderabbitai Bot commented Apr 9, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds diff-awareness: get_overview accepts changed_lines, a new read_enclosing tool locates enclosing definitions, and change-classification+marking logic was added. Data models, tree parsing, tools, docs, and tests were updated to support these features.

Changes

Cohort / File(s) Summary
Docs & Badges
README.md, docs/API.md, docs/design.md, docs/examples.md
Removed Codecov badge; documented get_overview(…, changed_lines) signature, changed_symbols top-level field, per-outline changes field, and added a diff-aware example.
Data Models
src/data_models.py
Added FileOverview.changed_symbols: int = 0 and `OutlineItem.changes: str
Change Classification
src/change_marker.py
New module: ChangedLineRange type, parse_changed_lines(), classify_change(), and mark_outline() (validation, sorting/merging ranges, and per-item classification).
Tools & Server
src/tools.py, src/server.py
get_overview accepts and handles changed_lines (parsing, marking, adding changed_symbols); new read_enclosing(...) tool added and exposed via server.
Tree Parsing
src/tree_parser.py
Added DEFINITION_NODE_TYPES, _build_definition_label() helper, and find_enclosing_definition() to locate enclosing AST definitions and produce labels and spans.
Integration Tests
tests/integration/test_get_overview_diff.py, tests/integration/test_read_enclosing.py, tests/integration/test_mcp_server.py
Added tests for get_overview diff behavior, read_enclosing functionality and fallback, binary rejection, and updated MCP tool registry expectations.
Unit Tests
tests/unit/test_change_marker.py, tests/unit/test_tools.py, tests/unit/test_tree_parser.py
New unit tests for parsing/merging ranges, classification/marking behavior, read_enclosing edge cases, and find_enclosing_definition behavior.
Test Fixtures
tests/test_data/python/nested_class.py, tests/test_data/javascript/nested_arrow.js
Added nested-definition fixtures used by tree-parser and enclosing-definition tests.

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant Server
    participant GetOverviewTool as get_overview
    participant ChangeMarker as Change\ Marker
    participant TreeParser as Tree\ Parser

    Client->>Server: get_overview(file_path, changed_lines)
    Server->>GetOverviewTool: get_overview(file_path, changed_lines)
    GetOverviewTool->>TreeParser: build outline(file_path)
    TreeParser-->>GetOverviewTool: outline items
    GetOverviewTool->>ChangeMarker: parse_changed_lines(raw)
    ChangeMarker-->>GetOverviewTool: changed_ranges
    GetOverviewTool->>ChangeMarker: mark_outline(outline, changed_ranges)
    ChangeMarker-->>GetOverviewTool: marked_outline, changed_symbols_count
    GetOverviewTool-->>Server: {outline: marked_outline, changed_symbols: N}
    Server-->>Client: response
Loading
sequenceDiagram
    actor Client
    participant Server
    participant ReadEnclosing as read_enclosing
    participant TreeParser as Tree\ Parser

    Client->>Server: read_enclosing(file_path, line, depth)
    Server->>ReadEnclosing: read_enclosing(file_path, line, depth)
    ReadEnclosing->>TreeParser: find_enclosing_definition(file_path, content, line, depth)
    alt definition found
        TreeParser-->>ReadEnclosing: (text, start, end, label)
        ReadEnclosing-->>Server: {mode: "enclosing", enclosing_symbol: label, content, start_line, end_line}
    else not found
        TreeParser-->>ReadEnclosing: None
        ReadEnclosing-->>Server: {mode: "context_window", enclosing_symbol: null, content, start_line, end_line}
    end
    Server-->>Client: response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Modernize MCP Server #9: Modifies MCP tool interface and get_overview tool surface similarly; likely related changes to tool signatures and registrations.

Poem

🐰 I hopped through lines both old and new,

Marked each symbol with a hop and cue,
Diffs and encloses now sing in rhyme,
Read the context, find the defining time,
A rabbit's nod to code that tracks the changes!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Improve file navigation for code review tools' accurately summarizes the main feature additions: diff-aware change classification (changed_lines) and enclosing definition lookup (read_enclosing) to enhance code review navigation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch review-usefulness

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented Apr 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.56150% with 27 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.43%. Comparing base (34f038a) to head (6d43ac1).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/tree_parser.py 69.01% 22 Missing ⚠️
src/server.py 50.00% 2 Missing ⚠️
src/tools.py 95.00% 2 Missing ⚠️
src/change_marker.py 98.57% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main      #10      +/-   ##
==========================================
- Coverage   89.86%   89.43%   -0.44%     
==========================================
  Files          11       12       +1     
  Lines        1490     1675     +185     
==========================================
+ Hits         1339     1498     +159     
- Misses        151      177      +26     
Files with missing lines Coverage Δ
src/data_models.py 100.00% <100.00%> (ø)
src/change_marker.py 98.57% <98.57%> (ø)
src/server.py 77.14% <50.00%> (-0.99%) ⬇️
src/tools.py 96.63% <95.00%> (-0.20%) ⬇️
src/tree_parser.py 83.06% <69.01%> (-3.32%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
src/server.py (1)

194-207: Add upper bounds to depth and context_lines to prevent oversized requests.

Line 194 and Line 201 currently allow unbounded values; adding le constraints improves resilience under malformed or extreme inputs.

🛡️ Suggested guardrails
     depth: Annotated[
         int,
         Field(
             description="Nesting depth: 1 = innermost definition, 2 = parent (e.g., class containing a method)",
             ge=1,
+            le=20,
         ),
     ] = 1,
     context_lines: Annotated[
         int,
         Field(
             description="Lines of context for fallback window when no enclosing definition is found",
             ge=1,
+            le=500,
         ),
     ] = 40,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/server.py` around lines 194 - 207, The depth and context_lines Annotated
Field definitions currently lack upper bounds; update the Field(...) calls for
the symbols depth and context_lines to include appropriate le (<=) constraints
(e.g., set depth Field(..., ge=1, le=10) and context_lines Field(..., ge=1,
le=200)) to prevent oversized requests, keeping the existing descriptions and
defaults unchanged; modify the Annotated declarations for depth and
context_lines accordingly so validation rejects extreme inputs at model parse
time.
docs/examples.md (1)

554-557: Filter changed symbols recursively, not only top-level items.

Line 554 currently checks only overview["outline"], which can skip nested changed symbols (e.g., methods inside classes) in this workflow example.

♻️ Suggested doc snippet update
-# Step 3: Focus review on changed functions
-changed = [s for s in overview["outline"] if s["changes"]]
-for symbol in changed:
+def flatten(items):
+    for item in items:
+        yield item
+        yield from flatten(item.get("children", []))
+
+# Step 3: Focus review on changed symbols (including nested ones)
+changed = [s for s in flatten(overview["outline"]) if s.get("changes")]
+for symbol in changed:
     code = read_content("/path/to/src/auth.py", offset=symbol["line_number"],
                         limit=symbol["line_count"])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/examples.md` around lines 554 - 557, The example filters changed symbols
only at the top level using overview["outline"], which misses nested items;
update the logic that builds changed (the variable `changed`) to traverse
`overview["outline"]` recursively (e.g., a small helper that walks nested
children) so nested changed symbols (methods inside classes) are included before
calling `read_content` with `symbol["line_number"]` and `symbol["line_count"]`;
ensure the recursion returns the same symbol dicts used by `read_content` so
existing calls to `read_content("/path/to/src/auth.py",
offset=symbol["line_number"], limit=symbol["line_count"])` continue to work.
src/tools.py (1)

568-570: Fallback window should backfill near EOF to honor requested size.

At Line 568–Line 570, when the target is near file end, lines_returned can be much smaller than context_lines even if earlier lines are available. Consider shifting start backward after clamping end.

♻️ Suggested refactor
-    start = max(1, line - context_lines // 2)
-    end = min(total_lines, start + context_lines - 1)
+    start = max(1, line - context_lines // 2)
+    end = min(total_lines, start + context_lines - 1)
+    # Backfill from above when we're clipped at EOF
+    if end - start + 1 < context_lines:
+        start = max(1, end - context_lines + 1)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/tools.py` around lines 568 - 570, The context window near EOF can be too
small because only `start` is clamped downward; after computing `end =
min(total_lines, start + context_lines - 1)` you should backfill by moving
`start` backward when the window is short: if (end - start + 1) < context_lines
then set start = max(1, end - context_lines + 1) before building `content_text`;
update the `content_text = "".join(lines[start - 1 : end])` usage accordingly
and ensure you keep the 1-based to 0-based conversion for slicing consistent
with the `lines` list.
tests/unit/test_tree_parser.py (1)

484-490: Make fixture loading path-robust.

Line 484 and Line 485 rely on CWD-sensitive string paths ("tests/test_data/..."). That can fail in some runners. Resolve from __file__ instead to keep tests deterministic.

♻️ Suggested refactor
-class TestFindEnclosingDefinition:
+class TestFindEnclosingDefinition:
     """Tests for find_enclosing_definition()."""
 
-    PYTHON_FIXTURE = "tests/test_data/python/nested_class.py"
-    JS_FIXTURE = "tests/test_data/javascript/nested_arrow.js"
+    _TEST_DATA_DIR = Path(__file__).resolve().parents[1] / "test_data"
+    PYTHON_FIXTURE = _TEST_DATA_DIR / "python" / "nested_class.py"
+    JS_FIXTURE = _TEST_DATA_DIR / "javascript" / "nested_arrow.js"
 
     `@staticmethod`
-    def _read_fixture(path: str) -> str:
-        with open(path) as f:
-            return f.read()
+    def _read_fixture(path: Path) -> str:
+        return path.read_text(encoding="utf-8")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/test_tree_parser.py` around lines 484 - 490, PYTHON_FIXTURE and
JS_FIXTURE use CWD-dependent string paths; update fixture loading so paths are
resolved relative to the test file using __file__. Modify the _read_fixture
function (and keep using PYTHON_FIXTURE/JS_FIXTURE) to resolve the incoming path
against Path(__file__).parent (or the test module directory) before
opening/reading, e.g., convert the path to a pathlib.Path and do
parent_dir.joinpath(path).read_text(); ensure references to _read_fixture,
PYTHON_FIXTURE, and JS_FIXTURE are preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/change_marker.py`:
- Around line 39-42: The current validation in changed_lines accepts booleans
because isinstance(True, int) is True; update the check in the function/method
that validates start and end (the block that currently does "if not
isinstance(start, int) or not isinstance(end, int):") to reject booleans
explicitly by requiring the exact int type (e.g., use type(start) is int and
type(end) is int or add explicit "isinstance(x, bool)" guards), and keep the
ValueError raised with a clear message referencing the actual types provided.

In `@tests/integration/test_get_overview_diff.py`:
- Around line 111-130: The test
test_get_overview_with_changed_lines_simple_outline can pass vacuously because
the .txt content may produce no outline items; update the test to guarantee at
least one simple-outline item and then assert its changes marking: modify the
tmp_path file content (used by get_overview) to include a header or marker that
your simple-outline parser recognizes (so outline is non-empty), call
get_overview(str(txt_file), changed_lines=[[1,2,"modified"]]) as before, assert
"changed_symbols" in result, assert result["outline"] is not empty, and then for
at least one specific item in result["outline"] verify the "changes" key exists
and reflects the modified lines; reference the test function name
test_get_overview_with_changed_lines_simple_outline and the get_overview/outline
keys when locating where to change the test.

---

Nitpick comments:
In `@docs/examples.md`:
- Around line 554-557: The example filters changed symbols only at the top level
using overview["outline"], which misses nested items; update the logic that
builds changed (the variable `changed`) to traverse `overview["outline"]`
recursively (e.g., a small helper that walks nested children) so nested changed
symbols (methods inside classes) are included before calling `read_content` with
`symbol["line_number"]` and `symbol["line_count"]`; ensure the recursion returns
the same symbol dicts used by `read_content` so existing calls to
`read_content("/path/to/src/auth.py", offset=symbol["line_number"],
limit=symbol["line_count"])` continue to work.

In `@src/server.py`:
- Around line 194-207: The depth and context_lines Annotated Field definitions
currently lack upper bounds; update the Field(...) calls for the symbols depth
and context_lines to include appropriate le (<=) constraints (e.g., set depth
Field(..., ge=1, le=10) and context_lines Field(..., ge=1, le=200)) to prevent
oversized requests, keeping the existing descriptions and defaults unchanged;
modify the Annotated declarations for depth and context_lines accordingly so
validation rejects extreme inputs at model parse time.

In `@src/tools.py`:
- Around line 568-570: The context window near EOF can be too small because only
`start` is clamped downward; after computing `end = min(total_lines, start +
context_lines - 1)` you should backfill by moving `start` backward when the
window is short: if (end - start + 1) < context_lines then set start = max(1,
end - context_lines + 1) before building `content_text`; update the
`content_text = "".join(lines[start - 1 : end])` usage accordingly and ensure
you keep the 1-based to 0-based conversion for slicing consistent with the
`lines` list.

In `@tests/unit/test_tree_parser.py`:
- Around line 484-490: PYTHON_FIXTURE and JS_FIXTURE use CWD-dependent string
paths; update fixture loading so paths are resolved relative to the test file
using __file__. Modify the _read_fixture function (and keep using
PYTHON_FIXTURE/JS_FIXTURE) to resolve the incoming path against
Path(__file__).parent (or the test module directory) before opening/reading,
e.g., convert the path to a pathlib.Path and do
parent_dir.joinpath(path).read_text(); ensure references to _read_fixture,
PYTHON_FIXTURE, and JS_FIXTURE are preserved.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a0432fb1-d593-40bb-b44a-c6a67f560b5d

📥 Commits

Reviewing files that changed from the base of the PR and between 34f038a and a1a18a6.

📒 Files selected for processing (17)
  • README.md
  • docs/API.md
  • docs/design.md
  • docs/examples.md
  • src/change_marker.py
  • src/data_models.py
  • src/server.py
  • src/tools.py
  • src/tree_parser.py
  • tests/integration/test_get_overview_diff.py
  • tests/integration/test_mcp_server.py
  • tests/integration/test_read_enclosing.py
  • tests/test_data/javascript/nested_arrow.js
  • tests/test_data/python/nested_class.py
  • tests/unit/test_change_marker.py
  • tests/unit/test_tools.py
  • tests/unit/test_tree_parser.py

Comment thread src/change_marker.py
Comment on lines +39 to +42
if not isinstance(start, int) or not isinstance(end, int):
raise ValueError(
f"start and end must be integers, got {type(start).__name__} and {type(end).__name__}"
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Reject boolean line numbers in changed_lines validation.

At Line 39–Line 42, isinstance(..., int) accepts True/False. That can silently treat booleans as line numbers (1/0) and misclassify changes. Use strict int checks.

🛡️ Suggested fix
-        if not isinstance(start, int) or not isinstance(end, int):
+        if type(start) is not int or type(end) is not int:
             raise ValueError(
                 f"start and end must be integers, got {type(start).__name__} and {type(end).__name__}"
             )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/change_marker.py` around lines 39 - 42, The current validation in
changed_lines accepts booleans because isinstance(True, int) is True; update the
check in the function/method that validates start and end (the block that
currently does "if not isinstance(start, int) or not isinstance(end, int):") to
reject booleans explicitly by requiring the exact int type (e.g., use
type(start) is int and type(end) is int or add explicit "isinstance(x, bool)"
guards), and keep the ValueError raised with a clear message referencing the
actual types provided.

Comment thread tests/integration/test_get_overview_diff.py
Fix vacuous simple-outline test, add EOF backfill for context
window, and make test fixture paths CWD-independent.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
tests/integration/test_get_overview_diff.py (1)

111-135: ⚠️ Potential issue | 🟡 Minor

Make the simple-outline assertion verify the intended item, not just “any changed”.

Line 135 can still pass if a different outline item is incorrectly marked. Assert that the Section One symbol (lines 1–2) is specifically "modified".

Proposed test tightening
-        # At least one item should actually be marked as changed
-        assert any(item["changes"] is not None for item in result["outline"])
+        section_one_items = [i for i in result["outline"] if "Section One" in i["name"]]
+        assert section_one_items, "Section One should appear in the simple outline"
+        assert section_one_items[0]["changes"] == "modified"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/integration/test_get_overview_diff.py` around lines 111 - 135, The test
test_get_overview_with_changed_lines_simple_outline currently only asserts that
any outline item is marked changed; instead, locate the outline item that
corresponds to "Section One" (created by get_overview when calling with
changed_lines=[[1,2,"modified"]]) by matching its name/text or its start
line/range in result["outline"], and assert that this specific item's "changes"
field equals "modified" (while keeping the other existing assertions). Use the
test's get_overview call and the outline items in result["outline"] to identify
the correct symbol and verify its changes value.
🧹 Nitpick comments (1)
tests/integration/test_get_overview_diff.py (1)

141-163: Consider parameterizing invalid-input cases to reduce repetition.

The three negative tests are solid; combining them with pytest.mark.parametrize would keep this suite easier to extend.

Optional refactor sketch
-    def test_get_overview_invalid_changed_lines_bad_type(self, tmp_path: Path):
-        ...
-    def test_get_overview_invalid_changed_lines_start_gt_end(self, tmp_path: Path):
-        ...
-    def test_get_overview_invalid_changed_lines_empty_inner(self, tmp_path: Path):
-        ...
+    `@pytest.mark.parametrize`(
+        "changed_lines",
+        [
+            ["bad"],   # type: ignore[list-item]
+            [[10, 5]],
+            [[]],      # type: ignore[list-item]
+        ],
+    )
+    def test_get_overview_invalid_changed_lines(self, tmp_path: Path, changed_lines):
+        py_file = tmp_path / "err.py"
+        py_file.write_text("x = 1\n")
+        with pytest.raises(ToolError, match="Invalid changed_lines"):
+            get_overview(str(py_file), changed_lines=changed_lines)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/integration/test_get_overview_diff.py` around lines 141 - 163, Replace
the three repetitive tests (test_get_overview_invalid_changed_lines_bad_type,
test_get_overview_invalid_changed_lines_start_gt_end,
test_get_overview_invalid_changed_lines_empty_inner) with a single parameterized
test using pytest.mark.parametrize that iterates over the invalid changed_lines
values (e.g., ["bad"], [[10, 5]], [[]]) and asserts with
pytest.raises(ToolError, match="Invalid changed_lines") when calling
get_overview(file_path, changed_lines=...); keep each case as a separate param
entry (with optional ids) and ensure the tmp_path fixture still creates the file
before calling get_overview.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@tests/integration/test_get_overview_diff.py`:
- Around line 111-135: The test
test_get_overview_with_changed_lines_simple_outline currently only asserts that
any outline item is marked changed; instead, locate the outline item that
corresponds to "Section One" (created by get_overview when calling with
changed_lines=[[1,2,"modified"]]) by matching its name/text or its start
line/range in result["outline"], and assert that this specific item's "changes"
field equals "modified" (while keeping the other existing assertions). Use the
test's get_overview call and the outline items in result["outline"] to identify
the correct symbol and verify its changes value.

---

Nitpick comments:
In `@tests/integration/test_get_overview_diff.py`:
- Around line 141-163: Replace the three repetitive tests
(test_get_overview_invalid_changed_lines_bad_type,
test_get_overview_invalid_changed_lines_start_gt_end,
test_get_overview_invalid_changed_lines_empty_inner) with a single parameterized
test using pytest.mark.parametrize that iterates over the invalid changed_lines
values (e.g., ["bad"], [[10, 5]], [[]]) and asserts with
pytest.raises(ToolError, match="Invalid changed_lines") when calling
get_overview(file_path, changed_lines=...); keep each case as a separate param
entry (with optional ids) and ensure the tmp_path fixture still creates the file
before calling get_overview.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 453122b0-e54d-4959-b715-6688b75284f5

📥 Commits

Reviewing files that changed from the base of the PR and between a1a18a6 and 6d43ac1.

📒 Files selected for processing (4)
  • src/tools.py
  • tests/integration/test_get_overview_diff.py
  • tests/unit/test_tools.py
  • tests/unit/test_tree_parser.py
✅ Files skipped from review due to trivial changes (1)
  • tests/unit/test_tree_parser.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/unit/test_tools.py
  • src/tools.py

@peteretelej
peteretelej merged commit f32573b into main Apr 9, 2026
6 checks passed
@peteretelej
peteretelej deleted the review-usefulness branch April 9, 2026 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant