overkill 0.2.1__tar.gz → 0.3.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 (90) hide show
  1. {overkill-0.2.1 → overkill-0.3.0}/.gitignore +3 -1
  2. overkill-0.2.1/.reviewlooprc.example → overkill-0.3.0/.overkillrc.example +2 -2
  3. {overkill-0.2.1 → overkill-0.3.0}/PKG-INFO +15 -15
  4. {overkill-0.2.1 → overkill-0.3.0}/README.md +14 -14
  5. {overkill-0.2.1 → overkill-0.3.0}/bin/lib/common.sh +1 -1
  6. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/claude-review.prompt.md +20 -2
  7. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/codex-review.prompt.md +15 -6
  8. {overkill-0.2.1 → overkill-0.3.0}/pyproject.toml +2 -2
  9. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/__main__.py +2 -2
  10. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/cli.py +89 -13
  11. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/git_ops.py +5 -2
  12. overkill-0.3.0/src/mr_overkill/init.py +214 -0
  13. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/loop_engine.py +14 -1
  14. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/refactor_suggest.py +11 -1
  15. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/self_review.py +1 -1
  16. {overkill-0.2.1 → overkill-0.3.0}/tests/test_cli.py +4 -4
  17. overkill-0.3.0/tests/test_init.py +161 -0
  18. {overkill-0.2.1 → overkill-0.3.0}/uninstall.sh +32 -3
  19. {overkill-0.2.1 → overkill-0.3.0}/uv.lock +1 -1
  20. overkill-0.2.1/src/mr_overkill/init.py +0 -142
  21. overkill-0.2.1/tests/test_init.py +0 -110
  22. {overkill-0.2.1 → overkill-0.3.0}/.github/workflows/publish.yml +0 -0
  23. {overkill-0.2.1 → overkill-0.3.0}/.github/workflows/test.yml +0 -0
  24. {overkill-0.2.1 → overkill-0.3.0}/.python-version +0 -0
  25. {overkill-0.2.1 → overkill-0.3.0}/.refactorsuggestrc.example +0 -0
  26. {overkill-0.2.1 → overkill-0.3.0}/AGENTS.md +0 -0
  27. {overkill-0.2.1 → overkill-0.3.0}/CLAUDE.md +0 -0
  28. {overkill-0.2.1 → overkill-0.3.0}/GEMINI.md +0 -0
  29. {overkill-0.2.1 → overkill-0.3.0}/LICENSE +0 -0
  30. {overkill-0.2.1 → overkill-0.3.0}/bin/lib/check-claude-limit.sh +0 -0
  31. {overkill-0.2.1 → overkill-0.3.0}/bin/lib/check-codex-limit.sh +0 -0
  32. {overkill-0.2.1 → overkill-0.3.0}/bin/lib/retry.sh +0 -0
  33. {overkill-0.2.1 → overkill-0.3.0}/bin/lib/self-review.sh +0 -0
  34. {overkill-0.2.1 → overkill-0.3.0}/bin/refactor-suggest.sh +0 -0
  35. {overkill-0.2.1 → overkill-0.3.0}/bin/review-loop.sh +0 -0
  36. {overkill-0.2.1 → overkill-0.3.0}/install.sh +0 -0
  37. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/claude-fix-execute.prompt.md +0 -0
  38. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/claude-fix.prompt.md +0 -0
  39. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/claude-refactor-fix-execute.prompt.md +0 -0
  40. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/claude-refactor-fix.prompt.md +0 -0
  41. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/claude-refactor-full.prompt.md +0 -0
  42. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/claude-refactor-layer.prompt.md +0 -0
  43. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/claude-refactor-micro.prompt.md +0 -0
  44. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/claude-refactor-module.prompt.md +0 -0
  45. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/claude-self-review.prompt.md +0 -0
  46. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/codex-refactor-full.prompt.md +0 -0
  47. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/codex-refactor-layer.prompt.md +0 -0
  48. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/codex-refactor-micro.prompt.md +0 -0
  49. {overkill-0.2.1 → overkill-0.3.0}/prompts/active/codex-refactor-module.prompt.md +0 -0
  50. {overkill-0.2.1 → overkill-0.3.0}/prompts/reference/claude-code-review-plugin.md +0 -0
  51. {overkill-0.2.1 → overkill-0.3.0}/prompts/reference/claude-security-review.md +0 -0
  52. {overkill-0.2.1 → overkill-0.3.0}/prompts/reference/codex-review-original.md +0 -0
  53. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/__init__.py +0 -0
  54. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/agents.py +0 -0
  55. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/budget/__init__.py +0 -0
  56. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/budget/claude.py +0 -0
  57. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/budget/codex.py +0 -0
  58. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/budget_report.py +0 -0
  59. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/classify.py +0 -0
  60. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/data/__init__.py +0 -0
  61. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/json_extract.py +0 -0
  62. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/models.py +0 -0
  63. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/reporting.py +0 -0
  64. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/resume.py +0 -0
  65. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/retry.py +0 -0
  66. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/review_loop.py +0 -0
  67. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/time_utils.py +0 -0
  68. {overkill-0.2.1 → overkill-0.3.0}/src/mr_overkill/two_step_fix.py +0 -0
  69. {overkill-0.2.1 → overkill-0.3.0}/test/refactor-suggest.bats +0 -0
  70. {overkill-0.2.1 → overkill-0.3.0}/test/test_helper.bash +0 -0
  71. {overkill-0.2.1 → overkill-0.3.0}/tests/__init__.py +0 -0
  72. {overkill-0.2.1 → overkill-0.3.0}/tests/conftest.py +0 -0
  73. {overkill-0.2.1 → overkill-0.3.0}/tests/test_agents.py +0 -0
  74. {overkill-0.2.1 → overkill-0.3.0}/tests/test_budget_claude.py +0 -0
  75. {overkill-0.2.1 → overkill-0.3.0}/tests/test_budget_codex.py +0 -0
  76. {overkill-0.2.1 → overkill-0.3.0}/tests/test_budget_policy.py +0 -0
  77. {overkill-0.2.1 → overkill-0.3.0}/tests/test_budget_report.py +0 -0
  78. {overkill-0.2.1 → overkill-0.3.0}/tests/test_classify.py +0 -0
  79. {overkill-0.2.1 → overkill-0.3.0}/tests/test_git_ops.py +0 -0
  80. {overkill-0.2.1 → overkill-0.3.0}/tests/test_integration.py +0 -0
  81. {overkill-0.2.1 → overkill-0.3.0}/tests/test_json_extract.py +0 -0
  82. {overkill-0.2.1 → overkill-0.3.0}/tests/test_loop_engine.py +0 -0
  83. {overkill-0.2.1 → overkill-0.3.0}/tests/test_refactor_suggest.py +0 -0
  84. {overkill-0.2.1 → overkill-0.3.0}/tests/test_reporting.py +0 -0
  85. {overkill-0.2.1 → overkill-0.3.0}/tests/test_resume.py +0 -0
  86. {overkill-0.2.1 → overkill-0.3.0}/tests/test_retry.py +0 -0
  87. {overkill-0.2.1 → overkill-0.3.0}/tests/test_review_loop.py +0 -0
  88. {overkill-0.2.1 → overkill-0.3.0}/tests/test_self_review.py +0 -0
  89. {overkill-0.2.1 → overkill-0.3.0}/tests/test_time_utils.py +0 -0
  90. {overkill-0.2.1 → overkill-0.3.0}/tests/test_two_step_fix.py +0 -0
@@ -3,7 +3,9 @@
3
3
 
4
4
  # Legacy log directory from previous versions
5
5
  .ai-review-logs/
6
- # review-loop self-hosted install
6
+ # overkill self-hosted install
7
+ .overkill/
8
+ # Legacy directory (pre-migration)
7
9
  .review-loop/
8
10
 
9
11
  # Python
@@ -1,5 +1,5 @@
1
- # .reviewlooprc — project-level configuration for review-loop.sh
2
- # Copy this file to your project root as ".reviewlooprc" and customize.
1
+ # .overkillrc — project-level configuration for overkill review-loop
2
+ # Place this file in .overkill/.overkillrc and customize.
3
3
  # CLI arguments always take precedence over these values.
4
4
 
5
5
  # Target branch to diff against (default: develop)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: overkill
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: AI-powered code review loop — automates Codex review + Claude fix cycles
5
5
  Project-URL: Repository, https://github.com/modocai/mr-overkill
6
6
  Project-URL: Issues, https://github.com/modocai/mr-overkill/issues
@@ -161,7 +161,7 @@ Examples:
161
161
 
162
162
  ## Usage: overkill init
163
163
 
164
- Initialize `.review-loop/` in a project directory. Safe to re-run — prompts are refreshed, user-edited configs are preserved.
164
+ Initialize `.overkill/` in a project directory. Safe to re-run — prompts are refreshed, user-edited configs are preserved.
165
165
 
166
166
  ```
167
167
  overkill init [TARGET_DIR] # default: current directory
@@ -170,9 +170,9 @@ overkill init [TARGET_DIR] # default: current directory
170
170
  Creates:
171
171
 
172
172
  ```
173
- .review-loop/
173
+ .overkill/
174
174
  ├── prompts/active/ # 10 prompt templates
175
- ├── .reviewlooprc # review-loop config
175
+ ├── .overkillrc # review-loop config
176
176
  ├── .refactorsuggestrc # refactor-suggest config
177
177
  ├── logs/ # runtime logs
178
178
  │ └── refactor/ # refactor-suggest logs
@@ -207,9 +207,9 @@ Recommended workflow: start with `--dry-run` to review findings, then re-run wit
207
207
 
208
208
  ## Configuration
209
209
 
210
- After running `overkill init`, config files live in `.review-loop/`:
210
+ After running `overkill init`, config files live in `.overkill/`:
211
211
 
212
- ### .review-loop/.reviewlooprc
212
+ ### .overkill/.overkillrc
213
213
 
214
214
  ```bash
215
215
  TARGET_BRANCH="main"
@@ -220,9 +220,9 @@ REVIEWER_BACKEND="codex" # or "claude"
220
220
  PROMPTS_DIR="./custom-prompts"
221
221
  ```
222
222
 
223
- See `.review-loop/.reviewlooprc` for all available options.
223
+ See `.overkill/.overkillrc` for all available options.
224
224
 
225
- ### .review-loop/.refactorsuggestrc
225
+ ### .overkill/.refactorsuggestrc
226
226
 
227
227
  ```bash
228
228
  SCOPE="auto"
@@ -243,7 +243,7 @@ PROMPTS_DIR="./custom-prompts"
243
243
 
244
244
  ```
245
245
  1. Check prerequisites (git, codex, claude, jq, envsubst, target branch)
246
- 2. Create .review-loop/logs/ directory
246
+ 2. Create .overkill/logs/ directory
247
247
  3. Loop (iteration 1..N):
248
248
  a. Generate diff: git diff $TARGET...$CURRENT
249
249
  b. Empty diff → exit
@@ -258,14 +258,14 @@ PROMPTS_DIR="./custom-prompts"
258
258
  h. Push to remote (updates PR)
259
259
  i. Post review/fix/self-review summary as PR comment
260
260
  j. Next iteration reviews the updated committed state
261
- 4. Write summary to .review-loop/logs/summary.md
261
+ 4. Write summary to .overkill/logs/summary.md
262
262
  ```
263
263
 
264
264
  ## Output Files
265
265
 
266
- All logs are git-ignored by default (inside `.review-loop/`).
266
+ All logs are git-ignored by default (inside `.overkill/`).
267
267
 
268
- ### review-loop logs (`.review-loop/logs/`)
268
+ ### review-loop logs (`.overkill/logs/`)
269
269
 
270
270
  | File | Description |
271
271
  |------|-------------|
@@ -277,7 +277,7 @@ All logs are git-ignored by default (inside `.review-loop/`).
277
277
  | `refix-N-M.md` | Claude re-fix log (iteration N, sub-iteration M) |
278
278
  | `summary.md` | Final summary with status and per-iteration results |
279
279
 
280
- ### refactor-suggest logs (`.review-loop/logs/refactor/`)
280
+ ### refactor-suggest logs (`.overkill/logs/refactor/`)
281
281
 
282
282
  | File | Description |
283
283
  |------|-------------|
@@ -316,7 +316,7 @@ Go/no-go decision based on current usage percentage:
316
316
 
317
317
  ## Customizing Prompts
318
318
 
319
- Edit the templates in `.review-loop/prompts/active/`.
319
+ Edit the templates in `.overkill/prompts/active/`.
320
320
 
321
321
  ### review-loop prompts
322
322
 
@@ -364,7 +364,7 @@ The loop terminates when any of these occur:
364
364
 
365
365
  ```bash
366
366
  # Quick — just nuke the directory
367
- rm -rf .review-loop
367
+ rm -rf .overkill
368
368
 
369
369
  # Also remove the Python package
370
370
  pip uninstall overkill # or: uv tool uninstall overkill / pipx uninstall overkill
@@ -139,7 +139,7 @@ Examples:
139
139
 
140
140
  ## Usage: overkill init
141
141
 
142
- Initialize `.review-loop/` in a project directory. Safe to re-run — prompts are refreshed, user-edited configs are preserved.
142
+ Initialize `.overkill/` in a project directory. Safe to re-run — prompts are refreshed, user-edited configs are preserved.
143
143
 
144
144
  ```
145
145
  overkill init [TARGET_DIR] # default: current directory
@@ -148,9 +148,9 @@ overkill init [TARGET_DIR] # default: current directory
148
148
  Creates:
149
149
 
150
150
  ```
151
- .review-loop/
151
+ .overkill/
152
152
  ├── prompts/active/ # 10 prompt templates
153
- ├── .reviewlooprc # review-loop config
153
+ ├── .overkillrc # review-loop config
154
154
  ├── .refactorsuggestrc # refactor-suggest config
155
155
  ├── logs/ # runtime logs
156
156
  │ └── refactor/ # refactor-suggest logs
@@ -185,9 +185,9 @@ Recommended workflow: start with `--dry-run` to review findings, then re-run wit
185
185
 
186
186
  ## Configuration
187
187
 
188
- After running `overkill init`, config files live in `.review-loop/`:
188
+ After running `overkill init`, config files live in `.overkill/`:
189
189
 
190
- ### .review-loop/.reviewlooprc
190
+ ### .overkill/.overkillrc
191
191
 
192
192
  ```bash
193
193
  TARGET_BRANCH="main"
@@ -198,9 +198,9 @@ REVIEWER_BACKEND="codex" # or "claude"
198
198
  PROMPTS_DIR="./custom-prompts"
199
199
  ```
200
200
 
201
- See `.review-loop/.reviewlooprc` for all available options.
201
+ See `.overkill/.overkillrc` for all available options.
202
202
 
203
- ### .review-loop/.refactorsuggestrc
203
+ ### .overkill/.refactorsuggestrc
204
204
 
205
205
  ```bash
206
206
  SCOPE="auto"
@@ -221,7 +221,7 @@ PROMPTS_DIR="./custom-prompts"
221
221
 
222
222
  ```
223
223
  1. Check prerequisites (git, codex, claude, jq, envsubst, target branch)
224
- 2. Create .review-loop/logs/ directory
224
+ 2. Create .overkill/logs/ directory
225
225
  3. Loop (iteration 1..N):
226
226
  a. Generate diff: git diff $TARGET...$CURRENT
227
227
  b. Empty diff → exit
@@ -236,14 +236,14 @@ PROMPTS_DIR="./custom-prompts"
236
236
  h. Push to remote (updates PR)
237
237
  i. Post review/fix/self-review summary as PR comment
238
238
  j. Next iteration reviews the updated committed state
239
- 4. Write summary to .review-loop/logs/summary.md
239
+ 4. Write summary to .overkill/logs/summary.md
240
240
  ```
241
241
 
242
242
  ## Output Files
243
243
 
244
- All logs are git-ignored by default (inside `.review-loop/`).
244
+ All logs are git-ignored by default (inside `.overkill/`).
245
245
 
246
- ### review-loop logs (`.review-loop/logs/`)
246
+ ### review-loop logs (`.overkill/logs/`)
247
247
 
248
248
  | File | Description |
249
249
  |------|-------------|
@@ -255,7 +255,7 @@ All logs are git-ignored by default (inside `.review-loop/`).
255
255
  | `refix-N-M.md` | Claude re-fix log (iteration N, sub-iteration M) |
256
256
  | `summary.md` | Final summary with status and per-iteration results |
257
257
 
258
- ### refactor-suggest logs (`.review-loop/logs/refactor/`)
258
+ ### refactor-suggest logs (`.overkill/logs/refactor/`)
259
259
 
260
260
  | File | Description |
261
261
  |------|-------------|
@@ -294,7 +294,7 @@ Go/no-go decision based on current usage percentage:
294
294
 
295
295
  ## Customizing Prompts
296
296
 
297
- Edit the templates in `.review-loop/prompts/active/`.
297
+ Edit the templates in `.overkill/prompts/active/`.
298
298
 
299
299
  ### review-loop prompts
300
300
 
@@ -342,7 +342,7 @@ The loop terminates when any of these occur:
342
342
 
343
343
  ```bash
344
344
  # Quick — just nuke the directory
345
- rm -rf .review-loop
345
+ rm -rf .overkill
346
346
 
347
347
  # Also remove the Python package
348
348
  pip uninstall overkill # or: uv tool uninstall overkill / pipx uninstall overkill
@@ -277,7 +277,7 @@ _changed_files_since_snapshot() {
277
277
  _out=$(mktemp)
278
278
  _git_all_dirty_nul | while IFS= read -r -d '' _f; do
279
279
  [[ -n "$_f" ]] || continue
280
- [[ "$_f" == .review-loop/logs/* ]] && continue
280
+ [[ "$_f" == .overkill/logs/* || "$_f" == .review-loop/logs/* ]] && continue
281
281
  if [[ -f "$_f" ]]; then
282
282
  _cur_hash=$(git hash-object "$_f" 2>/dev/null || echo UNHASHABLE)
283
283
  if [[ -x "$_f" ]]; then _cur_mode="100755"; else _cur_mode="100644"; fi
@@ -8,15 +8,23 @@ You are a code reviewer analyzing a proposed change.
8
8
 
9
9
  ## Instructions
10
10
 
11
- Run the following command to get the diff:
11
+ Start by running the following command to get the diff:
12
12
 
13
13
  ```
14
14
  git diff ${TARGET_BRANCH}...${CURRENT_BRANCH}
15
15
  ```
16
16
 
17
+ Then **actively explore the codebase** to understand context before flagging issues:
18
+
19
+ - Use `Read` to examine surrounding code when a change touches a function or module.
20
+ - Use `Grep` to check if a pattern, variable, or function is used elsewhere before calling it dead code or flagging a naming issue.
21
+ - Use `Glob` to find related files (e.g. tests, configs) that may clarify intent.
22
+
17
23
  Review the diff according to the guidelines below.
18
24
 
19
- ## Review Guidelines
25
+ ## Review Guidelines — HIGH SIGNAL ONLY
26
+
27
+ We only want findings where you are confident the issue is real. **If you are not certain an issue is real, do not flag it.** False positives erode trust and waste reviewer time.
20
28
 
21
29
  1. Only flag issues the original author would fix if they knew about them.
22
30
  2. The issue must be **introduced by this diff** — do not flag pre-existing problems.
@@ -24,6 +32,16 @@ Review the diff according to the guidelines below.
24
32
  4. Do not flag trivial style issues unless they obscure meaning or violate documented standards.
25
33
  5. Do not speculate — you must identify the exact code location and explain why it is a problem.
26
34
  6. If this is iteration > 1, focus on whether issues from prior reviews have been properly fixed, and identify any new issues introduced by the fixes.
35
+ 7. **Only flag issues where your confidence is >= 0.85.** If you cannot reach that threshold after investigating, do not include the finding.
36
+
37
+ ### Do NOT flag (false positive filter)
38
+
39
+ - Pre-existing issues not introduced by this diff.
40
+ - Something that appears to be a bug but is actually correct when you read the surrounding code.
41
+ - Pedantic nitpicks that a senior engineer would not flag in a real review.
42
+ - Issues that a linter or formatter will catch — do not run the linter to verify.
43
+ - Potential issues that depend on specific inputs or state that are not demonstrated in the diff.
44
+ - General code quality concerns (e.g. lack of test coverage, general security hygiene) unless they are concretely exploitable.
27
45
 
28
46
  ## Priority Levels
29
47
 
@@ -20,10 +20,16 @@ Review the diff according to the guidelines below.
20
20
 
21
21
  1. Only flag issues the original author would fix if they knew about them.
22
22
  2. The issue must be **introduced by this diff** — do not flag pre-existing problems.
23
- 3. The issue must be discrete, actionable, and concretely provable.
24
- 4. Do not flag trivial style issues unless they obscure meaning or violate documented standards.
25
- 5. Do not speculate you must identify the exact code location and explain why it is a problem.
26
- 6. If this is iteration > 1, focus on whether issues from prior reviews have been properly fixed, and identify any new issues introduced by the fixes.
23
+ 3. The issue must meaningfully impact the accuracy, performance, security, or maintainability of the code.
24
+ 4. The issue must be discrete, actionable, and concretely provable.
25
+ 5. Fixing the bug does not demand a level of rigor not present in the rest of the codebase (e.g. one doesn't need detailed comments and input validation in a repository of one-off scripts).
26
+ 6. The bug does not rely on unstated assumptions about the codebase or author's intent.
27
+ 7. It is not enough to speculate that a change may disrupt another part of the codebase — you must identify the other parts of the code that are provably affected.
28
+ 8. The bug is clearly not just an intentional change by the original author.
29
+ 9. Do not flag trivial style issues unless they obscure meaning or violate documented standards.
30
+ 10. If this is iteration > 1, focus on whether issues from prior reviews have been properly fixed, and identify any new issues introduced by the fixes.
31
+
32
+ Output all findings that the original author would fix if they knew about them. If there is no finding that a person would definitely want to fix, prefer outputting no findings. Do not stop at the first qualifying finding — continue until you've listed every qualifying finding.
27
33
 
28
34
  ## Priority Levels
29
35
 
@@ -36,9 +42,12 @@ Review the diff according to the guidelines below.
36
42
 
37
43
  - One comment per distinct issue.
38
44
  - Brief (at most 1 paragraph body).
39
- - Clearly state the scenarios/inputs required for the bug to manifest.
40
- - Matter-of-fact tone, no flattery.
45
+ - Clearly state the scenarios, environments, or inputs required for the bug to manifest.
46
+ - Appropriately communicate severity — do not overclaim. Immediately indicate if the issue's severity depends on specific conditions.
47
+ - The comment should be written such that the original author can immediately grasp the idea without close reading.
48
+ - Matter-of-fact tone, no flattery. Avoid "Great job …", "Thanks for …".
41
49
  - Code snippets max 3 lines, wrapped in markdown code tags.
50
+ - Use ```suggestion blocks only for concrete replacement code (minimal lines; no commentary inside the block). Preserve exact leading whitespace.
42
51
 
43
52
  ## Output Format
44
53
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "overkill"
3
- version = "0.2.1"
3
+ version = "0.3.0"
4
4
  description = "AI-powered code review loop — automates Codex review + Claude fix cycles"
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
@@ -36,7 +36,7 @@ packages = ["src/mr_overkill"]
36
36
 
37
37
  [tool.hatch.build.targets.wheel.force-include]
38
38
  "prompts/active" = "mr_overkill/data/prompts/active"
39
- ".reviewlooprc.example" = "mr_overkill/data/.reviewlooprc.example"
39
+ ".overkillrc.example" = "mr_overkill/data/.overkillrc.example"
40
40
  ".refactorsuggestrc.example" = "mr_overkill/data/.refactorsuggestrc.example"
41
41
 
42
42
  [tool.pytest.ini_options]
@@ -24,7 +24,7 @@ def main() -> None:
24
24
  print(
25
25
  "Usage: overkill <command>\n\n"
26
26
  "Commands:\n"
27
- " init Initialize .review-loop/ in a project\n"
27
+ " init Initialize .overkill/ in a project\n"
28
28
  " review-loop Run AI review-fix loop\n"
29
29
  " refactor-suggest Run AI refactoring suggestions\n"
30
30
  " check-budget Show token budget usage summary",
@@ -43,7 +43,7 @@ def main() -> None:
43
43
 
44
44
  p = argparse.ArgumentParser(
45
45
  prog="overkill init",
46
- description="Initialize .review-loop/ in a project",
46
+ description="Initialize .overkill/ in a project",
47
47
  )
48
48
  p.add_argument("target", nargs="?", default=".", help="Target directory")
49
49
  init_args = p.parse_args()
@@ -7,6 +7,7 @@ mirroring the CLI interface of the bash scripts.
7
7
  from __future__ import annotations
8
8
 
9
9
  import argparse
10
+ import logging
10
11
  import re
11
12
  import subprocess
12
13
  from dataclasses import dataclass
@@ -59,18 +60,45 @@ def _load_rc_file(rc_name: str) -> dict[str, str]:
59
60
  return {}
60
61
 
61
62
  git_root = Path(result.stdout.strip())
62
- rc_path = git_root / ".review-loop" / rc_name
63
+ rc_path = git_root / ".overkill" / rc_name
63
64
  if not rc_path.is_file():
64
- # Fall back to the legacy repo-root location
65
- legacy = git_root / rc_name
66
- if legacy.is_file():
67
- import logging
65
+ # Fall back to the legacy .review-loop/ location
66
+ legacy_dir = git_root / ".review-loop" / rc_name
67
+ # Also check for legacy .reviewlooprc name in .review-loop/
68
+ legacy_old_name = (
69
+ git_root / ".review-loop" / ".reviewlooprc"
70
+ if rc_name == ".overkillrc" else None
71
+ )
72
+ # Legacy repo-root name: .overkillrc was .reviewlooprc
73
+ legacy_root_name = ".reviewlooprc" if rc_name == ".overkillrc" else rc_name
74
+ legacy_root = git_root / legacy_root_name
75
+ if legacy_dir.is_file():
76
+ logging.getLogger(__name__).warning(
77
+ "%s found at .review-loop/ (legacy location). "
78
+ "Please run 'overkill init' to migrate to .overkill/",
79
+ rc_name,
80
+ )
81
+ rc_path = legacy_dir
82
+ elif legacy_old_name and legacy_old_name.is_file():
83
+ logging.getLogger(__name__).warning(
84
+ ".reviewlooprc found at .review-loop/ (legacy location). "
85
+ "Please run 'overkill init' to migrate to .overkill/.overkillrc",
86
+ )
87
+ rc_path = legacy_old_name
88
+ elif (git_root / rc_name).is_file():
68
89
  logging.getLogger(__name__).warning(
69
90
  "%s found at repo root (legacy location). "
70
- "Please move it to .review-loop/%s",
91
+ "Please move it to .overkill/%s",
71
92
  rc_name, rc_name,
72
93
  )
73
- rc_path = legacy
94
+ rc_path = git_root / rc_name
95
+ elif legacy_root.is_file():
96
+ logging.getLogger(__name__).warning(
97
+ "%s found at repo root (legacy location). "
98
+ "Please move it to .overkill/%s",
99
+ legacy_root_name, rc_name,
100
+ )
101
+ rc_path = legacy_root
74
102
  else:
75
103
  return {}
76
104
 
@@ -118,7 +146,33 @@ def _resolve_prompts_dir(prompts_dir: str) -> Path:
118
146
  check=False,
119
147
  )
120
148
  if result.returncode == 0:
121
- return Path(result.stdout.strip()) / prompts_dir
149
+ git_root = Path(result.stdout.strip())
150
+ resolved = git_root / prompts_dir
151
+ # Legacy fallback: .overkill/... → .review-loop/...
152
+ if not resolved.is_dir() and ".overkill/" in prompts_dir:
153
+ legacy = git_root / prompts_dir.replace(
154
+ ".overkill/", ".review-loop/", 1
155
+ )
156
+ if legacy.is_dir():
157
+ logging.getLogger(__name__).warning(
158
+ "Prompts dir found at %s (legacy location). "
159
+ "Please run 'overkill init' to migrate to .overkill/",
160
+ legacy,
161
+ )
162
+ return legacy
163
+ # Inverse fallback: .review-loop/... → .overkill/...
164
+ if not resolved.is_dir() and ".review-loop/" in prompts_dir:
165
+ migrated = git_root / prompts_dir.replace(
166
+ ".review-loop/", ".overkill/", 1
167
+ )
168
+ if migrated.is_dir():
169
+ logging.getLogger(__name__).warning(
170
+ "Prompts dir migrated to %s. "
171
+ "Please update PROMPTS_DIR in your rc file.",
172
+ migrated,
173
+ )
174
+ return migrated
175
+ return resolved
122
176
  return p
123
177
 
124
178
 
@@ -249,7 +303,7 @@ def parse_review_loop_args(
249
303
  args = parser.parse_args(argv)
250
304
 
251
305
  # Load rc file defaults
252
- rc = _load_rc_file(".reviewlooprc")
306
+ rc = _load_rc_file(".overkillrc")
253
307
 
254
308
  # Resolve values with precedence: CLI > rc file > defaults
255
309
  target = args.target or rc.get("TARGET_BRANCH", "develop")
@@ -292,7 +346,7 @@ def parse_review_loop_args(
292
346
  budget_scope_str = rc.get("BUDGET_SCOPE", "module")
293
347
 
294
348
  prompts_dir = _resolve_prompts_dir(
295
- rc.get("PROMPTS_DIR", ".review-loop/prompts/active")
349
+ rc.get("PROMPTS_DIR", ".overkill/prompts/active")
296
350
  )
297
351
 
298
352
  current_branch = _detect_current_branch()
@@ -306,7 +360,18 @@ def parse_review_loop_args(
306
360
  check=False,
307
361
  )
308
362
  git_root = Path(result.stdout.strip()) if result.returncode == 0 else Path(".")
309
- log_dir = git_root / ".review-loop" / "logs"
363
+ log_dir = git_root / ".overkill" / "logs"
364
+ if not log_dir.is_dir():
365
+ legacy_log = git_root / ".review-loop" / "logs"
366
+ if legacy_log.is_dir():
367
+ log_dir = legacy_log
368
+
369
+ # In mixed-state repos, fall back to legacy logs when resume metadata
370
+ # is missing from the preferred directory.
371
+ if args.resume and not (log_dir / "max-loop.txt").is_file():
372
+ legacy_log = git_root / ".review-loop" / "logs"
373
+ if (legacy_log / "max-loop.txt").is_file():
374
+ log_dir = legacy_log
310
375
 
311
376
  # Restore saved values on resume when not explicitly given
312
377
  if args.resume:
@@ -539,7 +604,7 @@ def parse_refactor_suggest_args(
539
604
  budget_scope_str = rc.get("BUDGET_SCOPE", "module")
540
605
 
541
606
  prompts_dir = _resolve_prompts_dir(
542
- rc.get("PROMPTS_DIR", ".review-loop/prompts/active")
607
+ rc.get("PROMPTS_DIR", ".overkill/prompts/active")
543
608
  )
544
609
 
545
610
  current_branch = _detect_current_branch()
@@ -555,7 +620,18 @@ def parse_refactor_suggest_args(
555
620
  Path(result.stdout.strip()) if result.returncode == 0
556
621
  else Path(".")
557
622
  )
558
- log_dir = git_root / ".review-loop" / "logs" / "refactor"
623
+ log_dir = git_root / ".overkill" / "logs" / "refactor"
624
+ if not log_dir.is_dir():
625
+ legacy_log = git_root / ".review-loop" / "logs" / "refactor"
626
+ if legacy_log.is_dir():
627
+ log_dir = legacy_log
628
+
629
+ # In mixed-state repos, fall back to legacy logs when resume metadata
630
+ # is missing from the preferred directory.
631
+ if args.resume and not (log_dir / "max-loop.txt").is_file():
632
+ legacy_log = git_root / ".review-loop" / "logs" / "refactor"
633
+ if (legacy_log / "max-loop.txt").is_file():
634
+ log_dir = legacy_log
559
635
 
560
636
  # Restore saved values on resume when not explicitly given
561
637
  if args.resume:
@@ -100,12 +100,14 @@ def changed_files_since_snapshot(
100
100
  snapshot: list[WorktreeSnapshot],
101
101
  cwd: Path | None = None,
102
102
  exclude_prefix: str | None = None,
103
+ exclude_prefixes: tuple[str, ...] | None = None,
103
104
  ) -> list[str]:
104
105
  """Compare current dirty files against a snapshot.
105
106
 
106
107
  Returns list of file paths that changed (new, modified, or deleted).
107
108
  Uses a dict for O(1) lookups (vs O(n²) awk in bash).
108
109
  """
110
+ _prefixes = exclude_prefixes or ((exclude_prefix,) if exclude_prefix else ())
109
111
  snap_map: dict[str, tuple[str, str]] = {
110
112
  s.path: (s.file_hash, s.mode) for s in snapshot
111
113
  }
@@ -113,7 +115,7 @@ def changed_files_since_snapshot(
113
115
  changed: list[str] = []
114
116
 
115
117
  for f in git_all_dirty(cwd):
116
- if exclude_prefix and f.startswith(exclude_prefix):
118
+ if _prefixes and any(f.startswith(p) for p in _prefixes):
117
119
  continue
118
120
 
119
121
  fpath = base / f
@@ -210,7 +212,8 @@ def commit_and_push(
210
212
  Raises ``RuntimeError`` if ``git commit`` or ``git push`` fails.
211
213
  """
212
214
  changed = changed_files_since_snapshot(
213
- snapshot, cwd=cwd, exclude_prefix=".review-loop/logs/",
215
+ snapshot, cwd=cwd,
216
+ exclude_prefixes=(".overkill/logs/", ".review-loop/logs/"),
214
217
  )
215
218
  if not changed:
216
219
  logger.info("No file changes after fix — nothing to commit.")