code-review-ai-cli 1.2.0__tar.gz → 1.3.1__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.
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/PKG-INFO +18 -79
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/README.md +18 -79
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/code_review_ai_cli.egg-info/PKG-INFO +18 -79
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/code_review_ai_cli.egg-info/SOURCES.txt +2 -0
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/pyproject.toml +1 -1
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/src/ai_review.py +65 -25
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/src/config.py +11 -3
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/src/git_utils.py +112 -2
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/src/llm_client.py +0 -18
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/src/prompts/config.yaml.template +10 -3
- code_review_ai_cli-1.3.1/src/rag_engine.py +162 -0
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/src/tfs_client.py +28 -134
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/tests/test_ai_review.py +17 -7
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/tests/test_config.py +2 -2
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/tests/test_git_utils.py +153 -1
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/tests/test_llm_client.py +0 -1
- code_review_ai_cli-1.3.1/tests/test_rag_engine.py +250 -0
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/tests/test_tfs_client.py +66 -87
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/code_review_ai_cli.egg-info/dependency_links.txt +0 -0
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/code_review_ai_cli.egg-info/entry_points.txt +0 -0
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/code_review_ai_cli.egg-info/requires.txt +0 -0
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/code_review_ai_cli.egg-info/top_level.txt +0 -0
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/setup.cfg +0 -0
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/src/__init__.py +0 -0
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/src/formatter.py +0 -0
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/src/prompts/review_context.example.md +0 -0
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/src/usage_tracker.py +0 -0
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/tests/test_formatter.py +0 -0
- {code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/tests/test_usage_tracker.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-review-ai-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.1
|
|
4
4
|
Summary: Automated AI-powered code review CLI for Azure DevOps / TFS Pull Requests
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: code-review,ai,azure-devops,tfs,pull-request,llm
|
|
@@ -40,6 +40,8 @@ Requires-Dist: pytest-mock>=3.14.0; extra == "dev"
|
|
|
40
40
|
Automated code review tool with Pull Request integration for Azure DevOps/TFS and support for multiple LLM providers.
|
|
41
41
|
**Documentation where** [docs/index.md](docs/index.md) for complete guides on CLI usage, LLM configuration, and architecture.
|
|
42
42
|
|
|
43
|
+
> **The CLI must be run from inside the local clone of the repository being reviewed.**
|
|
44
|
+
|
|
43
45
|
## Features
|
|
44
46
|
|
|
45
47
|
- **AI Pull Request Review** — Automated code analysis with configurable LLM providers
|
|
@@ -48,6 +50,7 @@ Automated code review tool with Pull Request integration for Azure DevOps/TFS an
|
|
|
48
50
|
- **Multiple LLM Providers** — OpenAI, Azure OpenAI, Gemini, Claude, Ollama, GitHub Copilot, AWS Bedrock
|
|
49
51
|
- **Smart Filtering** — Filter by file extensions, limit diff size
|
|
50
52
|
- **Project-aware PR Context** — Sends repository and linked work item context while restricting findings to modified PR lines
|
|
53
|
+
- **RAG Context** — Enriches the review with related code snippets found via `git grep` in the local repository
|
|
51
54
|
- **Single Reviewer Context** — One Markdown context file with local override support
|
|
52
55
|
- **Usage Tracking** — Store per-PR token usage and optional cost estimates
|
|
53
56
|
- **Interactive CLI** — Menu-driven selection and confirmation
|
|
@@ -93,21 +96,6 @@ Creates:
|
|
|
93
96
|
- `review_context.local.md` — Local reviewer context override, ignored by git
|
|
94
97
|
- `.gitignore` entry for `review_context.local.md`
|
|
95
98
|
|
|
96
|
-
### 3. Run Your First Review
|
|
97
|
-
|
|
98
|
-
```bash
|
|
99
|
-
# List active PRs
|
|
100
|
-
ai-review list-prs
|
|
101
|
-
|
|
102
|
-
# Review a specific PR
|
|
103
|
-
ai-review pr-review 42
|
|
104
|
-
|
|
105
|
-
# Dry-run (preview without posting)
|
|
106
|
-
ai-review pr-review 42 --dry-run
|
|
107
|
-
|
|
108
|
-
# Check stored token/cost usage
|
|
109
|
-
ai-review usage
|
|
110
|
-
```
|
|
111
99
|
|
|
112
100
|
## Configuration File
|
|
113
101
|
|
|
@@ -129,11 +117,14 @@ tfs:
|
|
|
129
117
|
review:
|
|
130
118
|
language: pt
|
|
131
119
|
verbosity: detailed # or: quick, security
|
|
132
|
-
scope: diff_with_context # diff_with_context, diff_only
|
|
120
|
+
scope: diff_with_context # diff_with_context, diff_only
|
|
133
121
|
file_extensions_filter: [".cs", ".ts", ".py"]
|
|
134
122
|
max_diff_files: 50
|
|
135
123
|
max_comments_to_post: 20
|
|
136
124
|
custom_prompt_file: review_context.local.md
|
|
125
|
+
rag:
|
|
126
|
+
enabled: true # requires local branch == PR target
|
|
127
|
+
max_chars: 40000
|
|
137
128
|
project_context:
|
|
138
129
|
enabled: true
|
|
139
130
|
mode: on_demand # on_demand, full
|
|
@@ -147,42 +138,20 @@ review:
|
|
|
147
138
|
max_items: 20
|
|
148
139
|
```
|
|
149
140
|
|
|
150
|
-
|
|
151
|
-
source-branch change packets, full changed-file contents as read-only context,
|
|
152
|
-
linked work item documentation, and a repository manifest, then the model
|
|
153
|
-
requests any extra files it needs. Inline PR comments must still be grounded in
|
|
154
|
-
actual changed lines from the change packets. Set
|
|
155
|
-
`review.project_context.mode: full` to send the full eligible repository
|
|
156
|
-
snapshot instead. Bedrock uses a default estimated prompt budget of 180000
|
|
157
|
-
tokens; override it with `llm.max_prompt_tokens` if your model supports more or
|
|
158
|
-
less.
|
|
159
|
-
|
|
160
|
-
Reviewer context is loaded from exactly one Markdown file. By default the CLI
|
|
161
|
-
uses `review_context.local.md` when it exists, otherwise it falls back to the
|
|
162
|
-
packaged `src/prompts/review_context.example.md`. Keep local team tweaks in
|
|
163
|
-
`review_context.local.md`; it is gitignored so the canonical context cannot
|
|
164
|
-
drift across machines.
|
|
141
|
+
### 3. Run Your First Review
|
|
165
142
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
source-branch grounding, duplicate checks, and comment cap regardless of model.
|
|
143
|
+
```bash
|
|
144
|
+
# List active PRs
|
|
145
|
+
ai-review list-prs
|
|
170
146
|
|
|
171
|
-
|
|
147
|
+
# Review a specific PR
|
|
148
|
+
ai-review pr-review 42
|
|
172
149
|
|
|
173
|
-
|
|
150
|
+
# Dry-run (preview without posting)
|
|
151
|
+
ai-review pr-review 42 --dry-run
|
|
174
152
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
ai_review.py # CLI entry point
|
|
178
|
-
config.py # Configuration management
|
|
179
|
-
llm_client.py # LLM provider abstraction
|
|
180
|
-
tfs_client.py # Azure DevOps integration
|
|
181
|
-
git_utils.py # Git diff processing
|
|
182
|
-
formatter.py # Output formatting (terminal, markdown, JSON)
|
|
183
|
-
|
|
184
|
-
tests/
|
|
185
|
-
test_*.py # Unit and integration tests
|
|
153
|
+
# Check stored token/cost usage
|
|
154
|
+
ai-review usage
|
|
186
155
|
```
|
|
187
156
|
|
|
188
157
|
### Run Tests
|
|
@@ -205,33 +174,3 @@ ruff check src/ tests/
|
|
|
205
174
|
# Type checking (if using mypy)
|
|
206
175
|
mypy src/
|
|
207
176
|
```
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
## VS Code Integration
|
|
211
|
-
|
|
212
|
-
Predefined tasks for quick execution in VS Code:
|
|
213
|
-
|
|
214
|
-
### Available Tasks
|
|
215
|
-
|
|
216
|
-
1. **AI Review: Pull Request (Interactive)**
|
|
217
|
-
- Interactive mode with main menu
|
|
218
|
-
- Run with: `Ctrl+Shift+B` → Select task
|
|
219
|
-
|
|
220
|
-
2. **AI Review: PR (Dry-Run)**
|
|
221
|
-
- Dry-run for a specific PR
|
|
222
|
-
- Prompts for PR ID
|
|
223
|
-
|
|
224
|
-
3. **AI Review: List Active PRs**
|
|
225
|
-
- Lists active PRs
|
|
226
|
-
- Quick diagnostics
|
|
227
|
-
|
|
228
|
-
4. **AI Review: Interactive Mode**
|
|
229
|
-
- Full tool menu
|
|
230
|
-
- Runs in background
|
|
231
|
-
|
|
232
|
-
### How to run tasks
|
|
233
|
-
|
|
234
|
-
In VS Code:
|
|
235
|
-
1. `Ctrl+Shift+P` → "Tasks: Run Task"
|
|
236
|
-
2. Select the desired task
|
|
237
|
-
3. Fill in parameters if needed
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
Automated code review tool with Pull Request integration for Azure DevOps/TFS and support for multiple LLM providers.
|
|
4
4
|
**Documentation where** [docs/index.md](docs/index.md) for complete guides on CLI usage, LLM configuration, and architecture.
|
|
5
5
|
|
|
6
|
+
> **The CLI must be run from inside the local clone of the repository being reviewed.**
|
|
7
|
+
|
|
6
8
|
## Features
|
|
7
9
|
|
|
8
10
|
- **AI Pull Request Review** — Automated code analysis with configurable LLM providers
|
|
@@ -11,6 +13,7 @@ Automated code review tool with Pull Request integration for Azure DevOps/TFS an
|
|
|
11
13
|
- **Multiple LLM Providers** — OpenAI, Azure OpenAI, Gemini, Claude, Ollama, GitHub Copilot, AWS Bedrock
|
|
12
14
|
- **Smart Filtering** — Filter by file extensions, limit diff size
|
|
13
15
|
- **Project-aware PR Context** — Sends repository and linked work item context while restricting findings to modified PR lines
|
|
16
|
+
- **RAG Context** — Enriches the review with related code snippets found via `git grep` in the local repository
|
|
14
17
|
- **Single Reviewer Context** — One Markdown context file with local override support
|
|
15
18
|
- **Usage Tracking** — Store per-PR token usage and optional cost estimates
|
|
16
19
|
- **Interactive CLI** — Menu-driven selection and confirmation
|
|
@@ -56,21 +59,6 @@ Creates:
|
|
|
56
59
|
- `review_context.local.md` — Local reviewer context override, ignored by git
|
|
57
60
|
- `.gitignore` entry for `review_context.local.md`
|
|
58
61
|
|
|
59
|
-
### 3. Run Your First Review
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
# List active PRs
|
|
63
|
-
ai-review list-prs
|
|
64
|
-
|
|
65
|
-
# Review a specific PR
|
|
66
|
-
ai-review pr-review 42
|
|
67
|
-
|
|
68
|
-
# Dry-run (preview without posting)
|
|
69
|
-
ai-review pr-review 42 --dry-run
|
|
70
|
-
|
|
71
|
-
# Check stored token/cost usage
|
|
72
|
-
ai-review usage
|
|
73
|
-
```
|
|
74
62
|
|
|
75
63
|
## Configuration File
|
|
76
64
|
|
|
@@ -92,11 +80,14 @@ tfs:
|
|
|
92
80
|
review:
|
|
93
81
|
language: pt
|
|
94
82
|
verbosity: detailed # or: quick, security
|
|
95
|
-
scope: diff_with_context # diff_with_context, diff_only
|
|
83
|
+
scope: diff_with_context # diff_with_context, diff_only
|
|
96
84
|
file_extensions_filter: [".cs", ".ts", ".py"]
|
|
97
85
|
max_diff_files: 50
|
|
98
86
|
max_comments_to_post: 20
|
|
99
87
|
custom_prompt_file: review_context.local.md
|
|
88
|
+
rag:
|
|
89
|
+
enabled: true # requires local branch == PR target
|
|
90
|
+
max_chars: 40000
|
|
100
91
|
project_context:
|
|
101
92
|
enabled: true
|
|
102
93
|
mode: on_demand # on_demand, full
|
|
@@ -110,42 +101,20 @@ review:
|
|
|
110
101
|
max_items: 20
|
|
111
102
|
```
|
|
112
103
|
|
|
113
|
-
|
|
114
|
-
source-branch change packets, full changed-file contents as read-only context,
|
|
115
|
-
linked work item documentation, and a repository manifest, then the model
|
|
116
|
-
requests any extra files it needs. Inline PR comments must still be grounded in
|
|
117
|
-
actual changed lines from the change packets. Set
|
|
118
|
-
`review.project_context.mode: full` to send the full eligible repository
|
|
119
|
-
snapshot instead. Bedrock uses a default estimated prompt budget of 180000
|
|
120
|
-
tokens; override it with `llm.max_prompt_tokens` if your model supports more or
|
|
121
|
-
less.
|
|
122
|
-
|
|
123
|
-
Reviewer context is loaded from exactly one Markdown file. By default the CLI
|
|
124
|
-
uses `review_context.local.md` when it exists, otherwise it falls back to the
|
|
125
|
-
packaged `src/prompts/review_context.example.md`. Keep local team tweaks in
|
|
126
|
-
`review_context.local.md`; it is gitignored so the canonical context cannot
|
|
127
|
-
drift across machines.
|
|
104
|
+
### 3. Run Your First Review
|
|
128
105
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
source-branch grounding, duplicate checks, and comment cap regardless of model.
|
|
106
|
+
```bash
|
|
107
|
+
# List active PRs
|
|
108
|
+
ai-review list-prs
|
|
133
109
|
|
|
134
|
-
|
|
110
|
+
# Review a specific PR
|
|
111
|
+
ai-review pr-review 42
|
|
135
112
|
|
|
136
|
-
|
|
113
|
+
# Dry-run (preview without posting)
|
|
114
|
+
ai-review pr-review 42 --dry-run
|
|
137
115
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
ai_review.py # CLI entry point
|
|
141
|
-
config.py # Configuration management
|
|
142
|
-
llm_client.py # LLM provider abstraction
|
|
143
|
-
tfs_client.py # Azure DevOps integration
|
|
144
|
-
git_utils.py # Git diff processing
|
|
145
|
-
formatter.py # Output formatting (terminal, markdown, JSON)
|
|
146
|
-
|
|
147
|
-
tests/
|
|
148
|
-
test_*.py # Unit and integration tests
|
|
116
|
+
# Check stored token/cost usage
|
|
117
|
+
ai-review usage
|
|
149
118
|
```
|
|
150
119
|
|
|
151
120
|
### Run Tests
|
|
@@ -167,34 +136,4 @@ ruff check src/ tests/
|
|
|
167
136
|
|
|
168
137
|
# Type checking (if using mypy)
|
|
169
138
|
mypy src/
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
## VS Code Integration
|
|
174
|
-
|
|
175
|
-
Predefined tasks for quick execution in VS Code:
|
|
176
|
-
|
|
177
|
-
### Available Tasks
|
|
178
|
-
|
|
179
|
-
1. **AI Review: Pull Request (Interactive)**
|
|
180
|
-
- Interactive mode with main menu
|
|
181
|
-
- Run with: `Ctrl+Shift+B` → Select task
|
|
182
|
-
|
|
183
|
-
2. **AI Review: PR (Dry-Run)**
|
|
184
|
-
- Dry-run for a specific PR
|
|
185
|
-
- Prompts for PR ID
|
|
186
|
-
|
|
187
|
-
3. **AI Review: List Active PRs**
|
|
188
|
-
- Lists active PRs
|
|
189
|
-
- Quick diagnostics
|
|
190
|
-
|
|
191
|
-
4. **AI Review: Interactive Mode**
|
|
192
|
-
- Full tool menu
|
|
193
|
-
- Runs in background
|
|
194
|
-
|
|
195
|
-
### How to run tasks
|
|
196
|
-
|
|
197
|
-
In VS Code:
|
|
198
|
-
1. `Ctrl+Shift+P` → "Tasks: Run Task"
|
|
199
|
-
2. Select the desired task
|
|
200
|
-
3. Fill in parameters if needed
|
|
139
|
+
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-review-ai-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.1
|
|
4
4
|
Summary: Automated AI-powered code review CLI for Azure DevOps / TFS Pull Requests
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: code-review,ai,azure-devops,tfs,pull-request,llm
|
|
@@ -40,6 +40,8 @@ Requires-Dist: pytest-mock>=3.14.0; extra == "dev"
|
|
|
40
40
|
Automated code review tool with Pull Request integration for Azure DevOps/TFS and support for multiple LLM providers.
|
|
41
41
|
**Documentation where** [docs/index.md](docs/index.md) for complete guides on CLI usage, LLM configuration, and architecture.
|
|
42
42
|
|
|
43
|
+
> **The CLI must be run from inside the local clone of the repository being reviewed.**
|
|
44
|
+
|
|
43
45
|
## Features
|
|
44
46
|
|
|
45
47
|
- **AI Pull Request Review** — Automated code analysis with configurable LLM providers
|
|
@@ -48,6 +50,7 @@ Automated code review tool with Pull Request integration for Azure DevOps/TFS an
|
|
|
48
50
|
- **Multiple LLM Providers** — OpenAI, Azure OpenAI, Gemini, Claude, Ollama, GitHub Copilot, AWS Bedrock
|
|
49
51
|
- **Smart Filtering** — Filter by file extensions, limit diff size
|
|
50
52
|
- **Project-aware PR Context** — Sends repository and linked work item context while restricting findings to modified PR lines
|
|
53
|
+
- **RAG Context** — Enriches the review with related code snippets found via `git grep` in the local repository
|
|
51
54
|
- **Single Reviewer Context** — One Markdown context file with local override support
|
|
52
55
|
- **Usage Tracking** — Store per-PR token usage and optional cost estimates
|
|
53
56
|
- **Interactive CLI** — Menu-driven selection and confirmation
|
|
@@ -93,21 +96,6 @@ Creates:
|
|
|
93
96
|
- `review_context.local.md` — Local reviewer context override, ignored by git
|
|
94
97
|
- `.gitignore` entry for `review_context.local.md`
|
|
95
98
|
|
|
96
|
-
### 3. Run Your First Review
|
|
97
|
-
|
|
98
|
-
```bash
|
|
99
|
-
# List active PRs
|
|
100
|
-
ai-review list-prs
|
|
101
|
-
|
|
102
|
-
# Review a specific PR
|
|
103
|
-
ai-review pr-review 42
|
|
104
|
-
|
|
105
|
-
# Dry-run (preview without posting)
|
|
106
|
-
ai-review pr-review 42 --dry-run
|
|
107
|
-
|
|
108
|
-
# Check stored token/cost usage
|
|
109
|
-
ai-review usage
|
|
110
|
-
```
|
|
111
99
|
|
|
112
100
|
## Configuration File
|
|
113
101
|
|
|
@@ -129,11 +117,14 @@ tfs:
|
|
|
129
117
|
review:
|
|
130
118
|
language: pt
|
|
131
119
|
verbosity: detailed # or: quick, security
|
|
132
|
-
scope: diff_with_context # diff_with_context, diff_only
|
|
120
|
+
scope: diff_with_context # diff_with_context, diff_only
|
|
133
121
|
file_extensions_filter: [".cs", ".ts", ".py"]
|
|
134
122
|
max_diff_files: 50
|
|
135
123
|
max_comments_to_post: 20
|
|
136
124
|
custom_prompt_file: review_context.local.md
|
|
125
|
+
rag:
|
|
126
|
+
enabled: true # requires local branch == PR target
|
|
127
|
+
max_chars: 40000
|
|
137
128
|
project_context:
|
|
138
129
|
enabled: true
|
|
139
130
|
mode: on_demand # on_demand, full
|
|
@@ -147,42 +138,20 @@ review:
|
|
|
147
138
|
max_items: 20
|
|
148
139
|
```
|
|
149
140
|
|
|
150
|
-
|
|
151
|
-
source-branch change packets, full changed-file contents as read-only context,
|
|
152
|
-
linked work item documentation, and a repository manifest, then the model
|
|
153
|
-
requests any extra files it needs. Inline PR comments must still be grounded in
|
|
154
|
-
actual changed lines from the change packets. Set
|
|
155
|
-
`review.project_context.mode: full` to send the full eligible repository
|
|
156
|
-
snapshot instead. Bedrock uses a default estimated prompt budget of 180000
|
|
157
|
-
tokens; override it with `llm.max_prompt_tokens` if your model supports more or
|
|
158
|
-
less.
|
|
159
|
-
|
|
160
|
-
Reviewer context is loaded from exactly one Markdown file. By default the CLI
|
|
161
|
-
uses `review_context.local.md` when it exists, otherwise it falls back to the
|
|
162
|
-
packaged `src/prompts/review_context.example.md`. Keep local team tweaks in
|
|
163
|
-
`review_context.local.md`; it is gitignored so the canonical context cannot
|
|
164
|
-
drift across machines.
|
|
141
|
+
### 3. Run Your First Review
|
|
165
142
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
source-branch grounding, duplicate checks, and comment cap regardless of model.
|
|
143
|
+
```bash
|
|
144
|
+
# List active PRs
|
|
145
|
+
ai-review list-prs
|
|
170
146
|
|
|
171
|
-
|
|
147
|
+
# Review a specific PR
|
|
148
|
+
ai-review pr-review 42
|
|
172
149
|
|
|
173
|
-
|
|
150
|
+
# Dry-run (preview without posting)
|
|
151
|
+
ai-review pr-review 42 --dry-run
|
|
174
152
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
ai_review.py # CLI entry point
|
|
178
|
-
config.py # Configuration management
|
|
179
|
-
llm_client.py # LLM provider abstraction
|
|
180
|
-
tfs_client.py # Azure DevOps integration
|
|
181
|
-
git_utils.py # Git diff processing
|
|
182
|
-
formatter.py # Output formatting (terminal, markdown, JSON)
|
|
183
|
-
|
|
184
|
-
tests/
|
|
185
|
-
test_*.py # Unit and integration tests
|
|
153
|
+
# Check stored token/cost usage
|
|
154
|
+
ai-review usage
|
|
186
155
|
```
|
|
187
156
|
|
|
188
157
|
### Run Tests
|
|
@@ -205,33 +174,3 @@ ruff check src/ tests/
|
|
|
205
174
|
# Type checking (if using mypy)
|
|
206
175
|
mypy src/
|
|
207
176
|
```
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
## VS Code Integration
|
|
211
|
-
|
|
212
|
-
Predefined tasks for quick execution in VS Code:
|
|
213
|
-
|
|
214
|
-
### Available Tasks
|
|
215
|
-
|
|
216
|
-
1. **AI Review: Pull Request (Interactive)**
|
|
217
|
-
- Interactive mode with main menu
|
|
218
|
-
- Run with: `Ctrl+Shift+B` → Select task
|
|
219
|
-
|
|
220
|
-
2. **AI Review: PR (Dry-Run)**
|
|
221
|
-
- Dry-run for a specific PR
|
|
222
|
-
- Prompts for PR ID
|
|
223
|
-
|
|
224
|
-
3. **AI Review: List Active PRs**
|
|
225
|
-
- Lists active PRs
|
|
226
|
-
- Quick diagnostics
|
|
227
|
-
|
|
228
|
-
4. **AI Review: Interactive Mode**
|
|
229
|
-
- Full tool menu
|
|
230
|
-
- Runs in background
|
|
231
|
-
|
|
232
|
-
### How to run tasks
|
|
233
|
-
|
|
234
|
-
In VS Code:
|
|
235
|
-
1. `Ctrl+Shift+P` → "Tasks: Run Task"
|
|
236
|
-
2. Select the desired task
|
|
237
|
-
3. Fill in parameters if needed
|
{code_review_ai_cli-1.2.0 → code_review_ai_cli-1.3.1}/code_review_ai_cli.egg-info/SOURCES.txt
RENAMED
|
@@ -12,6 +12,7 @@ src/config.py
|
|
|
12
12
|
src/formatter.py
|
|
13
13
|
src/git_utils.py
|
|
14
14
|
src/llm_client.py
|
|
15
|
+
src/rag_engine.py
|
|
15
16
|
src/tfs_client.py
|
|
16
17
|
src/usage_tracker.py
|
|
17
18
|
src/prompts/config.yaml.template
|
|
@@ -21,5 +22,6 @@ tests/test_config.py
|
|
|
21
22
|
tests/test_formatter.py
|
|
22
23
|
tests/test_git_utils.py
|
|
23
24
|
tests/test_llm_client.py
|
|
25
|
+
tests/test_rag_engine.py
|
|
24
26
|
tests/test_tfs_client.py
|
|
25
27
|
tests/test_usage_tracker.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "code-review-ai-cli"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.3.1"
|
|
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"
|
|
@@ -84,6 +84,7 @@ from src.config import ReviewConfig, VALID_PROVIDERS
|
|
|
84
84
|
from src.git_utils import GitUtils, GitError
|
|
85
85
|
from src.llm_client import LLMClient, LLMError
|
|
86
86
|
from src.formatter import ReviewFormatter, Colors, save_output
|
|
87
|
+
from src.rag_engine import obter_contexto_rag
|
|
87
88
|
from src.usage_tracker import (
|
|
88
89
|
append_usage_record,
|
|
89
90
|
build_pr_usage_record,
|
|
@@ -94,7 +95,7 @@ from src.usage_tracker import (
|
|
|
94
95
|
from src import __version__ as VERSION
|
|
95
96
|
|
|
96
97
|
|
|
97
|
-
REVIEW_SCOPE_CHOICES = ["diff_only", "diff_with_context"
|
|
98
|
+
REVIEW_SCOPE_CHOICES = ["diff_only", "diff_with_context"]
|
|
98
99
|
|
|
99
100
|
|
|
100
101
|
def _get_spinner_frames() -> list[str]:
|
|
@@ -263,7 +264,7 @@ def _add_global_options(parser: argparse.ArgumentParser) -> None:
|
|
|
263
264
|
"--review-scope", default=None,
|
|
264
265
|
choices=REVIEW_SCOPE_CHOICES,
|
|
265
266
|
help=(
|
|
266
|
-
"Review scope: diff_with_context (default)
|
|
267
|
+
"Review scope: diff_with_context (default) or diff_only"
|
|
267
268
|
)
|
|
268
269
|
)
|
|
269
270
|
group_review.add_argument(
|
|
@@ -333,11 +334,6 @@ def _review_scope_context_note(review_scope: str) -> str:
|
|
|
333
334
|
"Context will be used for understanding only; review comments remain "
|
|
334
335
|
"limited to modified PR lines."
|
|
335
336
|
)
|
|
336
|
-
if scope == "full_code":
|
|
337
|
-
return (
|
|
338
|
-
"Review is running in full_code mode; full changed files are context, "
|
|
339
|
-
"but comments remain limited to actual PR changes."
|
|
340
|
-
)
|
|
341
337
|
return "Review is running in diff_only mode."
|
|
342
338
|
|
|
343
339
|
|
|
@@ -786,7 +782,6 @@ def _comment_mentions_non_anchor_terms(comment: dict, anchor_text: str) -> bool:
|
|
|
786
782
|
comment.get("comment", ""),
|
|
787
783
|
comment.get("anchor_code", ""),
|
|
788
784
|
comment.get("problematic_code", ""),
|
|
789
|
-
comment.get("evidence", ""),
|
|
790
785
|
):
|
|
791
786
|
if term not in anchor_text:
|
|
792
787
|
return True
|
|
@@ -904,15 +899,15 @@ def _filter_comments_to_grounded_source_lines(
|
|
|
904
899
|
discarded_grounding.append(comment)
|
|
905
900
|
continue
|
|
906
901
|
|
|
907
|
-
if not
|
|
902
|
+
if not evidence:
|
|
908
903
|
discarded_grounding.append(comment)
|
|
909
904
|
continue
|
|
910
905
|
|
|
911
|
-
if not _text_contains_evidence(anchor_text,
|
|
906
|
+
if not _text_contains_evidence(anchor_text, anchor_code):
|
|
912
907
|
discarded_grounding.append(comment)
|
|
913
908
|
continue
|
|
914
909
|
|
|
915
|
-
if not _text_contains_evidence(anchor_text,
|
|
910
|
+
if not _text_contains_evidence(anchor_text, problematic_code):
|
|
916
911
|
discarded_grounding.append(comment)
|
|
917
912
|
continue
|
|
918
913
|
|
|
@@ -924,10 +919,6 @@ def _filter_comments_to_grounded_source_lines(
|
|
|
924
919
|
discarded_grounding.append(comment)
|
|
925
920
|
continue
|
|
926
921
|
|
|
927
|
-
if not _text_contains_evidence(source_text, evidence):
|
|
928
|
-
discarded_grounding.append(comment)
|
|
929
|
-
continue
|
|
930
|
-
|
|
931
922
|
if _comment_mentions_absent_source_terms(comment, source_text):
|
|
932
923
|
discarded_grounding.append(comment)
|
|
933
924
|
continue
|
|
@@ -1381,19 +1372,29 @@ def run_pr_review_workflow(args: argparse.Namespace, config: ReviewConfig,
|
|
|
1381
1372
|
# Show PR details
|
|
1382
1373
|
print(formatter.format_pr_details(pr_details))
|
|
1383
1374
|
|
|
1384
|
-
# --- Get PR diff ---
|
|
1375
|
+
# --- Get PR diff via git local ---
|
|
1385
1376
|
print(formatter.format_progress("Getting Pull Request diff"))
|
|
1386
1377
|
|
|
1378
|
+
_local_repo = (config.tfs_local_repo_path or "").strip() or os.getcwd()
|
|
1379
|
+
git_utils_pr = GitUtils(repo_path=_local_repo, pat=config.tfs_pat)
|
|
1380
|
+
|
|
1387
1381
|
try:
|
|
1388
|
-
|
|
1389
|
-
repo_name,
|
|
1390
|
-
pr_id,
|
|
1391
|
-
review_scope=config.review_scope,
|
|
1392
|
-
)
|
|
1382
|
+
target_ref, source_ref = tfs.obter_dados_pr(pr_id)
|
|
1393
1383
|
except TFSError as exc:
|
|
1394
1384
|
print(formatter.format_error(str(exc)))
|
|
1395
1385
|
return 1
|
|
1396
1386
|
|
|
1387
|
+
try:
|
|
1388
|
+
git_utils_pr.fetch_merge_commit(source_ref)
|
|
1389
|
+
except GitError as exc:
|
|
1390
|
+
print(formatter.format_warning(f"Could not fetch source branch: {exc}"))
|
|
1391
|
+
|
|
1392
|
+
try:
|
|
1393
|
+
diff = git_utils_pr.get_pr_diff(target_ref, source_ref)
|
|
1394
|
+
except GitError as exc:
|
|
1395
|
+
print(formatter.format_error(str(exc)))
|
|
1396
|
+
return 1
|
|
1397
|
+
|
|
1397
1398
|
if not diff.strip():
|
|
1398
1399
|
print(formatter.format_warning("PR contains no code changes."))
|
|
1399
1400
|
return 0
|
|
@@ -1411,8 +1412,13 @@ def run_pr_review_workflow(args: argparse.Namespace, config: ReviewConfig,
|
|
|
1411
1412
|
print(formatter.format_info("🔍 DRY-RUN mode: comments will NOT be posted"))
|
|
1412
1413
|
|
|
1413
1414
|
# Get diff files summary
|
|
1414
|
-
git_utils =
|
|
1415
|
-
|
|
1415
|
+
git_utils = git_utils_pr
|
|
1416
|
+
|
|
1417
|
+
# --- Noise filter (binary, lock files, oversized sections) ---
|
|
1418
|
+
diff = git_utils_pr.filter_diff_noise(diff, config.max_diff_lines)
|
|
1419
|
+
if not diff.strip():
|
|
1420
|
+
print(formatter.format_warning("After filtering noise (binary/lock files), the diff is empty."))
|
|
1421
|
+
return 0
|
|
1416
1422
|
|
|
1417
1423
|
# Filter extensions before limiting/truncating the diff sent to the LLM
|
|
1418
1424
|
if config.file_extensions_filter:
|
|
@@ -1460,7 +1466,41 @@ def run_pr_review_workflow(args: argparse.Namespace, config: ReviewConfig,
|
|
|
1460
1466
|
))
|
|
1461
1467
|
|
|
1462
1468
|
use_contextual_review = review_scope == "diff_with_context"
|
|
1463
|
-
load_changed_file_context = review_scope
|
|
1469
|
+
load_changed_file_context = review_scope == "diff_with_context"
|
|
1470
|
+
|
|
1471
|
+
# --- RAG context ---
|
|
1472
|
+
rag_context = ""
|
|
1473
|
+
if config.rag_enabled and diff_truncated.strip():
|
|
1474
|
+
# Verify local branch matches the PR target branch to avoid RAG context contamination.
|
|
1475
|
+
_target_branch = target_ref.removeprefix("origin/")
|
|
1476
|
+
try:
|
|
1477
|
+
_local_branch = git_utils_pr.get_current_branch()
|
|
1478
|
+
except GitError as exc:
|
|
1479
|
+
print(formatter.format_error(
|
|
1480
|
+
f"Cannot determine local branch: {exc}\n"
|
|
1481
|
+
"Ensure the local repository is accessible and try again."
|
|
1482
|
+
))
|
|
1483
|
+
return 1
|
|
1484
|
+
|
|
1485
|
+
if _local_branch != _target_branch:
|
|
1486
|
+
print(formatter.format_error(
|
|
1487
|
+
f"Local branch mismatch: you are on '{_local_branch}' "
|
|
1488
|
+
f"but this PR targets '{_target_branch}'.\n"
|
|
1489
|
+
f"RAG context would be built from the wrong branch, which may corrupt the review.\n"
|
|
1490
|
+
f"Please run: git checkout {_target_branch}"
|
|
1491
|
+
))
|
|
1492
|
+
return 1
|
|
1493
|
+
|
|
1494
|
+
print(formatter.format_progress("Loading RAG context from local repository"))
|
|
1495
|
+
rag_context = obter_contexto_rag(
|
|
1496
|
+
diff_truncated,
|
|
1497
|
+
repo_path=git_utils.repo_path,
|
|
1498
|
+
max_chars=config.rag_max_chars,
|
|
1499
|
+
)
|
|
1500
|
+
if rag_context:
|
|
1501
|
+
print(formatter.format_info(
|
|
1502
|
+
f"RAG context loaded ({len(rag_context):,} characters)."
|
|
1503
|
+
))
|
|
1464
1504
|
|
|
1465
1505
|
work_item_context = ""
|
|
1466
1506
|
linked_work_item_ids: list[int] | None = None
|
|
@@ -1604,7 +1644,7 @@ def run_pr_review_workflow(args: argparse.Namespace, config: ReviewConfig,
|
|
|
1604
1644
|
structured_comments = llm.review_pr_structured(
|
|
1605
1645
|
diff=diff_truncated,
|
|
1606
1646
|
files_summary=files_summary,
|
|
1607
|
-
context=getattr(args, "context", ""),
|
|
1647
|
+
context="\n\n".join(filter(None, [getattr(args, "context", ""), rag_context])),
|
|
1608
1648
|
review_scope=config.review_scope,
|
|
1609
1649
|
project_context=project_context,
|
|
1610
1650
|
work_item_context=work_item_context,
|