overkill 0.4.1__tar.gz → 0.5.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.
Files changed (86) hide show
  1. {overkill-0.4.1 → overkill-0.5.1}/.github/workflows/test.yml +1 -1
  2. {overkill-0.4.1 → overkill-0.5.1}/PKG-INFO +11 -3
  3. {overkill-0.4.1 → overkill-0.5.1}/README.md +8 -1
  4. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/claude-review.prompt.md +2 -0
  5. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/codex-review.prompt.md +2 -0
  6. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/gemini-review.prompt.md +2 -0
  7. {overkill-0.4.1 → overkill-0.5.1}/pyproject.toml +5 -4
  8. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/agents.py +10 -0
  9. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/cli.py +18 -2
  10. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/loop_engine.py +1 -0
  11. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/models.py +10 -3
  12. {overkill-0.4.1 → overkill-0.5.1}/uv.lock +96 -3
  13. {overkill-0.4.1 → overkill-0.5.1}/.github/workflows/publish.yml +0 -0
  14. {overkill-0.4.1 → overkill-0.5.1}/.gitignore +0 -0
  15. {overkill-0.4.1 → overkill-0.5.1}/.overkillrc.example +0 -0
  16. {overkill-0.4.1 → overkill-0.5.1}/.python-version +0 -0
  17. {overkill-0.4.1 → overkill-0.5.1}/.refactorsuggestrc.example +0 -0
  18. {overkill-0.4.1 → overkill-0.5.1}/AGENTS.md +0 -0
  19. {overkill-0.4.1 → overkill-0.5.1}/CLAUDE.md +0 -0
  20. {overkill-0.4.1 → overkill-0.5.1}/GEMINI.md +0 -0
  21. {overkill-0.4.1 → overkill-0.5.1}/LICENSE +0 -0
  22. {overkill-0.4.1 → overkill-0.5.1}/install.sh +0 -0
  23. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/claude-fix-execute.prompt.md +0 -0
  24. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/claude-fix.prompt.md +0 -0
  25. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/claude-refactor-fix-execute.prompt.md +0 -0
  26. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/claude-refactor-fix.prompt.md +0 -0
  27. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/claude-refactor-full.prompt.md +0 -0
  28. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/claude-refactor-layer.prompt.md +0 -0
  29. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/claude-refactor-micro.prompt.md +0 -0
  30. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/claude-refactor-module.prompt.md +0 -0
  31. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/claude-self-review.prompt.md +0 -0
  32. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/codex-refactor-full.prompt.md +0 -0
  33. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/codex-refactor-layer.prompt.md +0 -0
  34. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/codex-refactor-micro.prompt.md +0 -0
  35. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/codex-refactor-module.prompt.md +0 -0
  36. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/gemini-refactor-full.prompt.md +0 -0
  37. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/gemini-refactor-layer.prompt.md +0 -0
  38. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/gemini-refactor-micro.prompt.md +0 -0
  39. {overkill-0.4.1 → overkill-0.5.1}/prompts/active/gemini-refactor-module.prompt.md +0 -0
  40. {overkill-0.4.1 → overkill-0.5.1}/prompts/reference/claude-code-review-plugin.md +0 -0
  41. {overkill-0.4.1 → overkill-0.5.1}/prompts/reference/claude-security-review.md +0 -0
  42. {overkill-0.4.1 → overkill-0.5.1}/prompts/reference/codex-review-original.md +0 -0
  43. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/__init__.py +0 -0
  44. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/__main__.py +0 -0
  45. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/budget/__init__.py +0 -0
  46. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/budget/claude.py +0 -0
  47. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/budget/codex.py +0 -0
  48. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/budget/gemini.py +0 -0
  49. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/budget_report.py +0 -0
  50. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/classify.py +0 -0
  51. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/data/__init__.py +0 -0
  52. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/git_ops.py +0 -0
  53. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/init.py +0 -0
  54. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/json_extract.py +0 -0
  55. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/refactor_suggest.py +0 -0
  56. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/reporting.py +0 -0
  57. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/resume.py +0 -0
  58. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/retry.py +0 -0
  59. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/review_loop.py +0 -0
  60. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/self_review.py +0 -0
  61. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/time_utils.py +0 -0
  62. {overkill-0.4.1 → overkill-0.5.1}/src/mr_overkill/two_step_fix.py +0 -0
  63. {overkill-0.4.1 → overkill-0.5.1}/tests/__init__.py +0 -0
  64. {overkill-0.4.1 → overkill-0.5.1}/tests/conftest.py +0 -0
  65. {overkill-0.4.1 → overkill-0.5.1}/tests/test_agents.py +0 -0
  66. {overkill-0.4.1 → overkill-0.5.1}/tests/test_budget_claude.py +0 -0
  67. {overkill-0.4.1 → overkill-0.5.1}/tests/test_budget_codex.py +0 -0
  68. {overkill-0.4.1 → overkill-0.5.1}/tests/test_budget_gemini.py +0 -0
  69. {overkill-0.4.1 → overkill-0.5.1}/tests/test_budget_policy.py +0 -0
  70. {overkill-0.4.1 → overkill-0.5.1}/tests/test_budget_report.py +0 -0
  71. {overkill-0.4.1 → overkill-0.5.1}/tests/test_classify.py +0 -0
  72. {overkill-0.4.1 → overkill-0.5.1}/tests/test_cli.py +0 -0
  73. {overkill-0.4.1 → overkill-0.5.1}/tests/test_git_ops.py +0 -0
  74. {overkill-0.4.1 → overkill-0.5.1}/tests/test_init.py +0 -0
  75. {overkill-0.4.1 → overkill-0.5.1}/tests/test_integration.py +0 -0
  76. {overkill-0.4.1 → overkill-0.5.1}/tests/test_json_extract.py +0 -0
  77. {overkill-0.4.1 → overkill-0.5.1}/tests/test_loop_engine.py +0 -0
  78. {overkill-0.4.1 → overkill-0.5.1}/tests/test_refactor_suggest.py +0 -0
  79. {overkill-0.4.1 → overkill-0.5.1}/tests/test_reporting.py +0 -0
  80. {overkill-0.4.1 → overkill-0.5.1}/tests/test_resume.py +0 -0
  81. {overkill-0.4.1 → overkill-0.5.1}/tests/test_retry.py +0 -0
  82. {overkill-0.4.1 → overkill-0.5.1}/tests/test_review_loop.py +0 -0
  83. {overkill-0.4.1 → overkill-0.5.1}/tests/test_self_review.py +0 -0
  84. {overkill-0.4.1 → overkill-0.5.1}/tests/test_time_utils.py +0 -0
  85. {overkill-0.4.1 → overkill-0.5.1}/tests/test_two_step_fix.py +0 -0
  86. {overkill-0.4.1 → overkill-0.5.1}/uninstall.sh +0 -0
@@ -11,7 +11,7 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
  strategy:
13
13
  matrix:
14
- python-version: ["3.12", "3.13"]
14
+ python-version: ["3.11", "3.12", "3.13"]
15
15
 
16
16
  steps:
17
17
  - uses: actions/checkout@v6
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: overkill
3
- Version: 0.4.1
3
+ Version: 0.5.1
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
@@ -14,10 +14,11 @@ Classifier: Intended Audience :: Developers
14
14
  Classifier: License :: OSI Approved :: MIT License
15
15
  Classifier: Operating System :: OS Independent
16
16
  Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
17
18
  Classifier: Programming Language :: Python :: 3.12
18
19
  Classifier: Programming Language :: Python :: 3.13
19
20
  Classifier: Topic :: Software Development :: Quality Assurance
20
- Requires-Python: >=3.12
21
+ Requires-Python: >=3.11
21
22
  Description-Content-Type: text/markdown
22
23
 
23
24
  # :tophat: Mr. Overkill
@@ -49,6 +50,13 @@ This tool is designed to:
49
50
  # Install the package
50
51
  pip install overkill # or: uv tool install overkill / pipx install overkill
51
52
 
53
+ # As a project dependency (uv)
54
+ uv add overkill
55
+
56
+ # Upgrade
57
+ pip install --upgrade overkill
58
+ uv lock --upgrade-package overkill # uv projects
59
+
52
60
  # Initialize your project
53
61
  overkill init /path/to/your-project
54
62
  ```
@@ -72,7 +80,7 @@ You need these to participate in the madness:
72
80
 
73
81
  **Runtime**:
74
82
 
75
- - [Python](https://www.python.org/) 3.12+ — for the `overkill` CLI
83
+ - [Python](https://www.python.org/) 3.11+ — for the `overkill` CLI
76
84
  - [Node.js](https://nodejs.org/) v18+ — Codex and Claude Code CLI are npm packages, so yes, you need this
77
85
  - A fast credit card — essential
78
86
 
@@ -27,6 +27,13 @@ This tool is designed to:
27
27
  # Install the package
28
28
  pip install overkill # or: uv tool install overkill / pipx install overkill
29
29
 
30
+ # As a project dependency (uv)
31
+ uv add overkill
32
+
33
+ # Upgrade
34
+ pip install --upgrade overkill
35
+ uv lock --upgrade-package overkill # uv projects
36
+
30
37
  # Initialize your project
31
38
  overkill init /path/to/your-project
32
39
  ```
@@ -50,7 +57,7 @@ You need these to participate in the madness:
50
57
 
51
58
  **Runtime**:
52
59
 
53
- - [Python](https://www.python.org/) 3.12+ — for the `overkill` CLI
60
+ - [Python](https://www.python.org/) 3.11+ — for the `overkill` CLI
54
61
  - [Node.js](https://nodejs.org/) v18+ — Codex and Claude Code CLI are npm packages, so yes, you need this
55
62
  - A fast credit card — essential
56
63
 
@@ -6,6 +6,8 @@ You are a code reviewer analyzing a proposed change.
6
6
  - **Target branch**: ${TARGET_BRANCH}
7
7
  - **Review iteration**: ${ITERATION}
8
8
 
9
+ ${REVIEWER_CONTEXT}
10
+
9
11
  ## Instructions
10
12
 
11
13
  Start by running the following command to get the diff:
@@ -6,6 +6,8 @@ You are a code reviewer analyzing a proposed change.
6
6
  - **Target branch**: ${TARGET_BRANCH}
7
7
  - **Review iteration**: ${ITERATION}
8
8
 
9
+ ${REVIEWER_CONTEXT}
10
+
9
11
  ## Instructions
10
12
 
11
13
  Run the following command to get the diff:
@@ -6,6 +6,8 @@ You are a code reviewer analyzing a proposed change.
6
6
  - **Target branch**: ${TARGET_BRANCH}
7
7
  - **Review iteration**: ${ITERATION}
8
8
 
9
+ ${REVIEWER_CONTEXT}
10
+
9
11
  ## Instructions
10
12
 
11
13
  Start by running the following command to get the diff:
@@ -1,10 +1,10 @@
1
1
  [project]
2
2
  name = "overkill"
3
- version = "0.4.1"
3
+ version = "0.5.1"
4
4
  description = "AI-powered code review loop — automates Codex review + Claude fix cycles"
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
7
- requires-python = ">=3.12"
7
+ requires-python = ">=3.11"
8
8
  authors = [{ name = "ModocAI" }]
9
9
  keywords = ["code-review", "refactoring", "ai", "claude", "codex", "automation"]
10
10
  classifiers = [
@@ -14,6 +14,7 @@ classifiers = [
14
14
  "License :: OSI Approved :: MIT License",
15
15
  "Operating System :: OS Independent",
16
16
  "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.11",
17
18
  "Programming Language :: Python :: 3.12",
18
19
  "Programming Language :: Python :: 3.13",
19
20
  "Topic :: Software Development :: Quality Assurance",
@@ -44,14 +45,14 @@ testpaths = ["tests"]
44
45
  pythonpath = ["src"]
45
46
 
46
47
  [tool.ruff]
47
- target-version = "py312"
48
+ target-version = "py311"
48
49
  src = ["src", "tests"]
49
50
 
50
51
  [tool.ruff.lint]
51
52
  select = ["E", "F", "I", "UP", "B", "SIM", "RUF"]
52
53
 
53
54
  [tool.mypy]
54
- python_version = "3.12"
55
+ python_version = "3.11"
55
56
  strict = true
56
57
  warn_return_any = true
57
58
  warn_unused_configs = true
@@ -38,6 +38,13 @@ from mr_overkill.two_step_fix import claude_two_step_fix
38
38
  logger = logging.getLogger(__name__)
39
39
 
40
40
 
41
+ def _format_reviewer_context(raw: str) -> str:
42
+ """Wrap non-empty reviewer context in a markdown section."""
43
+ if not raw:
44
+ return ""
45
+ return f"## Author Context\n\n{raw}"
46
+
47
+
41
48
  # ── Budget / retry helpers (moved from review_loop.py) ───────────────
42
49
 
43
50
 
@@ -167,6 +174,7 @@ class CodexReviewAgent(ReviewAgent):
167
174
  "CURRENT_BRANCH": config.current_branch,
168
175
  "TARGET_BRANCH": config.target_branch,
169
176
  "ITERATION": str(iteration),
177
+ "REVIEWER_CONTEXT": _format_reviewer_context(config.reviewer_context),
170
178
  })
171
179
 
172
180
  if not self._budget_fn("codex", config.budget_scope, 0):
@@ -268,6 +276,7 @@ class ClaudeReviewAgent(ReviewAgent):
268
276
  "CURRENT_BRANCH": config.current_branch,
269
277
  "TARGET_BRANCH": config.target_branch,
270
278
  "ITERATION": str(iteration),
279
+ "REVIEWER_CONTEXT": _format_reviewer_context(config.reviewer_context),
271
280
  })
272
281
 
273
282
  if not self._budget_fn("claude", config.budget_scope, 0):
@@ -365,6 +374,7 @@ class GeminiReviewAgent(ReviewAgent):
365
374
  "CURRENT_BRANCH": config.current_branch,
366
375
  "TARGET_BRANCH": config.target_branch,
367
376
  "ITERATION": str(iteration),
377
+ "REVIEWER_CONTEXT": _format_reviewer_context(config.reviewer_context),
368
378
  })
369
379
 
370
380
  if not self._budget_fn("gemini", config.budget_scope, 0):
@@ -108,13 +108,14 @@ def _load_rc_file(rc_name: str) -> dict[str, str]:
108
108
  "RETRY_INITIAL_WAIT", "BUDGET_SCOPE", "DIAGNOSTIC_LOG",
109
109
  "SCOPE", "AUTO_APPROVE", "CREATE_PR", "WITH_REVIEW",
110
110
  "REVIEW_LOOPS", "FIX_NITS", "REVIEWER_BACKEND",
111
+ "REVIEWER_CONTEXT",
111
112
  }
112
113
  boolean_keys = {
113
114
  "DRY_RUN", "AUTO_COMMIT", "DIAGNOSTIC_LOG",
114
115
  "AUTO_APPROVE", "CREATE_PR", "WITH_REVIEW", "FIX_NITS",
115
116
  }
116
117
  kv_re = re.compile(
117
- r"^\s*(\w+)=[\"']?([^\"']*)[\"']?\s*$"
118
+ r"""^\s*(\w+)=(?:"([^"]*)"|'([^']*)'|(.*?))\s*$"""
118
119
  )
119
120
  values: dict[str, str] = {}
120
121
 
@@ -124,7 +125,8 @@ def _load_rc_file(rc_name: str) -> dict[str, str]:
124
125
  continue
125
126
  m = kv_re.match(line)
126
127
  if m and m.group(1) in allowed_keys:
127
- key, val = m.group(1), m.group(2).strip()
128
+ raw = m.group(2) or m.group(3) or m.group(4) or ""
129
+ key, val = m.group(1), raw.strip()
128
130
  if key in boolean_keys and val.lower() not in ("true", "false"):
129
131
  msg = f"{rc_path.name}: {key} must be 'true' or 'false', got '{val}'."
130
132
  raise SystemExit(f"Error: {msg}")
@@ -299,6 +301,11 @@ def parse_review_loop_args(
299
301
  choices=["claude", "codex", "gemini"],
300
302
  help="Backend for code review (default: codex)",
301
303
  )
304
+ parser.add_argument(
305
+ "--context",
306
+ default=None,
307
+ help="Additional context for the reviewer (e.g. design intent, constraints)",
308
+ )
302
309
 
303
310
  args = parser.parse_args(argv)
304
311
 
@@ -394,6 +401,10 @@ def parse_review_loop_args(
394
401
  saved = log_dir / "reviewer-backend.txt"
395
402
  if saved.is_file():
396
403
  args.reviewer_backend = saved.read_text().strip()
404
+ if args.context is None:
405
+ saved = log_dir / "reviewer-context.txt"
406
+ if saved.is_file():
407
+ args.context = saved.read_text().strip()
397
408
 
398
409
  if max_loop is not None and max_loop < 1:
399
410
  parser.error("--max-loop must be a positive integer")
@@ -405,6 +416,10 @@ def parse_review_loop_args(
405
416
  f" got {reviewer_backend!r}"
406
417
  )
407
418
 
419
+ reviewer_context = (
420
+ args.context if args.context is not None else rc.get("REVIEWER_CONTEXT", "")
421
+ )
422
+
408
423
  return LoopConfig(
409
424
  current_branch=current_branch,
410
425
  target_branch=target,
@@ -425,6 +440,7 @@ def parse_review_loop_args(
425
440
  prompts_dir=prompts_dir,
426
441
  pr_number=pr_number,
427
442
  reviewer_backend=reviewer_backend,
443
+ reviewer_context=reviewer_context,
428
444
  )
429
445
 
430
446
 
@@ -635,6 +635,7 @@ def _save_metadata(config: LoopConfig, cwd: Path | None) -> None:
635
635
  (log_dir / "target-branch.txt").write_text(config.target_branch)
636
636
  (log_dir / "max-loop.txt").write_text(str(config.max_loop))
637
637
  (log_dir / "reviewer-backend.txt").write_text(config.reviewer_backend)
638
+ (log_dir / "reviewer-context.txt").write_text(config.reviewer_context)
638
639
  if config.scope:
639
640
  (log_dir / "scope.txt").write_text(config.scope)
640
641
 
@@ -22,7 +22,11 @@ class BudgetTimeoutError(Exception):
22
22
  # ── Enums ────────────────────────────────────────────────────────────
23
23
 
24
24
 
25
- class ErrorClass(StrEnum):
25
+ class _StrEnum(StrEnum):
26
+ """Thin base so all project enums share a single parent."""
27
+
28
+
29
+ class ErrorClass(_StrEnum):
26
30
  """Classification of a CLI error for retry decisions."""
27
31
 
28
32
  TRANSIENT = "transient"
@@ -30,7 +34,7 @@ class ErrorClass(StrEnum):
30
34
  UNKNOWN = "unknown"
31
35
 
32
36
 
33
- class BudgetScope(StrEnum):
37
+ class BudgetScope(_StrEnum):
34
38
  """Granularity of a budget check — determines the usage threshold."""
35
39
 
36
40
  MICRO = "micro"
@@ -39,7 +43,7 @@ class BudgetScope(StrEnum):
39
43
  FULL = "full"
40
44
 
41
45
 
42
- class FinalStatus(StrEnum):
46
+ class FinalStatus(_StrEnum):
43
47
  """Terminal states for a review/refactor loop run."""
44
48
 
45
49
  ALL_CLEAR = "all_clear"
@@ -174,6 +178,9 @@ class LoopConfig:
174
178
  # Reviewer backend
175
179
  reviewer_backend: str = "codex" # "codex" | "claude" | "gemini"
176
180
 
181
+ # Additional context for the reviewer
182
+ reviewer_context: str = ""
183
+
177
184
  # Refactor-specific
178
185
  scope: str | None = None # micro | module | layer | full
179
186
  skip_initial_no_diff: bool = False # refactor: 1st iteration has no diff
@@ -1,6 +1,6 @@
1
1
  version = 1
2
2
  revision = 2
3
- requires-python = ">=3.12"
3
+ requires-python = ">=3.11"
4
4
 
5
5
  [[package]]
6
6
  name = "colorama"
@@ -17,6 +17,21 @@ version = "7.13.4"
17
17
  source = { registry = "https://pypi.org/simple" }
18
18
  sdist = { url = "https://files.pythonhosted.org/packages/24/56/95b7e30fa389756cb56630faa728da46a27b8c6eb46f9d557c68fff12b65/coverage-7.13.4.tar.gz", hash = "sha256:e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91", size = 827239, upload-time = "2026-02-09T12:59:03.86Z" }
19
19
  wheels = [
20
+ { url = "https://files.pythonhosted.org/packages/b4/ad/b59e5b451cf7172b8d1043dc0fa718f23aab379bc1521ee13d4bd9bfa960/coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053", size = 219278, upload-time = "2026-02-09T12:56:31.673Z" },
21
+ { url = "https://files.pythonhosted.org/packages/f1/17/0cb7ca3de72e5f4ef2ec2fa0089beafbcaaaead1844e8b8a63d35173d77d/coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11", size = 219783, upload-time = "2026-02-09T12:56:33.104Z" },
22
+ { url = "https://files.pythonhosted.org/packages/ab/63/325d8e5b11e0eaf6d0f6a44fad444ae58820929a9b0de943fa377fe73e85/coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa", size = 250200, upload-time = "2026-02-09T12:56:34.474Z" },
23
+ { url = "https://files.pythonhosted.org/packages/76/53/c16972708cbb79f2942922571a687c52bd109a7bd51175aeb7558dff2236/coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7", size = 252114, upload-time = "2026-02-09T12:56:35.749Z" },
24
+ { url = "https://files.pythonhosted.org/packages/eb/c2/7ab36d8b8cc412bec9ea2d07c83c48930eb4ba649634ba00cb7e4e0f9017/coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00", size = 254220, upload-time = "2026-02-09T12:56:37.796Z" },
25
+ { url = "https://files.pythonhosted.org/packages/d6/4d/cf52c9a3322c89a0e6febdfbc83bb45c0ed3c64ad14081b9503adee702e7/coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef", size = 256164, upload-time = "2026-02-09T12:56:39.016Z" },
26
+ { url = "https://files.pythonhosted.org/packages/78/e9/eb1dd17bd6de8289df3580e967e78294f352a5df8a57ff4671ee5fc3dcd0/coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903", size = 250325, upload-time = "2026-02-09T12:56:40.668Z" },
27
+ { url = "https://files.pythonhosted.org/packages/71/07/8c1542aa873728f72267c07278c5cc0ec91356daf974df21335ccdb46368/coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f", size = 251913, upload-time = "2026-02-09T12:56:41.97Z" },
28
+ { url = "https://files.pythonhosted.org/packages/74/d7/c62e2c5e4483a748e27868e4c32ad3daa9bdddbba58e1bc7a15e252baa74/coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299", size = 249974, upload-time = "2026-02-09T12:56:43.323Z" },
29
+ { url = "https://files.pythonhosted.org/packages/98/9f/4c5c015a6e98ced54efd0f5cf8d31b88e5504ecb6857585fc0161bb1e600/coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505", size = 253741, upload-time = "2026-02-09T12:56:45.155Z" },
30
+ { url = "https://files.pythonhosted.org/packages/bd/59/0f4eef89b9f0fcd9633b5d350016f54126ab49426a70ff4c4e87446cabdc/coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6", size = 249695, upload-time = "2026-02-09T12:56:46.636Z" },
31
+ { url = "https://files.pythonhosted.org/packages/b5/2c/b7476f938deb07166f3eb281a385c262675d688ff4659ad56c6c6b8e2e70/coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9", size = 250599, upload-time = "2026-02-09T12:56:48.13Z" },
32
+ { url = "https://files.pythonhosted.org/packages/b8/34/c3420709d9846ee3785b9f2831b4d94f276f38884032dca1457fa83f7476/coverage-7.13.4-cp311-cp311-win32.whl", hash = "sha256:784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9", size = 221780, upload-time = "2026-02-09T12:56:50.479Z" },
33
+ { url = "https://files.pythonhosted.org/packages/61/08/3d9c8613079d2b11c185b865de9a4c1a68850cfda2b357fae365cf609f29/coverage-7.13.4-cp311-cp311-win_amd64.whl", hash = "sha256:2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f", size = 222715, upload-time = "2026-02-09T12:56:51.815Z" },
34
+ { url = "https://files.pythonhosted.org/packages/18/1a/54c3c80b2f056164cc0a6cdcb040733760c7c4be9d780fe655f356f433e4/coverage-7.13.4-cp311-cp311-win_arm64.whl", hash = "sha256:79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f", size = 221385, upload-time = "2026-02-09T12:56:53.194Z" },
20
35
  { url = "https://files.pythonhosted.org/packages/d1/81/4ce2fdd909c5a0ed1f6dedb88aa57ab79b6d1fbd9b588c1ac7ef45659566/coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459", size = 219449, upload-time = "2026-02-09T12:56:54.889Z" },
21
36
  { url = "https://files.pythonhosted.org/packages/5d/96/5238b1efc5922ddbdc9b0db9243152c09777804fb7c02ad1741eb18a11c0/coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3", size = 219810, upload-time = "2026-02-09T12:56:56.33Z" },
22
37
  { url = "https://files.pythonhosted.org/packages/78/72/2f372b726d433c9c35e56377cf1d513b4c16fe51841060d826b95caacec1/coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634", size = 251308, upload-time = "2026-02-09T12:56:57.858Z" },
@@ -95,6 +110,11 @@ wheels = [
95
110
  { url = "https://files.pythonhosted.org/packages/0d/4a/331fe2caf6799d591109bb9c08083080f6de90a823695d412a935622abb2/coverage-7.13.4-py3-none-any.whl", hash = "sha256:1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0", size = 211242, upload-time = "2026-02-09T12:59:02.032Z" },
96
111
  ]
97
112
 
113
+ [package.optional-dependencies]
114
+ toml = [
115
+ { name = "tomli", marker = "python_full_version <= '3.11'" },
116
+ ]
117
+
98
118
  [[package]]
99
119
  name = "iniconfig"
100
120
  version = "2.3.0"
@@ -110,6 +130,19 @@ version = "0.8.1"
110
130
  source = { registry = "https://pypi.org/simple" }
111
131
  sdist = { url = "https://files.pythonhosted.org/packages/56/9c/b4b0c54d84da4a94b37bd44151e46d5e583c9534c7e02250b961b1b6d8a8/librt-0.8.1.tar.gz", hash = "sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73", size = 177471, upload-time = "2026-02-17T16:13:06.101Z" }
112
132
  wheels = [
133
+ { url = "https://files.pythonhosted.org/packages/1d/01/0e748af5e4fee180cf7cd12bd12b0513ad23b045dccb2a83191bde82d168/librt-0.8.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd", size = 65315, upload-time = "2026-02-17T16:11:25.152Z" },
134
+ { url = "https://files.pythonhosted.org/packages/9d/4d/7184806efda571887c798d573ca4134c80ac8642dcdd32f12c31b939c595/librt-0.8.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965", size = 68021, upload-time = "2026-02-17T16:11:26.129Z" },
135
+ { url = "https://files.pythonhosted.org/packages/ae/88/c3c52d2a5d5101f28d3dc89298444626e7874aa904eed498464c2af17627/librt-0.8.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da", size = 194500, upload-time = "2026-02-17T16:11:27.177Z" },
136
+ { url = "https://files.pythonhosted.org/packages/d6/5d/6fb0a25b6a8906e85b2c3b87bee1d6ed31510be7605b06772f9374ca5cb3/librt-0.8.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0", size = 205622, upload-time = "2026-02-17T16:11:28.242Z" },
137
+ { url = "https://files.pythonhosted.org/packages/b2/a6/8006ae81227105476a45691f5831499e4d936b1c049b0c1feb17c11b02d1/librt-0.8.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e", size = 218304, upload-time = "2026-02-17T16:11:29.344Z" },
138
+ { url = "https://files.pythonhosted.org/packages/ee/19/60e07886ad16670aae57ef44dada41912c90906a6fe9f2b9abac21374748/librt-0.8.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3", size = 211493, upload-time = "2026-02-17T16:11:30.445Z" },
139
+ { url = "https://files.pythonhosted.org/packages/9c/cf/f666c89d0e861d05600438213feeb818c7514d3315bae3648b1fc145d2b6/librt-0.8.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac", size = 219129, upload-time = "2026-02-17T16:11:32.021Z" },
140
+ { url = "https://files.pythonhosted.org/packages/8f/ef/f1bea01e40b4a879364c031476c82a0dc69ce068daad67ab96302fed2d45/librt-0.8.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596", size = 213113, upload-time = "2026-02-17T16:11:33.192Z" },
141
+ { url = "https://files.pythonhosted.org/packages/9b/80/cdab544370cc6bc1b72ea369525f547a59e6938ef6863a11ab3cd24759af/librt-0.8.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99", size = 212269, upload-time = "2026-02-17T16:11:34.373Z" },
142
+ { url = "https://files.pythonhosted.org/packages/9d/9c/48d6ed8dac595654f15eceab2035131c136d1ae9a1e3548e777bb6dbb95d/librt-0.8.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe", size = 234673, upload-time = "2026-02-17T16:11:36.063Z" },
143
+ { url = "https://files.pythonhosted.org/packages/16/01/35b68b1db517f27a01be4467593292eb5315def8900afad29fabf56304ba/librt-0.8.1-cp311-cp311-win32.whl", hash = "sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb", size = 54597, upload-time = "2026-02-17T16:11:37.544Z" },
144
+ { url = "https://files.pythonhosted.org/packages/71/02/796fe8f02822235966693f257bf2c79f40e11337337a657a8cfebba5febc/librt-0.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b", size = 61733, upload-time = "2026-02-17T16:11:38.691Z" },
145
+ { url = "https://files.pythonhosted.org/packages/28/ad/232e13d61f879a42a4e7117d65e4984bb28371a34bb6fb9ca54ec2c8f54e/librt-0.8.1-cp311-cp311-win_arm64.whl", hash = "sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9", size = 52273, upload-time = "2026-02-17T16:11:40.308Z" },
113
146
  { url = "https://files.pythonhosted.org/packages/95/21/d39b0a87ac52fc98f621fb6f8060efb017a767ebbbac2f99fbcbc9ddc0d7/librt-0.8.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a", size = 66516, upload-time = "2026-02-17T16:11:41.604Z" },
114
147
  { url = "https://files.pythonhosted.org/packages/69/f1/46375e71441c43e8ae335905e069f1c54febee63a146278bcee8782c84fd/librt-0.8.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9", size = 68634, upload-time = "2026-02-17T16:11:43.268Z" },
115
148
  { url = "https://files.pythonhosted.org/packages/0a/33/c510de7f93bf1fa19e13423a606d8189a02624a800710f6e6a0a0f0784b3/librt-0.8.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb", size = 198941, upload-time = "2026-02-17T16:11:44.28Z" },
@@ -176,6 +209,12 @@ dependencies = [
176
209
  ]
177
210
  sdist = { url = "https://files.pythonhosted.org/packages/f5/db/4efed9504bc01309ab9c2da7e352cc223569f05478012b5d9ece38fd44d2/mypy-1.19.1.tar.gz", hash = "sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba", size = 3582404, upload-time = "2025-12-15T05:03:48.42Z" }
178
211
  wheels = [
212
+ { url = "https://files.pythonhosted.org/packages/ef/47/6b3ebabd5474d9cdc170d1342fbf9dddc1b0ec13ec90bf9004ee6f391c31/mypy-1.19.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288", size = 13028539, upload-time = "2025-12-15T05:03:44.129Z" },
213
+ { url = "https://files.pythonhosted.org/packages/5c/a6/ac7c7a88a3c9c54334f53a941b765e6ec6c4ebd65d3fe8cdcfbe0d0fd7db/mypy-1.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab", size = 12083163, upload-time = "2025-12-15T05:03:37.679Z" },
214
+ { url = "https://files.pythonhosted.org/packages/67/af/3afa9cf880aa4a2c803798ac24f1d11ef72a0c8079689fac5cfd815e2830/mypy-1.19.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6", size = 12687629, upload-time = "2025-12-15T05:02:31.526Z" },
215
+ { url = "https://files.pythonhosted.org/packages/2d/46/20f8a7114a56484ab268b0ab372461cb3a8f7deed31ea96b83a4e4cfcfca/mypy-1.19.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331", size = 13436933, upload-time = "2025-12-15T05:03:15.606Z" },
216
+ { url = "https://files.pythonhosted.org/packages/5b/f8/33b291ea85050a21f15da910002460f1f445f8007adb29230f0adea279cb/mypy-1.19.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925", size = 13661754, upload-time = "2025-12-15T05:02:26.731Z" },
217
+ { url = "https://files.pythonhosted.org/packages/fd/a3/47cbd4e85bec4335a9cd80cf67dbc02be21b5d4c9c23ad6b95d6c5196bac/mypy-1.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042", size = 10055772, upload-time = "2025-12-15T05:03:26.179Z" },
179
218
  { url = "https://files.pythonhosted.org/packages/06/8a/19bfae96f6615aa8a0604915512e0289b1fad33d5909bf7244f02935d33a/mypy-1.19.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1", size = 13206053, upload-time = "2025-12-15T05:03:46.622Z" },
180
219
  { url = "https://files.pythonhosted.org/packages/a5/34/3e63879ab041602154ba2a9f99817bb0c85c4df19a23a1443c8986e4d565/mypy-1.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e", size = 12219134, upload-time = "2025-12-15T05:03:24.367Z" },
181
220
  { url = "https://files.pythonhosted.org/packages/89/cc/2db6f0e95366b630364e09845672dbee0cbf0bbe753a204b29a944967cd9/mypy-1.19.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2", size = 12731616, upload-time = "2025-12-15T05:02:44.725Z" },
@@ -208,7 +247,7 @@ wheels = [
208
247
 
209
248
  [[package]]
210
249
  name = "overkill"
211
- version = "0.3.0"
250
+ version = "0.5.0"
212
251
  source = { editable = "." }
213
252
 
214
253
  [package.dev-dependencies]
@@ -288,7 +327,7 @@ name = "pytest-cov"
288
327
  version = "7.0.0"
289
328
  source = { registry = "https://pypi.org/simple" }
290
329
  dependencies = [
291
- { name = "coverage" },
330
+ { name = "coverage", extra = ["toml"] },
292
331
  { name = "pluggy" },
293
332
  { name = "pytest" },
294
333
  ]
@@ -334,6 +373,60 @@ wheels = [
334
373
  { url = "https://files.pythonhosted.org/packages/3e/0a/9e1be9035b37448ce2e68c978f0591da94389ade5a5abafa4cf99985d1b2/ruff-0.15.4-py3-none-win_arm64.whl", hash = "sha256:60d5177e8cfc70e51b9c5fad936c634872a74209f934c1e79107d11787ad5453", size = 10966776, upload-time = "2026-02-26T20:03:56.908Z" },
335
374
  ]
336
375
 
376
+ [[package]]
377
+ name = "tomli"
378
+ version = "2.4.1"
379
+ source = { registry = "https://pypi.org/simple" }
380
+ sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" }
381
+ wheels = [
382
+ { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" },
383
+ { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" },
384
+ { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" },
385
+ { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" },
386
+ { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" },
387
+ { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" },
388
+ { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" },
389
+ { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" },
390
+ { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" },
391
+ { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" },
392
+ { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" },
393
+ { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" },
394
+ { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" },
395
+ { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" },
396
+ { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" },
397
+ { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" },
398
+ { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" },
399
+ { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" },
400
+ { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" },
401
+ { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" },
402
+ { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" },
403
+ { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" },
404
+ { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" },
405
+ { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" },
406
+ { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" },
407
+ { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" },
408
+ { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" },
409
+ { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" },
410
+ { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" },
411
+ { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" },
412
+ { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" },
413
+ { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" },
414
+ { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" },
415
+ { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" },
416
+ { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" },
417
+ { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" },
418
+ { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" },
419
+ { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" },
420
+ { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" },
421
+ { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" },
422
+ { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" },
423
+ { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" },
424
+ { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" },
425
+ { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" },
426
+ { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" },
427
+ { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" },
428
+ ]
429
+
337
430
  [[package]]
338
431
  name = "typing-extensions"
339
432
  version = "4.15.0"
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