code-review-ai-cli 2.1.0__tar.gz → 2.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. code_review_ai_cli-2.2.0/PKG-INFO +146 -0
  2. code_review_ai_cli-2.2.0/README.md +106 -0
  3. code_review_ai_cli-2.2.0/code_review_ai_cli.egg-info/PKG-INFO +146 -0
  4. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/pyproject.toml +1 -1
  5. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/src/ai_review.py +3 -12
  6. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/src/config.py +3 -1
  7. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/src/git_utils.py +0 -38
  8. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/src/prompts/config.yaml.template +8 -2
  9. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/src/tfs_client.py +40 -3
  10. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/tests/test_config.py +386 -360
  11. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/tests/test_git_utils.py +156 -162
  12. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/tests/test_tfs_client.py +84 -1
  13. code_review_ai_cli-2.1.0/PKG-INFO +0 -433
  14. code_review_ai_cli-2.1.0/README.md +0 -393
  15. code_review_ai_cli-2.1.0/code_review_ai_cli.egg-info/PKG-INFO +0 -433
  16. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/code_review_ai_cli.egg-info/SOURCES.txt +0 -0
  17. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/code_review_ai_cli.egg-info/dependency_links.txt +0 -0
  18. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/code_review_ai_cli.egg-info/entry_points.txt +0 -0
  19. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/code_review_ai_cli.egg-info/requires.txt +0 -0
  20. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/code_review_ai_cli.egg-info/top_level.txt +0 -0
  21. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/setup.cfg +0 -0
  22. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/src/__init__.py +0 -0
  23. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/src/context_extractor.py +0 -0
  24. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/src/formatter.py +0 -0
  25. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/src/llm_client.py +0 -0
  26. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/src/prompt_utils.py +0 -0
  27. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/src/prompts/review_prompt.md.template +0 -0
  28. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/tests/test_ai_review.py +0 -0
  29. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/tests/test_context_extractor.py +0 -0
  30. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/tests/test_formatter.py +0 -0
  31. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/tests/test_llm_client.py +0 -0
  32. {code_review_ai_cli-2.1.0 → code_review_ai_cli-2.2.0}/tests/test_prompt_utils.py +0 -0
@@ -0,0 +1,146 @@
1
+ Metadata-Version: 2.4
2
+ Name: code-review-ai-cli
3
+ Version: 2.2.0
4
+ Summary: Automated AI-powered code review CLI for Azure DevOps / TFS Pull Requests
5
+ License: MIT
6
+ Keywords: code-review,ai,azure-devops,tfs,pull-request,llm
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Environment :: Console
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Software Development :: Quality Assurance
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: requests>=2.28.0
19
+ Requires-Dist: PyYAML>=6.0
20
+ Provides-Extra: bedrock
21
+ Requires-Dist: boto3>=1.34.0; extra == "bedrock"
22
+ Provides-Extra: openai
23
+ Requires-Dist: openai>=1.0.0; extra == "openai"
24
+ Provides-Extra: gemini
25
+ Requires-Dist: google-generativeai>=0.3.0; extra == "gemini"
26
+ Provides-Extra: claude
27
+ Requires-Dist: anthropic>=0.18.0; extra == "claude"
28
+ Provides-Extra: tree-sitter
29
+ Requires-Dist: tree-sitter-languages>=1.10.2; extra == "tree-sitter"
30
+ Provides-Extra: all
31
+ Requires-Dist: boto3>=1.34.0; extra == "all"
32
+ Requires-Dist: openai>=1.0.0; extra == "all"
33
+ Requires-Dist: google-generativeai>=0.3.0; extra == "all"
34
+ Requires-Dist: anthropic>=0.18.0; extra == "all"
35
+ Requires-Dist: tree-sitter-languages>=1.10.2; extra == "all"
36
+ Provides-Extra: dev
37
+ Requires-Dist: pytest>=8.3.0; extra == "dev"
38
+ Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
39
+ Requires-Dist: pytest-mock>=3.14.0; extra == "dev"
40
+
41
+ # AI Code Review
42
+
43
+ AI Code Review is an automated AI-powered code review CLI, compatible with various LLM providers, designed for integration with Azure DevOps, whether in the cloud or on-premises. It allows you to run a review on demand or as part of a pipeline triggered before a commit or when a pull request is created.
44
+
45
+ ## Features
46
+
47
+ - AI Pull Request review (`pr-review`)
48
+ - Structured PR comments (inline + general summary)
49
+ - `dry-run` mode to validate without posting
50
+ - PR listing with filters (`list-prs`)
51
+ - Configuration exclusively via `config.yaml`
52
+ - Providers LLM: OpenAI, Azure OpenAI, Gemini, Claude, Ollama, GitHub Copilot, AWS Bedrock
53
+ - Diff filtering by **excluded path prefixes** (`excluded_paths`) and/or **file extensions** (`file_extensions_filter`)
54
+
55
+ ## Documentation
56
+
57
+ - [Configuration Guide](docs/configuration.md) - Details on YAML parameters and settings.
58
+ - [Commands Reference](docs/commands.md) - Complete list of CLI commands and arguments.
59
+ - [Execution Flow](docs/execution_flow.md) - Mermaid diagram of the application's lifecycle.
60
+ - [Troubleshooting](docs/troubleshooting.md) - Common issues and solutions.
61
+
62
+ ## Output Review Format
63
+
64
+ ![Review Output Format Example](/imgs/review_output.png)
65
+
66
+ ## Installation
67
+
68
+ Install from PyPI:
69
+ s
70
+ ```bash
71
+ pip install code-review-ai-cli
72
+ ```
73
+
74
+ After installing the package, generate ready-to-edit configuration files in your working directory:
75
+
76
+ ```bash
77
+ ai-review init
78
+ ```
79
+
80
+ This copies two bundled templates:
81
+
82
+ - **`config.yaml`** — all available options with inline documentation
83
+ - **`review_prompt.md`** — default review style rules, injected into every LLM prompt
84
+
85
+ The tool looks for `config.yaml` in the **current working directory** at runtime. You can also pass a different path with `--config`:
86
+
87
+ ```bash
88
+ ai-review pr-review --config ~/configs/ai-review.yaml
89
+ ```
90
+
91
+ If you plan to run the test suite locally, also install development dependencies:
92
+
93
+ ```bash
94
+ pip install "code-review-ai-cli[dev]"
95
+ ```
96
+
97
+ ## Minimal Example
98
+
99
+ Example `config.yaml`:
100
+
101
+ ```yaml
102
+ llm:
103
+ provider: openai
104
+ model: gpt-4o
105
+
106
+ openai:
107
+ api_key: sk-xxxx
108
+
109
+ tfs:
110
+ base_url: https://dev.azure.com/your-organization
111
+ project: ProjectName
112
+ pat: xxxxxxxxx
113
+ verify_ssl: true
114
+ # ca_bundle: C:/certs/corporate-root-ca.pem
115
+
116
+ review:
117
+ verbosity: detailed
118
+ scope: diff_only
119
+ custom_prompt_file: review_prompt.md
120
+ # file limit sent to the LLM
121
+ max_diff_files: 50
122
+ # per-file limit
123
+ max_diff_lines: 2000
124
+ # extension allowlist (empty list = all files)
125
+ file_extensions_filter: [".cs", ".ts", ".py"]
126
+ # exclude path prefixes from the diff (applied before file_extensions_filter)
127
+ # leading slash is optional; add trailing slash for exact folder boundary
128
+ excluded_paths: ["libs/generated"]
129
+
130
+ pr:
131
+ auto_post_comments: false
132
+ dry_run: false
133
+ comment_mode: structured
134
+
135
+ output:
136
+ format: terminal
137
+ file: ""
138
+ color: true
139
+ ```
140
+
141
+ ## Available VS Code Tasks
142
+
143
+ - `AI Review: Pull Request (Interactive)`
144
+ - `AI Review: PR (Dry-Run)`
145
+ - `AI Review: List Active PRs`
146
+ - `AI Review: Interactive Mode`
@@ -0,0 +1,106 @@
1
+ # AI Code Review
2
+
3
+ AI Code Review is an automated AI-powered code review CLI, compatible with various LLM providers, designed for integration with Azure DevOps, whether in the cloud or on-premises. It allows you to run a review on demand or as part of a pipeline triggered before a commit or when a pull request is created.
4
+
5
+ ## Features
6
+
7
+ - AI Pull Request review (`pr-review`)
8
+ - Structured PR comments (inline + general summary)
9
+ - `dry-run` mode to validate without posting
10
+ - PR listing with filters (`list-prs`)
11
+ - Configuration exclusively via `config.yaml`
12
+ - Providers LLM: OpenAI, Azure OpenAI, Gemini, Claude, Ollama, GitHub Copilot, AWS Bedrock
13
+ - Diff filtering by **excluded path prefixes** (`excluded_paths`) and/or **file extensions** (`file_extensions_filter`)
14
+
15
+ ## Documentation
16
+
17
+ - [Configuration Guide](docs/configuration.md) - Details on YAML parameters and settings.
18
+ - [Commands Reference](docs/commands.md) - Complete list of CLI commands and arguments.
19
+ - [Execution Flow](docs/execution_flow.md) - Mermaid diagram of the application's lifecycle.
20
+ - [Troubleshooting](docs/troubleshooting.md) - Common issues and solutions.
21
+
22
+ ## Output Review Format
23
+
24
+ ![Review Output Format Example](/imgs/review_output.png)
25
+
26
+ ## Installation
27
+
28
+ Install from PyPI:
29
+ s
30
+ ```bash
31
+ pip install code-review-ai-cli
32
+ ```
33
+
34
+ After installing the package, generate ready-to-edit configuration files in your working directory:
35
+
36
+ ```bash
37
+ ai-review init
38
+ ```
39
+
40
+ This copies two bundled templates:
41
+
42
+ - **`config.yaml`** — all available options with inline documentation
43
+ - **`review_prompt.md`** — default review style rules, injected into every LLM prompt
44
+
45
+ The tool looks for `config.yaml` in the **current working directory** at runtime. You can also pass a different path with `--config`:
46
+
47
+ ```bash
48
+ ai-review pr-review --config ~/configs/ai-review.yaml
49
+ ```
50
+
51
+ If you plan to run the test suite locally, also install development dependencies:
52
+
53
+ ```bash
54
+ pip install "code-review-ai-cli[dev]"
55
+ ```
56
+
57
+ ## Minimal Example
58
+
59
+ Example `config.yaml`:
60
+
61
+ ```yaml
62
+ llm:
63
+ provider: openai
64
+ model: gpt-4o
65
+
66
+ openai:
67
+ api_key: sk-xxxx
68
+
69
+ tfs:
70
+ base_url: https://dev.azure.com/your-organization
71
+ project: ProjectName
72
+ pat: xxxxxxxxx
73
+ verify_ssl: true
74
+ # ca_bundle: C:/certs/corporate-root-ca.pem
75
+
76
+ review:
77
+ verbosity: detailed
78
+ scope: diff_only
79
+ custom_prompt_file: review_prompt.md
80
+ # file limit sent to the LLM
81
+ max_diff_files: 50
82
+ # per-file limit
83
+ max_diff_lines: 2000
84
+ # extension allowlist (empty list = all files)
85
+ file_extensions_filter: [".cs", ".ts", ".py"]
86
+ # exclude path prefixes from the diff (applied before file_extensions_filter)
87
+ # leading slash is optional; add trailing slash for exact folder boundary
88
+ excluded_paths: ["libs/generated"]
89
+
90
+ pr:
91
+ auto_post_comments: false
92
+ dry_run: false
93
+ comment_mode: structured
94
+
95
+ output:
96
+ format: terminal
97
+ file: ""
98
+ color: true
99
+ ```
100
+
101
+ ## Available VS Code Tasks
102
+
103
+ - `AI Review: Pull Request (Interactive)`
104
+ - `AI Review: PR (Dry-Run)`
105
+ - `AI Review: List Active PRs`
106
+ - `AI Review: Interactive Mode`
@@ -0,0 +1,146 @@
1
+ Metadata-Version: 2.4
2
+ Name: code-review-ai-cli
3
+ Version: 2.2.0
4
+ Summary: Automated AI-powered code review CLI for Azure DevOps / TFS Pull Requests
5
+ License: MIT
6
+ Keywords: code-review,ai,azure-devops,tfs,pull-request,llm
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Environment :: Console
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Software Development :: Quality Assurance
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: requests>=2.28.0
19
+ Requires-Dist: PyYAML>=6.0
20
+ Provides-Extra: bedrock
21
+ Requires-Dist: boto3>=1.34.0; extra == "bedrock"
22
+ Provides-Extra: openai
23
+ Requires-Dist: openai>=1.0.0; extra == "openai"
24
+ Provides-Extra: gemini
25
+ Requires-Dist: google-generativeai>=0.3.0; extra == "gemini"
26
+ Provides-Extra: claude
27
+ Requires-Dist: anthropic>=0.18.0; extra == "claude"
28
+ Provides-Extra: tree-sitter
29
+ Requires-Dist: tree-sitter-languages>=1.10.2; extra == "tree-sitter"
30
+ Provides-Extra: all
31
+ Requires-Dist: boto3>=1.34.0; extra == "all"
32
+ Requires-Dist: openai>=1.0.0; extra == "all"
33
+ Requires-Dist: google-generativeai>=0.3.0; extra == "all"
34
+ Requires-Dist: anthropic>=0.18.0; extra == "all"
35
+ Requires-Dist: tree-sitter-languages>=1.10.2; extra == "all"
36
+ Provides-Extra: dev
37
+ Requires-Dist: pytest>=8.3.0; extra == "dev"
38
+ Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
39
+ Requires-Dist: pytest-mock>=3.14.0; extra == "dev"
40
+
41
+ # AI Code Review
42
+
43
+ AI Code Review is an automated AI-powered code review CLI, compatible with various LLM providers, designed for integration with Azure DevOps, whether in the cloud or on-premises. It allows you to run a review on demand or as part of a pipeline triggered before a commit or when a pull request is created.
44
+
45
+ ## Features
46
+
47
+ - AI Pull Request review (`pr-review`)
48
+ - Structured PR comments (inline + general summary)
49
+ - `dry-run` mode to validate without posting
50
+ - PR listing with filters (`list-prs`)
51
+ - Configuration exclusively via `config.yaml`
52
+ - Providers LLM: OpenAI, Azure OpenAI, Gemini, Claude, Ollama, GitHub Copilot, AWS Bedrock
53
+ - Diff filtering by **excluded path prefixes** (`excluded_paths`) and/or **file extensions** (`file_extensions_filter`)
54
+
55
+ ## Documentation
56
+
57
+ - [Configuration Guide](docs/configuration.md) - Details on YAML parameters and settings.
58
+ - [Commands Reference](docs/commands.md) - Complete list of CLI commands and arguments.
59
+ - [Execution Flow](docs/execution_flow.md) - Mermaid diagram of the application's lifecycle.
60
+ - [Troubleshooting](docs/troubleshooting.md) - Common issues and solutions.
61
+
62
+ ## Output Review Format
63
+
64
+ ![Review Output Format Example](/imgs/review_output.png)
65
+
66
+ ## Installation
67
+
68
+ Install from PyPI:
69
+ s
70
+ ```bash
71
+ pip install code-review-ai-cli
72
+ ```
73
+
74
+ After installing the package, generate ready-to-edit configuration files in your working directory:
75
+
76
+ ```bash
77
+ ai-review init
78
+ ```
79
+
80
+ This copies two bundled templates:
81
+
82
+ - **`config.yaml`** — all available options with inline documentation
83
+ - **`review_prompt.md`** — default review style rules, injected into every LLM prompt
84
+
85
+ The tool looks for `config.yaml` in the **current working directory** at runtime. You can also pass a different path with `--config`:
86
+
87
+ ```bash
88
+ ai-review pr-review --config ~/configs/ai-review.yaml
89
+ ```
90
+
91
+ If you plan to run the test suite locally, also install development dependencies:
92
+
93
+ ```bash
94
+ pip install "code-review-ai-cli[dev]"
95
+ ```
96
+
97
+ ## Minimal Example
98
+
99
+ Example `config.yaml`:
100
+
101
+ ```yaml
102
+ llm:
103
+ provider: openai
104
+ model: gpt-4o
105
+
106
+ openai:
107
+ api_key: sk-xxxx
108
+
109
+ tfs:
110
+ base_url: https://dev.azure.com/your-organization
111
+ project: ProjectName
112
+ pat: xxxxxxxxx
113
+ verify_ssl: true
114
+ # ca_bundle: C:/certs/corporate-root-ca.pem
115
+
116
+ review:
117
+ verbosity: detailed
118
+ scope: diff_only
119
+ custom_prompt_file: review_prompt.md
120
+ # file limit sent to the LLM
121
+ max_diff_files: 50
122
+ # per-file limit
123
+ max_diff_lines: 2000
124
+ # extension allowlist (empty list = all files)
125
+ file_extensions_filter: [".cs", ".ts", ".py"]
126
+ # exclude path prefixes from the diff (applied before file_extensions_filter)
127
+ # leading slash is optional; add trailing slash for exact folder boundary
128
+ excluded_paths: ["libs/generated"]
129
+
130
+ pr:
131
+ auto_post_comments: false
132
+ dry_run: false
133
+ comment_mode: structured
134
+
135
+ output:
136
+ format: terminal
137
+ file: ""
138
+ color: true
139
+ ```
140
+
141
+ ## Available VS Code Tasks
142
+
143
+ - `AI Review: Pull Request (Interactive)`
144
+ - `AI Review: PR (Dry-Run)`
145
+ - `AI Review: List Active PRs`
146
+ - `AI Review: Interactive Mode`
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code-review-ai-cli"
7
- version = "2.1.0"
7
+ version = "2.2.0"
8
8
  description = "Automated AI-powered code review CLI for Azure DevOps / TFS Pull Requests"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -79,7 +79,7 @@ SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
79
79
  PROJECT_ROOT = _ensure_project_root_on_path(__file__)
80
80
 
81
81
  from src.config import ReviewConfig, VALID_PROVIDERS # noqa: E402
82
- from src.git_utils import GitUtils, GitError # noqa: E402
82
+ from src.git_utils import GitUtils # noqa: E402
83
83
  from src.llm_client import LLMClient, LLMError # noqa: E402
84
84
  from src.formatter import ReviewFormatter, Colors, save_output # noqa: E402
85
85
  from src import __version__ as VERSION # noqa: E402
@@ -426,6 +426,8 @@ def run_pr_review_workflow(args: argparse.Namespace, config: ReviewConfig,
426
426
  repo_name,
427
427
  pr_id,
428
428
  review_scope=config.review_scope,
429
+ excluded_paths=config.excluded_paths or None,
430
+ file_extensions_filter=config.file_extensions_filter or None,
429
431
  )
430
432
  except TFSError as exc:
431
433
  print(formatter.format_error(str(exc)))
@@ -451,17 +453,6 @@ def run_pr_review_workflow(args: argparse.Namespace, config: ReviewConfig,
451
453
  git_utils = GitUtils.__new__(GitUtils)
452
454
  git_utils.repo_path = os.getcwd()
453
455
 
454
- # Filter extensions before limiting/truncating the diff sent to the LLM
455
- if config.file_extensions_filter:
456
- try:
457
- diff = git_utils.filter_diff_by_extensions(
458
- diff,
459
- config.file_extensions_filter,
460
- )
461
- except GitError as exc:
462
- print(formatter.format_warning(str(exc)))
463
- return 0
464
-
465
456
  # Keep only added lines (+): ignore context and removed lines
466
457
  diff = git_utils.filter_diff_additions_only(diff)
467
458
  if not diff.strip():
@@ -93,7 +93,8 @@ class ReviewConfig:
93
93
  max_scope_lines: int = 250 # Max lines in a single scope block before fallback to file_skeleton
94
94
  adaptive_context_lines: int = 10 # Context lines for Adaptive Diff fallback
95
95
  custom_prompt_file: str = "review_prompt.md" # Markdown file with extra rules/context
96
- file_extensions_filter: list = field(default_factory=list)
96
+ file_extensions_filter: list = field(default_factory=list) # File extensions to include (empty = all)
97
+ excluded_paths: list = field(default_factory=list) # Folder path segments to exclude from diff
97
98
 
98
99
  # --- PR Review ----------------------------------------------------
99
100
  auto_post_comments: bool = False # Post comments automatically
@@ -222,6 +223,7 @@ class ReviewConfig:
222
223
  "adaptive_context_lines": ("review", "adaptive_context_lines"),
223
224
  "custom_prompt_file": ("review", "custom_prompt_file"),
224
225
  "file_extensions_filter": ("review", "file_extensions_filter"),
226
+ "excluded_paths": ("review", "excluded_paths"),
225
227
  # PR
226
228
  "auto_post_comments": ("pr", "auto_post_comments"),
227
229
  "dry_run": ("pr", "dry_run"),
@@ -189,44 +189,6 @@ class GitUtils:
189
189
  )
190
190
  return limited, True, omitted_files
191
191
 
192
- def filter_diff_by_extensions(self, diff: str, extensions: list[str]) -> str:
193
- """
194
- Filters the diff to include only files with specific extensions.
195
-
196
- Args:
197
- diff: The full diff.
198
- extensions: List of extensions (e.g., ['.py', '.js', '.cs']).
199
- """
200
- if not extensions:
201
- return diff
202
-
203
- filtered_sections = []
204
- current_section: list[str] = []
205
- include_section = False
206
-
207
- for line in diff.split("\n"):
208
- if line.startswith("diff --git"):
209
- # Save previous section if applicable
210
- if include_section and current_section:
211
- filtered_sections.append("\n".join(current_section))
212
- current_section = [line]
213
- # Check if file has an allowed extension
214
- file_path = line.split(" b/")[-1] if " b/" in line else ""
215
- include_section = any(file_path.endswith(ext) for ext in extensions)
216
- else:
217
- current_section.append(line)
218
-
219
- # Last section
220
- if include_section and current_section:
221
- filtered_sections.append("\n".join(current_section))
222
-
223
- result = "\n".join(filtered_sections)
224
- if not result.strip():
225
- raise GitError(
226
- f"After filtering by extensions {extensions}, no changes remain."
227
- )
228
- return result
229
-
230
192
  def truncate_diff(self, diff: str, max_lines: int = 2000) -> tuple[str, bool]:
231
193
  """
232
194
  Kept for compatibility: applies per-file truncation when
@@ -13,7 +13,7 @@
13
13
  llm:
14
14
  provider: openai
15
15
 
16
- # Model to use (empty = provider default)
16
+ # Model to use (empty = provider default)
17
17
  # Examples:
18
18
  # openai: gpt-4o, gpt-4-turbo, gpt-4
19
19
  # gemini: gemini-1.5-pro, gemini-pro, gemini-2.0-flash
@@ -91,7 +91,7 @@ review:
91
91
  max_diff_lines: 4500
92
92
 
93
93
  # Max changed logical blocks for Enclosing Scopes strategy (diff_only mode)
94
- max_scope_blocks: 3
94
+ max_scope_blocks: 10
95
95
 
96
96
  # Max lines in a single enclosing scope before falling back to file_skeleton
97
97
  # (prevents sending entire large classes to the LLM)
@@ -100,6 +100,12 @@ review:
100
100
  # Surrounding lines to keep for Adaptive Diff fallback (diff_only mode)
101
101
  adaptive_context_lines: 10
102
102
 
103
+ # Exclude paths from the diff by prefix (empty list = no exclusions).
104
+ # Files whose path starts with a listed prefix are excluded.
105
+ # Matching is case-insensitive.
106
+ # Example: ["IoT/_input/packages", "libs/generated"]
107
+ excluded_paths: []
108
+
103
109
  # Filter by file extensions (empty list = all files)
104
110
  # Example: [".cs", ".ts"]
105
111
  file_extensions_filter: []
@@ -301,7 +301,9 @@ class TFSClient:
301
301
  return files
302
302
 
303
303
  def get_pull_request_diff(self, repository: str, pr_id: int,
304
- review_scope: str = "diff_only") -> str:
304
+ review_scope: str = "diff_only",
305
+ excluded_paths: list[str] | None = None,
306
+ file_extensions_filter: list[str] | None = None) -> str:
305
307
  """
306
308
  Gets the diff of a specific Pull Request.
307
309
 
@@ -317,16 +319,28 @@ class TFSClient:
317
319
  with ``+``, producing a pseudo-diff that represents the complete file
318
320
  as added content.
319
321
 
322
+ Files are filtered **before** any HTTP content request is made, so
323
+ excluded or extension-mismatched files incur no network cost.
324
+
320
325
  Args:
321
326
  repository: Repository name.
322
327
  pr_id: Pull Request ID.
323
328
  review_scope: ``"diff_only"`` (default) or ``"full_code"``.
329
+ excluded_paths: List of path prefixes to skip (case-insensitive,
330
+ leading slash optional). Files whose path starts with any
331
+ prefix are excluded before content is fetched.
332
+ Example: ``["/Libs/", "/IoT/_input/packages"]``.
333
+ file_extensions_filter: Allowlist of file extensions
334
+ (case-insensitive). When non-empty, only files whose path ends
335
+ with one of the listed extensions are processed.
336
+ Example: ``[".cs", ".ts"]``.
324
337
 
325
338
  Returns:
326
339
  Diff as text, ready to be passed to the LLM client.
327
340
 
328
341
  Raises:
329
- TFSError: If the PR has no iterations or contains no file changes.
342
+ TFSError: If the PR has no iterations or contains no file changes
343
+ after filtering.
330
344
  """
331
345
  # Get PR details
332
346
  path = f"git/repositories/{repository}/pullrequests/{pr_id}"
@@ -352,6 +366,14 @@ class TFSClient:
352
366
 
353
367
  review_scope = (review_scope or "diff_only").lower()
354
368
 
369
+ # Normalise filters once before the loop (forward slashes, lower-case).
370
+ # excluded_paths: strip optional leading slash so "Libs/" == "/Libs/".
371
+ _excl_prefixes = [
372
+ p.replace("\\", "/").lstrip("/").lower()
373
+ for p in (excluded_paths or [])
374
+ ]
375
+ _ext_filter = [e.lower() for e in (file_extensions_filter or [])]
376
+
355
377
  # Build diff from the changes
356
378
  diff_parts = []
357
379
  for change in changes.get("changeEntries", []):
@@ -363,6 +385,21 @@ class TFSClient:
363
385
  if item.get("isFolder"):
364
386
  continue
365
387
 
388
+ # --- Early-exit filters (no HTTP request made for skipped files) ---
389
+ # Normalise once: strip leading slash, lower-case, forward slashes.
390
+ norm_path = file_path.replace("\\", "/").lstrip("/").lower()
391
+
392
+ if _excl_prefixes and any(
393
+ norm_path.startswith(excl) for excl in _excl_prefixes
394
+ ):
395
+ continue
396
+
397
+ if _ext_filter and not any(
398
+ norm_path.endswith(ext) for ext in _ext_filter
399
+ ):
400
+ continue
401
+ # ------------------------------------------------------------------
402
+
366
403
  if review_scope == "full_code":
367
404
  diff_parts.extend(
368
405
  self._build_full_code_diff_part(
@@ -388,7 +425,7 @@ class TFSClient:
388
425
  diff_parts.append("")
389
426
 
390
427
  if not diff_parts:
391
- raise TFSError(f"PR #{pr_id} contains no file changes.")
428
+ raise TFSError(f"PR #{pr_id} contains no file changes after filtering.")
392
429
 
393
430
  return "\n".join(diff_parts)
394
431