overkill 0.8.2__tar.gz → 0.8.3__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.
- {overkill-0.8.2 → overkill-0.8.3}/PKG-INFO +2 -2
- {overkill-0.8.2 → overkill-0.8.3}/pyproject.toml +1 -1
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/self_review.py +10 -2
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_self_review.py +60 -0
- {overkill-0.8.2 → overkill-0.8.3}/uv.lock +1 -1
- {overkill-0.8.2 → overkill-0.8.3}/.github/workflows/publish.yml +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/.github/workflows/test.yml +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/.gitignore +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/.overkillrc.example +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/.python-version +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/.refactorsuggestrc.example +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/AGENTS.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/CLAUDE.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/GEMINI.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/LICENSE +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/README.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/install.sh +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/claude-fix-execute.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/claude-fix.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/claude-refactor-fix-execute.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/claude-refactor-fix.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/claude-refactor-full.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/claude-refactor-layer.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/claude-refactor-micro.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/claude-refactor-module.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/claude-review.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/claude-self-review.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/codex-refactor-full.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/codex-refactor-layer.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/codex-refactor-micro.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/codex-refactor-module.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/codex-review.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/gemini-refactor-full.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/gemini-refactor-layer.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/gemini-refactor-micro.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/gemini-refactor-module.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/active/gemini-review.prompt.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/reference/claude-code-review-plugin.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/reference/claude-security-review.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/prompts/reference/codex-review-original.md +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/__init__.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/__main__.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/agents.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/budget/__init__.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/budget/claude.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/budget/codex.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/budget/gemini.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/budget_report.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/classify.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/cli.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/data/__init__.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/data/review.schema.json +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/git_ops.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/init.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/json_extract.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/loop_engine.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/models.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/refactor_suggest.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/reporting.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/resume.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/retry.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/review_loop.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/time_utils.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/src/mr_overkill/two_step_fix.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/__init__.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/conftest.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_agents.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_budget_claude.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_budget_codex.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_budget_gemini.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_budget_policy.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_budget_report.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_classify.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_cli.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_git_ops.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_init.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_integration.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_json_extract.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_loop_engine.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_refactor_suggest.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_reporting.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_resume.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_retry.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_review_loop.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_time_utils.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/tests/test_two_step_fix.py +0 -0
- {overkill-0.8.2 → overkill-0.8.3}/uninstall.sh +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: overkill
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.3
|
|
4
4
|
Summary: AI-powered code review loop — automates Codex/Gemini 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
|
|
@@ -278,14 +278,22 @@ def _generate_diff(
|
|
|
278
278
|
check=False,
|
|
279
279
|
)
|
|
280
280
|
|
|
281
|
+
# Paths go in argv after ``--``: unlike add/reset, ``git diff`` has no
|
|
282
|
+
# --pathspec-from-file option and exits 129 on it, which would silently
|
|
283
|
+
# write an empty diff and skip the self-review for every iteration.
|
|
281
284
|
result = subprocess.run(
|
|
282
|
-
["git", "diff", "HEAD", "--
|
|
283
|
-
input=pathspec,
|
|
285
|
+
["git", "diff", "HEAD", "--", *changed_files],
|
|
284
286
|
cwd=cwd,
|
|
285
287
|
capture_output=True,
|
|
286
288
|
text=True,
|
|
287
289
|
check=False,
|
|
288
290
|
)
|
|
291
|
+
if result.returncode != 0:
|
|
292
|
+
logger.warning(
|
|
293
|
+
"git diff failed (exit %d): %s",
|
|
294
|
+
result.returncode,
|
|
295
|
+
result.stderr.strip(),
|
|
296
|
+
)
|
|
289
297
|
output.write_text(result.stdout, encoding="utf-8")
|
|
290
298
|
|
|
291
299
|
# Undo intent-to-add
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import json
|
|
6
|
+
import subprocess
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
from unittest.mock import MagicMock, patch
|
|
8
9
|
|
|
@@ -10,6 +11,7 @@ from mr_overkill.models import WorktreeSnapshot
|
|
|
10
11
|
from mr_overkill.self_review import (
|
|
11
12
|
_FIX_NITS_GUIDELINES,
|
|
12
13
|
_compute_fingerprint,
|
|
14
|
+
_generate_diff,
|
|
13
15
|
self_review_subloop,
|
|
14
16
|
)
|
|
15
17
|
|
|
@@ -449,3 +451,61 @@ class TestFixNitsGuidelines:
|
|
|
449
451
|
|
|
450
452
|
assert len(captured_prompt) == 1
|
|
451
453
|
assert "Fix nits" not in captured_prompt[0]
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
class TestGenerateDiff:
|
|
457
|
+
"""Exercise _generate_diff against a real git repo.
|
|
458
|
+
|
|
459
|
+
Every other test in this module patches _generate_diff out, so the real
|
|
460
|
+
command line was never run: it passed --pathspec-from-file to ``git diff``,
|
|
461
|
+
which rejects the option, and the discarded stderr turned that into an
|
|
462
|
+
empty diff that skipped the self-review on every iteration.
|
|
463
|
+
"""
|
|
464
|
+
|
|
465
|
+
def test_modified_tracked_file(self, tmp_git_repo: Path) -> None:
|
|
466
|
+
(tmp_git_repo / "README.md").write_text("# test\nsecond line\n")
|
|
467
|
+
output = tmp_git_repo / "out.diff"
|
|
468
|
+
|
|
469
|
+
_generate_diff(["README.md"], output, tmp_git_repo)
|
|
470
|
+
|
|
471
|
+
diff = output.read_text()
|
|
472
|
+
assert "+second line" in diff
|
|
473
|
+
assert "a/README.md" in diff
|
|
474
|
+
|
|
475
|
+
def test_untracked_file_included(self, tmp_git_repo: Path) -> None:
|
|
476
|
+
(tmp_git_repo / "new.py").write_text("print('hi')\n")
|
|
477
|
+
output = tmp_git_repo / "out.diff"
|
|
478
|
+
|
|
479
|
+
_generate_diff(["new.py"], output, tmp_git_repo)
|
|
480
|
+
|
|
481
|
+
assert "+print('hi')" in output.read_text()
|
|
482
|
+
|
|
483
|
+
def test_intent_to_add_is_undone(self, tmp_git_repo: Path) -> None:
|
|
484
|
+
"""The untracked file must be left unstaged for the later commit step."""
|
|
485
|
+
(tmp_git_repo / "new.py").write_text("print('hi')\n")
|
|
486
|
+
|
|
487
|
+
_generate_diff(["new.py"], tmp_git_repo / "out.diff", tmp_git_repo)
|
|
488
|
+
|
|
489
|
+
staged = subprocess.run(
|
|
490
|
+
["git", "diff", "--cached", "--name-only"],
|
|
491
|
+
cwd=tmp_git_repo,
|
|
492
|
+
capture_output=True,
|
|
493
|
+
text=True,
|
|
494
|
+
check=True,
|
|
495
|
+
)
|
|
496
|
+
assert staged.stdout.strip() == ""
|
|
497
|
+
|
|
498
|
+
def test_path_with_spaces(self, tmp_git_repo: Path) -> None:
|
|
499
|
+
(tmp_git_repo / "my file.txt").write_text("content\n")
|
|
500
|
+
output = tmp_git_repo / "out.diff"
|
|
501
|
+
|
|
502
|
+
_generate_diff(["my file.txt"], output, tmp_git_repo)
|
|
503
|
+
|
|
504
|
+
assert "+content" in output.read_text()
|
|
505
|
+
|
|
506
|
+
def test_no_changed_files_writes_empty(self, tmp_git_repo: Path) -> None:
|
|
507
|
+
output = tmp_git_repo / "out.diff"
|
|
508
|
+
|
|
509
|
+
_generate_diff([], output, tmp_git_repo)
|
|
510
|
+
|
|
511
|
+
assert output.read_text() == ""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|