crackerjack 0.38.12__py3-none-any.whl → 0.38.14__py3-none-any.whl
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.
Potentially problematic release.
This version of crackerjack might be problematic. Click here for more details.
- crackerjack/__main__.py +0 -1
- crackerjack/dynamic_config.py +0 -19
- crackerjack/executors/cached_hook_executor.py +2 -2
- crackerjack/orchestration/execution_strategies.py +1 -1
- crackerjack/py313.py +189 -0
- crackerjack/services/cache.py +0 -2
- crackerjack/services/config_template.py +6 -5
- {crackerjack-0.38.12.dist-info → crackerjack-0.38.14.dist-info}/METADATA +3 -3
- {crackerjack-0.38.12.dist-info → crackerjack-0.38.14.dist-info}/RECORD +12 -11
- {crackerjack-0.38.12.dist-info → crackerjack-0.38.14.dist-info}/WHEEL +0 -0
- {crackerjack-0.38.12.dist-info → crackerjack-0.38.14.dist-info}/entry_points.txt +0 -0
- {crackerjack-0.38.12.dist-info → crackerjack-0.38.14.dist-info}/licenses/LICENSE +0 -0
crackerjack/__main__.py
CHANGED
|
@@ -1318,7 +1318,6 @@ def main(
|
|
|
1318
1318
|
config_interactive: bool = CLI_OPTIONS["config_interactive"],
|
|
1319
1319
|
refresh_cache: bool = CLI_OPTIONS["refresh_cache"],
|
|
1320
1320
|
) -> None:
|
|
1321
|
-
"""Main CLI entry point with complexity <= 15."""
|
|
1322
1321
|
options = create_options(
|
|
1323
1322
|
commit,
|
|
1324
1323
|
interactive,
|
crackerjack/dynamic_config.py
CHANGED
|
@@ -366,24 +366,6 @@ HOOKS_REGISTRY: dict[str, list[HookMetadata]] = {
|
|
|
366
366
|
"experimental": False,
|
|
367
367
|
"pass_filenames": False,
|
|
368
368
|
},
|
|
369
|
-
{
|
|
370
|
-
"id": "pyright",
|
|
371
|
-
"name": "pyright-type-checking",
|
|
372
|
-
"repo": "local",
|
|
373
|
-
"rev": "",
|
|
374
|
-
"tier": 3,
|
|
375
|
-
"time_estimate": 0.25,
|
|
376
|
-
"stages": ["pre-push", "manual"],
|
|
377
|
-
"args": [],
|
|
378
|
-
"files": "^crackerjack/.*\\.py$",
|
|
379
|
-
"exclude": r"^crackerjack/(mcp|plugins)/.*\.py$|crackerjack/code_cleaner\.py$",
|
|
380
|
-
"additional_dependencies": None,
|
|
381
|
-
"types_or": None,
|
|
382
|
-
"language": "system",
|
|
383
|
-
"entry": "uv run pyright",
|
|
384
|
-
"experimental": False,
|
|
385
|
-
"pass_filenames": None,
|
|
386
|
-
},
|
|
387
369
|
],
|
|
388
370
|
"experimental": [],
|
|
389
371
|
}
|
|
@@ -579,7 +561,6 @@ class DynamicConfigGenerator:
|
|
|
579
561
|
"bandit",
|
|
580
562
|
"refurb",
|
|
581
563
|
"complexipy",
|
|
582
|
-
"pyright",
|
|
583
564
|
):
|
|
584
565
|
hook["exclude"] = r"^tests/|^src/"
|
|
585
566
|
else:
|
|
@@ -261,11 +261,11 @@ class SmartCacheManager:
|
|
|
261
261
|
hook_name: str,
|
|
262
262
|
project_state: dict[str, t.Any],
|
|
263
263
|
) -> bool:
|
|
264
|
-
external_hooks =
|
|
264
|
+
external_hooks = set()
|
|
265
265
|
if hook_name in external_hooks:
|
|
266
266
|
return False
|
|
267
267
|
|
|
268
|
-
expensive_hooks = {"pyright", "bandit", "vulture", "complexipy"}
|
|
268
|
+
expensive_hooks = {"pyright", "bandit", "vulture", "complexipy", "gitleaks"}
|
|
269
269
|
if hook_name in expensive_hooks:
|
|
270
270
|
return True
|
|
271
271
|
|
|
@@ -198,7 +198,7 @@ class StrategySelector:
|
|
|
198
198
|
if "test" in str(file_path):
|
|
199
199
|
priority_hooks.update(["pytest", "coverage"])
|
|
200
200
|
if str(file_path).endswith(("setup.py", "pyproject.toml")):
|
|
201
|
-
priority_hooks.update(["bandit", "creosote", "
|
|
201
|
+
priority_hooks.update(["bandit", "creosote", "gitleaks"])
|
|
202
202
|
|
|
203
203
|
selected_hooks = [
|
|
204
204
|
hook for hook in strategy.hooks if hook.name in priority_hooks
|
crackerjack/py313.py
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import typing
|
|
3
|
+
from enum import Enum, auto
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Any, Self, TypedDict
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CommandRunner[TReturn]:
|
|
9
|
+
def run_command(self, cmd: list[str], **kwargs: Any) -> TReturn:
|
|
10
|
+
raise NotImplementedError("Subclasses must implement run_command")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CommandResult(TypedDict):
|
|
14
|
+
success: bool
|
|
15
|
+
exit_code: int
|
|
16
|
+
stdout: str
|
|
17
|
+
stderr: str
|
|
18
|
+
command: list[str]
|
|
19
|
+
duration_ms: float
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def process_command_output(result: CommandResult) -> tuple[bool, str]:
|
|
23
|
+
match result:
|
|
24
|
+
case {"success": True, "stdout": stdout} if stdout.strip():
|
|
25
|
+
return (True, stdout)
|
|
26
|
+
case {"success": True}:
|
|
27
|
+
return (True, "Command completed successfully with no output")
|
|
28
|
+
case {"success": False, "exit_code": code, "stderr": stderr} if code == 127:
|
|
29
|
+
return (False, f"Command not found: {stderr}")
|
|
30
|
+
case {"success": False, "exit_code": code} if code > 0:
|
|
31
|
+
return (False, f"Command failed with exit code {code}: {result['stderr']}")
|
|
32
|
+
case _:
|
|
33
|
+
pass
|
|
34
|
+
return (False, "Unknown command result pattern")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class HookStatus(Enum):
|
|
38
|
+
SUCCESS = auto()
|
|
39
|
+
FAILURE = auto()
|
|
40
|
+
SKIPPED = auto()
|
|
41
|
+
ERROR = auto()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class HookResult(TypedDict):
|
|
45
|
+
status: HookStatus
|
|
46
|
+
hook_id: str
|
|
47
|
+
output: str
|
|
48
|
+
files: list[str]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def analyze_hook_result(result: HookResult) -> str:
|
|
52
|
+
match result:
|
|
53
|
+
case {"status": HookStatus.SUCCESS, "hook_id": hook_id}:
|
|
54
|
+
return f"✅ Hook {hook_id} passed successfully"
|
|
55
|
+
case {"status": HookStatus.FAILURE, "hook_id": hook_id, "output": output} if (
|
|
56
|
+
"fixable" in output
|
|
57
|
+
):
|
|
58
|
+
return f"🔧 Hook {hook_id} failed with fixable issues"
|
|
59
|
+
case {"status": HookStatus.FAILURE, "hook_id": hook_id}:
|
|
60
|
+
return f"❌ Hook {hook_id} failed"
|
|
61
|
+
case {"status": HookStatus.SKIPPED, "hook_id": hook_id}:
|
|
62
|
+
return f"⏩ Hook {hook_id} was skipped"
|
|
63
|
+
case {"status": HookStatus.ERROR, "hook_id": hook_id, "output": output}:
|
|
64
|
+
return f"💥 Hook {hook_id} encountered an error: {output}"
|
|
65
|
+
case _:
|
|
66
|
+
pass
|
|
67
|
+
return "Unknown hook result pattern"
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class ModernConfigManager:
|
|
71
|
+
def __init__(self, config_path: Path) -> None:
|
|
72
|
+
self.config_path = config_path
|
|
73
|
+
self.config: dict[str, Any] = {}
|
|
74
|
+
|
|
75
|
+
def load(self) -> Self:
|
|
76
|
+
return self
|
|
77
|
+
|
|
78
|
+
def update(self, key: str, value: Any) -> Self:
|
|
79
|
+
self.config[key] = value
|
|
80
|
+
return self
|
|
81
|
+
|
|
82
|
+
def save(self) -> Self:
|
|
83
|
+
return self
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def categorize_file(file_path: Path) -> str:
|
|
87
|
+
path_str = str(file_path)
|
|
88
|
+
name = file_path
|
|
89
|
+
match path_str:
|
|
90
|
+
case s if name.suffix == ".py" and "/ tests /" in s:
|
|
91
|
+
return "Python Test File"
|
|
92
|
+
case s if name.suffix == ".py" and "__init__.py" in name.name:
|
|
93
|
+
return "Python Module Init"
|
|
94
|
+
case s if name.suffix == ".py":
|
|
95
|
+
return "Python Source File"
|
|
96
|
+
case s if name.suffix in {".md", ".rst", ".txt"}:
|
|
97
|
+
return "Documentation File"
|
|
98
|
+
case s if name.stem.startswith(".") or name.name in {
|
|
99
|
+
".gitignore",
|
|
100
|
+
".pre-commit-config.yaml",
|
|
101
|
+
}:
|
|
102
|
+
return "Configuration File"
|
|
103
|
+
case _:
|
|
104
|
+
pass
|
|
105
|
+
return "Unknown File Type"
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def process_hook_results[T: HookResult, R](
|
|
109
|
+
results: list[T],
|
|
110
|
+
success_handler: typing.Callable[[T], R],
|
|
111
|
+
failure_handler: typing.Callable[[T], R],
|
|
112
|
+
) -> list[R]:
|
|
113
|
+
processed_results: list[R] = []
|
|
114
|
+
for result in results:
|
|
115
|
+
# Type checker knows T is HookResult, so no need for isinstance check
|
|
116
|
+
# But we keep it for runtime safety
|
|
117
|
+
if hasattr(result, "status") and result.status == HookStatus.SUCCESS:
|
|
118
|
+
processed_results.append(success_handler(result))
|
|
119
|
+
else:
|
|
120
|
+
processed_results.append(failure_handler(result))
|
|
121
|
+
return processed_results
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class EnhancedCommandRunner:
|
|
125
|
+
def __init__(self, working_dir: Path | None = None) -> None:
|
|
126
|
+
self.working_dir = working_dir
|
|
127
|
+
|
|
128
|
+
def run(self, cmd: list[str], **kwargs: Any) -> CommandResult:
|
|
129
|
+
import time
|
|
130
|
+
|
|
131
|
+
start_time = time.time()
|
|
132
|
+
try:
|
|
133
|
+
process = subprocess.run(
|
|
134
|
+
cmd,
|
|
135
|
+
check=False,
|
|
136
|
+
capture_output=True,
|
|
137
|
+
text=True,
|
|
138
|
+
cwd=self.working_dir,
|
|
139
|
+
**kwargs,
|
|
140
|
+
)
|
|
141
|
+
duration_ms = (time.time() - start_time) * 1000
|
|
142
|
+
return CommandResult(
|
|
143
|
+
success=process.returncode == 0,
|
|
144
|
+
exit_code=process.returncode,
|
|
145
|
+
stdout=process.stdout,
|
|
146
|
+
stderr=process.stderr,
|
|
147
|
+
command=cmd,
|
|
148
|
+
duration_ms=duration_ms,
|
|
149
|
+
)
|
|
150
|
+
except subprocess.SubprocessError as e:
|
|
151
|
+
duration_ms = (time.time() - start_time) * 1000
|
|
152
|
+
return CommandResult(
|
|
153
|
+
success=False,
|
|
154
|
+
exit_code=-1,
|
|
155
|
+
stdout="",
|
|
156
|
+
stderr=str(e),
|
|
157
|
+
command=cmd,
|
|
158
|
+
duration_ms=duration_ms,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
def handle_result(self, result: CommandResult) -> tuple[bool, str]:
|
|
162
|
+
return process_command_output(result)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def clean_python_code(code: str) -> str:
|
|
166
|
+
lines = code.splitlines()
|
|
167
|
+
cleaned_lines: list[str] = []
|
|
168
|
+
for line in lines:
|
|
169
|
+
match line.strip():
|
|
170
|
+
case "":
|
|
171
|
+
if not cleaned_lines or cleaned_lines[-1].strip():
|
|
172
|
+
cleaned_lines.append("")
|
|
173
|
+
case s if s.startswith(("import ", "from ")):
|
|
174
|
+
cleaned_lines.append(line)
|
|
175
|
+
case s if s.startswith("#"):
|
|
176
|
+
continue
|
|
177
|
+
case s if "#" in s and (
|
|
178
|
+
not any(
|
|
179
|
+
skip in s for skip in ("# noqa", "# type: ", "# pragma", "# skip")
|
|
180
|
+
)
|
|
181
|
+
):
|
|
182
|
+
code_part = line.split("#", 1)[0].rstrip()
|
|
183
|
+
if code_part:
|
|
184
|
+
cleaned_lines.append(code_part)
|
|
185
|
+
case s if s.startswith(('"""', "'''")):
|
|
186
|
+
continue
|
|
187
|
+
case _:
|
|
188
|
+
cleaned_lines.append(line)
|
|
189
|
+
return "\n".join(cleaned_lines)
|
crackerjack/services/cache.py
CHANGED
|
@@ -228,7 +228,6 @@ class CrackerjackCache:
|
|
|
228
228
|
"complexipy",
|
|
229
229
|
"refurb",
|
|
230
230
|
"gitleaks",
|
|
231
|
-
"detect-secrets",
|
|
232
231
|
}
|
|
233
232
|
|
|
234
233
|
# TTL configuration for different cache types (in seconds)
|
|
@@ -239,7 +238,6 @@ class CrackerjackCache:
|
|
|
239
238
|
"complexipy": 86400, # 24 hours - complexity analysis
|
|
240
239
|
"refurb": 86400, # 24 hours - code improvements
|
|
241
240
|
"gitleaks": 86400 * 7, # 7 days - secret detection is very stable
|
|
242
|
-
"detect-secrets": 86400 * 7, # 7 days - secret detection
|
|
243
241
|
}
|
|
244
242
|
|
|
245
243
|
# Agent version for cache invalidation when agent logic changes
|
|
@@ -95,12 +95,13 @@ class ConfigTemplateService:
|
|
|
95
95
|
"stages": ["pre-push", "manual"],
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
|
-
"id": "
|
|
99
|
-
"name": "
|
|
100
|
-
"entry": "uv run
|
|
98
|
+
"id": "zuban",
|
|
99
|
+
"name": "zuban-type-checking",
|
|
100
|
+
"entry": "uv run zuban check",
|
|
101
101
|
"language": "system",
|
|
102
|
-
"
|
|
103
|
-
"
|
|
102
|
+
"args": ["--config-file", "mypy.ini", "./crackerjack"],
|
|
103
|
+
"pass_filenames": False,
|
|
104
|
+
"exclude": r"^tests/|^src/",
|
|
104
105
|
"stages": ["pre-push", "manual"],
|
|
105
106
|
},
|
|
106
107
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: crackerjack
|
|
3
|
-
Version: 0.38.
|
|
3
|
+
Version: 0.38.14
|
|
4
4
|
Summary: Crackerjack Python project management tool
|
|
5
5
|
Project-URL: documentation, https://github.com/lesleslie/crackerjack
|
|
6
6
|
Project-URL: homepage, https://github.com/lesleslie/crackerjack
|
|
@@ -215,7 +215,7 @@ Limited tool-specific auto-fixes for simple formatting issues:
|
|
|
215
215
|
|
|
216
216
|
The AI agent intelligently fixes:
|
|
217
217
|
|
|
218
|
-
- **Type Errors (
|
|
218
|
+
- **Type Errors (zuban)**: Adds missing annotations, fixes type mismatches
|
|
219
219
|
- **🔒 Security Issues (bandit)**: Comprehensive security hardening including:
|
|
220
220
|
- **Shell Injection Prevention**: Removes `shell=True` from subprocess calls
|
|
221
221
|
- **Weak Cryptography**: Replaces MD5/SHA1 with SHA256
|
|
@@ -679,7 +679,7 @@ Crackerjack runs hooks in a two-stage process for optimal development workflow:
|
|
|
679
679
|
|
|
680
680
|
**Comprehensive Hooks (~30 seconds):**
|
|
681
681
|
|
|
682
|
-
-
|
|
682
|
+
- Zuban type checking
|
|
683
683
|
- Bandit security analysis
|
|
684
684
|
- Dead code detection (vulture)
|
|
685
685
|
- Dependency analysis (creosote)
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
crackerjack/CLAUDE.md,sha256=FnF1XgcaCB59HEZxglEl4qEBTMyHQcqKoL0YjnAq24s,41230
|
|
2
2
|
crackerjack/__init__.py,sha256=DajG9zHB8qBdgdiKMumrrssUbKeMXmtIQ3oOaSTb46Y,1426
|
|
3
|
-
crackerjack/__main__.py,sha256=
|
|
3
|
+
crackerjack/__main__.py,sha256=6Te0CW6qyKiso0cTHv9stWnDZ9W8KnWXzW0oQ3hN7n8,55498
|
|
4
4
|
crackerjack/api.py,sha256=PyCRaZHvKWdu62_2O4t_HcEfKNBdqyrfPdonS_PNn4c,21495
|
|
5
5
|
crackerjack/code_cleaner.py,sha256=M1zVaq31uW0nOkPneKR8kfR3892gyyVx0VhFgRaxsj4,44338
|
|
6
|
-
crackerjack/dynamic_config.py,sha256=
|
|
6
|
+
crackerjack/dynamic_config.py,sha256=85Kec1R3wthnLP0wd3LI3_gUI7-aV-mr-OLoUOCBnF4,21759
|
|
7
7
|
crackerjack/errors.py,sha256=yYbZ92kn_y6acEWgQvEPvozAYs2HT65uLwAXrtXxGsE,10049
|
|
8
8
|
crackerjack/interactive.py,sha256=t5FbxWeOErSl5kod4V8Gu5yF5yuWoZlwqlOdquOQ-vo,21943
|
|
9
|
+
crackerjack/py313.py,sha256=uLzXnII2N3Qng45lzb8-gMVe3z-U9dmT7V_BRV-zHJo,6192
|
|
9
10
|
crackerjack/adapters/__init__.py,sha256=k-8ajMDL9DS9hV2FYOu694nmNQg3HkudJRuNcXmx8N4,451
|
|
10
11
|
crackerjack/adapters/lsp_client.py,sha256=4kQ3T5JiWC7uc6kOjZuPdtUboseKSDjZpuKQpV74onc,10963
|
|
11
12
|
crackerjack/adapters/rust_tool_adapter.py,sha256=ui_qMt_WIwInRvRCeT7MnIdp8eln7Fvp4hakXQiVnjg,5999
|
|
@@ -69,7 +70,7 @@ crackerjack/documentation/mkdocs_integration.py,sha256=KqU2_9mA-rjP_VDrrfr6KTuPW
|
|
|
69
70
|
crackerjack/documentation/reference_generator.py,sha256=NGAIsC5bnjLBQkvEXPDU0pw8bQ5kYzbUUokhlXXFqrU,34520
|
|
70
71
|
crackerjack/executors/__init__.py,sha256=HF-DmXvKN45uKKDdiMxOT9bYxuy1B-Z91BihOhkK5lg,322
|
|
71
72
|
crackerjack/executors/async_hook_executor.py,sha256=FmKpiAxpZXKwvOWXnRQ73N-reDfX8NusESQ9a4HeacM,17620
|
|
72
|
-
crackerjack/executors/cached_hook_executor.py,sha256=
|
|
73
|
+
crackerjack/executors/cached_hook_executor.py,sha256=MwnHHBk6KJ_ovAJvAkVA-ad6D2cE0EgXNwy-NZQqB18,11172
|
|
73
74
|
crackerjack/executors/hook_executor.py,sha256=g53TXs5hOY0yRnSpyr44GgEmCRPMxHRgkfjtqBx_-4s,14479
|
|
74
75
|
crackerjack/executors/hook_lock_manager.py,sha256=ft24q6VFEkW_QrifNnSlrQeHGx9GuJeOOTsdlCcjnMI,26694
|
|
75
76
|
crackerjack/executors/individual_hook_executor.py,sha256=t0W9vuqLGPx0HmbTo01N9MRFyqLfY0ZLG06ZIA5qfBY,24362
|
|
@@ -142,7 +143,7 @@ crackerjack/monitoring/websocket_server.py,sha256=tmCYh5Qp58iicS_txj5OTdmt3I85M5
|
|
|
142
143
|
crackerjack/orchestration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
143
144
|
crackerjack/orchestration/advanced_orchestrator.py,sha256=05AZhCkPIiKSVVpIx7gb2_wVvGAKHv7gStu146ivcmY,32066
|
|
144
145
|
crackerjack/orchestration/coverage_improvement.py,sha256=XUTUcgub0nP3vvQ8Ud5SmCYKgulEe8SAY65jbcFQzdw,6869
|
|
145
|
-
crackerjack/orchestration/execution_strategies.py,sha256=
|
|
146
|
+
crackerjack/orchestration/execution_strategies.py,sha256=Iq5Q-dwC2GQ5E99kawqet031DnsrQCxSrqzTPnoWDbE,12476
|
|
146
147
|
crackerjack/orchestration/test_progress_streamer.py,sha256=Yu6uHuhoCvX6SZP0QNG3Yt8Q4s2tufEHr40o16QU98c,22541
|
|
147
148
|
crackerjack/plugins/__init__.py,sha256=B7hy9b9amJVbYLHgIz8kgTI29j-vYxsUY_sZ5ISbXU0,386
|
|
148
149
|
crackerjack/plugins/base.py,sha256=VFk-xNsgjSlmzJ_iPQALhkr7cguiOtEd3XSR9CcCPkc,5732
|
|
@@ -156,12 +157,12 @@ crackerjack/services/anomaly_detector.py,sha256=vUwhhGxNGarHQAly4GaN7kc5PBaBvlTf
|
|
|
156
157
|
crackerjack/services/api_extractor.py,sha256=iN4JDkvSyfHRNlhgV0Sf5B9cg4NVaCZn6p-zQlp9YGU,23836
|
|
157
158
|
crackerjack/services/backup_service.py,sha256=0e8AAo9svSBtbsbI9vwnAVSilB2fjph61lskgsUvDLk,15528
|
|
158
159
|
crackerjack/services/bounded_status_operations.py,sha256=mrBkUQwgtYjkbp-Y-5MdrU2A3rp3ZLVgOJv9vLdnJ8k,18763
|
|
159
|
-
crackerjack/services/cache.py,sha256=
|
|
160
|
+
crackerjack/services/cache.py,sha256=ZNpIHPoslMxgwfqzKJQQEqGUVlar22KGDQbydDuqx-M,14444
|
|
160
161
|
crackerjack/services/changelog_automation.py,sha256=KUeXCYLihRfLR0mUIRiI2aRQdCfe-45GnbB2gYNJJQE,14095
|
|
161
162
|
crackerjack/services/config.py,sha256=1gUQkcHPCGHVYSlx6mcrJlJLVIWhdaL7RjEmuy8_ev4,13704
|
|
162
163
|
crackerjack/services/config_integrity.py,sha256=Ac6-c7WuupsyrP2dxx_ijgjzpNnx9G0NWsXB-SZjelg,2904
|
|
163
164
|
crackerjack/services/config_merge.py,sha256=ubApDKbYMREaHARP3oaW9vY8iVeYuknsr6tJIiIz-_E,18999
|
|
164
|
-
crackerjack/services/config_template.py,sha256=
|
|
165
|
+
crackerjack/services/config_template.py,sha256=DssO4t_XZl3PCA4LV4TEQpRulZbfnx1ZKqcBB06vZlI,18047
|
|
165
166
|
crackerjack/services/contextual_ai_assistant.py,sha256=6Pnb2r824c4JYkP5mtCH8sJ2OPPvI-KtzbXcosspCfE,19962
|
|
166
167
|
crackerjack/services/coverage_badge_service.py,sha256=N6FDVd93zVzYLMzkjx4Hbk2dhA83ujLOH2AUE93PIsg,6673
|
|
167
168
|
crackerjack/services/coverage_ratchet.py,sha256=eKxmFyg-7Rnctnk--6P-yNNOFhoKwzTxd4iCJ52dtZE,13439
|
|
@@ -225,8 +226,8 @@ crackerjack/tools/validate_input_validator_patterns.py,sha256=NN7smYlXWrHLQXTb-8
|
|
|
225
226
|
crackerjack/tools/validate_regex_patterns.py,sha256=J7GG9EP1fASpRIsG8qRPeiCSkdCwmk0sdo29GgoJ6w8,5863
|
|
226
227
|
crackerjack/ui/__init__.py,sha256=eMb1OeTU-dSLICAACn0YdYB4Amdr8wHckjKfn0wOIZE,37
|
|
227
228
|
crackerjack/ui/server_panels.py,sha256=F5IH6SNN06BaZQMsFx_D-OA286aojmaFPJ5kvvSRv_c,4232
|
|
228
|
-
crackerjack-0.38.
|
|
229
|
-
crackerjack-0.38.
|
|
230
|
-
crackerjack-0.38.
|
|
231
|
-
crackerjack-0.38.
|
|
232
|
-
crackerjack-0.38.
|
|
229
|
+
crackerjack-0.38.14.dist-info/METADATA,sha256=R-lmCXd1FqckgsLk87Y6jO72lfBMy5EsalN-hUjCsF4,38079
|
|
230
|
+
crackerjack-0.38.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
231
|
+
crackerjack-0.38.14.dist-info/entry_points.txt,sha256=AJKNft0WXm9xoGUJ3Trl-iXHOWxRAYbagQiza3AILr4,57
|
|
232
|
+
crackerjack-0.38.14.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
|
|
233
|
+
crackerjack-0.38.14.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|