crackerjack 0.31.4__py3-none-any.whl → 0.31.8__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 +2 -0
- crackerjack/agents/base.py +1 -0
- crackerjack/agents/test_creation_agent.py +5 -0
- crackerjack/cli/options.py +8 -0
- crackerjack/core/phase_coordinator.py +25 -1
- crackerjack/core/workflow_orchestrator.py +264 -78
- crackerjack/dynamic_config.py +3 -3
- crackerjack/managers/publish_manager.py +22 -0
- crackerjack/managers/test_executor.py +13 -5
- crackerjack/managers/test_progress.py +31 -61
- crackerjack/mcp/context.py +6 -0
- crackerjack/mcp/tools/execution_tools.py +4 -2
- crackerjack/mcp/tools/progress_tools.py +95 -19
- crackerjack/mcp/tools/workflow_executor.py +224 -19
- crackerjack/orchestration/coverage_improvement.py +223 -0
- crackerjack/services/config.py +12 -1
- crackerjack/services/coverage_ratchet.py +9 -0
- crackerjack/services/filesystem.py +26 -0
- crackerjack/services/git.py +12 -1
- crackerjack/services/initialization.py +38 -12
- {crackerjack-0.31.4.dist-info → crackerjack-0.31.8.dist-info}/METADATA +1 -1
- {crackerjack-0.31.4.dist-info → crackerjack-0.31.8.dist-info}/RECORD +25 -24
- {crackerjack-0.31.4.dist-info → crackerjack-0.31.8.dist-info}/WHEEL +0 -0
- {crackerjack-0.31.4.dist-info → crackerjack-0.31.8.dist-info}/entry_points.txt +0 -0
- {crackerjack-0.31.4.dist-info → crackerjack-0.31.8.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"""Coverage improvement orchestration.
|
|
2
|
+
|
|
3
|
+
This module provides proactive test coverage improvement by analyzing coverage gaps
|
|
4
|
+
and triggering the TestCreationAgent to automatically generate missing tests.
|
|
5
|
+
Integrated into the AI agent workflow after successful test execution.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
import typing as t
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
from crackerjack.agents.base import Issue, IssueType, Priority
|
|
13
|
+
from crackerjack.agents.test_creation_agent import TestCreationAgent
|
|
14
|
+
from crackerjack.services.coverage_ratchet import CoverageRatchetService
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CoverageImprovementOrchestrator:
|
|
18
|
+
"""Orchestrates automatic test coverage improvement."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, project_path: Path, console: t.Any = None) -> None:
|
|
21
|
+
self.project_path = project_path
|
|
22
|
+
self.logger = logging.getLogger(__name__)
|
|
23
|
+
self.console = console
|
|
24
|
+
self.coverage_service = CoverageRatchetService(project_path, console)
|
|
25
|
+
self.min_coverage_improvement = 2.0 # Minimum 2% improvement target per run
|
|
26
|
+
|
|
27
|
+
async def should_improve_coverage(
|
|
28
|
+
self, current_coverage: float | None = None
|
|
29
|
+
) -> bool:
|
|
30
|
+
"""Determine if coverage improvement should be attempted.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
current_coverage: Current coverage percentage, will be detected if None
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
True if coverage improvement should be attempted
|
|
37
|
+
"""
|
|
38
|
+
try:
|
|
39
|
+
if current_coverage is None:
|
|
40
|
+
coverage_status = self.coverage_service.get_status_report()
|
|
41
|
+
current_coverage = coverage_status.get("current_coverage", 0.0)
|
|
42
|
+
|
|
43
|
+
# Always try to improve if coverage is below 100%
|
|
44
|
+
if current_coverage is not None and current_coverage < 100.0:
|
|
45
|
+
self.logger.info(
|
|
46
|
+
f"Coverage at {current_coverage:.1f}% - improvement recommended"
|
|
47
|
+
)
|
|
48
|
+
return True
|
|
49
|
+
|
|
50
|
+
self.logger.info("Coverage at 100% - no improvement needed")
|
|
51
|
+
return False
|
|
52
|
+
|
|
53
|
+
except Exception as e:
|
|
54
|
+
self.logger.warning(f"Could not determine coverage status: {e}")
|
|
55
|
+
# Default to trying improvement if we can't determine coverage
|
|
56
|
+
return True
|
|
57
|
+
|
|
58
|
+
async def create_coverage_improvement_issue(
|
|
59
|
+
self, coverage_gap: float | None = None
|
|
60
|
+
) -> Issue:
|
|
61
|
+
"""Create an issue for coverage improvement.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
coverage_gap: Percentage gap to 100% coverage
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
Issue configured for coverage improvement
|
|
68
|
+
"""
|
|
69
|
+
if coverage_gap is None:
|
|
70
|
+
try:
|
|
71
|
+
coverage_status = self.coverage_service.get_status_report()
|
|
72
|
+
current_coverage = coverage_status.get("current_coverage", 0.0)
|
|
73
|
+
coverage_gap = 100.0 - current_coverage
|
|
74
|
+
except Exception:
|
|
75
|
+
coverage_gap = 90.0 # Default gap if we can't determine
|
|
76
|
+
|
|
77
|
+
message = (
|
|
78
|
+
f"Proactive coverage improvement requested. "
|
|
79
|
+
f"Gap to 100%: {coverage_gap:.1f}%. "
|
|
80
|
+
f"Target improvement: {min(self.min_coverage_improvement, coverage_gap) if coverage_gap is not None else self.min_coverage_improvement:.1f}%"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
return Issue(
|
|
84
|
+
id="coverage_improvement_proactive",
|
|
85
|
+
type=IssueType.COVERAGE_IMPROVEMENT,
|
|
86
|
+
severity=Priority.MEDIUM,
|
|
87
|
+
message=message,
|
|
88
|
+
file_path=None, # Project-wide improvement
|
|
89
|
+
stage="coverage_improvement",
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
async def execute_coverage_improvement(
|
|
93
|
+
self, agent_context: t.Any
|
|
94
|
+
) -> dict[str, t.Any]:
|
|
95
|
+
"""Execute proactive coverage improvement.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
agent_context: AgentContext for the TestCreationAgent
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
Dictionary with improvement results
|
|
102
|
+
"""
|
|
103
|
+
try:
|
|
104
|
+
self.logger.info("Starting proactive coverage improvement")
|
|
105
|
+
|
|
106
|
+
# Check if improvement is needed
|
|
107
|
+
if not await self.should_improve_coverage():
|
|
108
|
+
return self._create_skipped_result("Coverage improvement not needed")
|
|
109
|
+
|
|
110
|
+
# Create coverage improvement issue and agent
|
|
111
|
+
issue = await self.create_coverage_improvement_issue()
|
|
112
|
+
test_agent = TestCreationAgent(agent_context)
|
|
113
|
+
|
|
114
|
+
# Validate agent confidence
|
|
115
|
+
confidence = await test_agent.can_handle(issue)
|
|
116
|
+
if confidence < 0.5:
|
|
117
|
+
return self._create_low_confidence_result(confidence)
|
|
118
|
+
|
|
119
|
+
# Execute the coverage improvement
|
|
120
|
+
fix_result = await test_agent.analyze_and_fix(issue)
|
|
121
|
+
result = self._create_completion_result(fix_result)
|
|
122
|
+
|
|
123
|
+
self._log_and_display_results(fix_result)
|
|
124
|
+
return result
|
|
125
|
+
|
|
126
|
+
except Exception as e:
|
|
127
|
+
return self._create_error_result(e)
|
|
128
|
+
|
|
129
|
+
def _create_skipped_result(self, reason: str) -> dict[str, t.Any]:
|
|
130
|
+
"""Create result dict for skipped coverage improvement."""
|
|
131
|
+
return {
|
|
132
|
+
"status": "skipped",
|
|
133
|
+
"reason": reason,
|
|
134
|
+
"coverage_at_100": True,
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
def _create_low_confidence_result(self, confidence: float) -> dict[str, t.Any]:
|
|
138
|
+
"""Create result dict for low confidence scenario."""
|
|
139
|
+
self.logger.warning(f"TestCreationAgent confidence too low: {confidence}")
|
|
140
|
+
return {
|
|
141
|
+
"status": "skipped",
|
|
142
|
+
"reason": "Agent confidence too low",
|
|
143
|
+
"confidence": confidence,
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
def _create_completion_result(self, fix_result: t.Any) -> dict[str, t.Any]:
|
|
147
|
+
"""Create result dict from fix results."""
|
|
148
|
+
return {
|
|
149
|
+
"status": "completed" if fix_result.success else "failed",
|
|
150
|
+
"confidence": fix_result.confidence,
|
|
151
|
+
"fixes_applied": fix_result.fixes_applied,
|
|
152
|
+
"files_modified": fix_result.files_modified,
|
|
153
|
+
"recommendations": fix_result.recommendations,
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
def _log_and_display_results(self, fix_result: t.Any) -> None:
|
|
157
|
+
"""Log and display the results of coverage improvement."""
|
|
158
|
+
if fix_result.success:
|
|
159
|
+
self.logger.info(
|
|
160
|
+
f"Coverage improvement successful: {len(fix_result.fixes_applied)} fixes applied"
|
|
161
|
+
)
|
|
162
|
+
if self.console:
|
|
163
|
+
self.console.print(
|
|
164
|
+
f"[green]📈[/green] Coverage improved: {len(fix_result.fixes_applied)} "
|
|
165
|
+
f"tests created in {len(fix_result.files_modified)} files"
|
|
166
|
+
)
|
|
167
|
+
else:
|
|
168
|
+
self.logger.warning("Coverage improvement failed")
|
|
169
|
+
if self.console:
|
|
170
|
+
self.console.print(
|
|
171
|
+
"[yellow]⚠️[/yellow] Coverage improvement attempt completed with issues"
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
def _create_error_result(self, error: Exception) -> dict[str, t.Any]:
|
|
175
|
+
"""Create result dict for error scenarios."""
|
|
176
|
+
self.logger.error(f"Coverage improvement failed with error: {error}")
|
|
177
|
+
return {
|
|
178
|
+
"status": "error",
|
|
179
|
+
"error": str(error),
|
|
180
|
+
"fixes_applied": [],
|
|
181
|
+
"files_modified": [],
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async def get_coverage_improvement_recommendations(self) -> list[str]:
|
|
185
|
+
"""Get recommendations for coverage improvement strategies.
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
List of strategic recommendations for improving coverage
|
|
189
|
+
"""
|
|
190
|
+
recommendations = [
|
|
191
|
+
"Focus on core business logic functions first",
|
|
192
|
+
"Add tests for error handling and edge cases",
|
|
193
|
+
"Consider property-based testing for complex algorithms",
|
|
194
|
+
"Test integration points and configuration handling",
|
|
195
|
+
"Add parametrized tests for different input scenarios",
|
|
196
|
+
]
|
|
197
|
+
|
|
198
|
+
from contextlib import suppress
|
|
199
|
+
|
|
200
|
+
with suppress(Exception):
|
|
201
|
+
# Add coverage-specific recommendations based on current state
|
|
202
|
+
coverage_status = self.coverage_service.get_status_report()
|
|
203
|
+
current_coverage = coverage_status.get("current_coverage", 0.0)
|
|
204
|
+
|
|
205
|
+
if current_coverage < 25.0:
|
|
206
|
+
recommendations.insert(
|
|
207
|
+
0, "Start with basic import and instantiation tests"
|
|
208
|
+
)
|
|
209
|
+
elif current_coverage < 50.0:
|
|
210
|
+
recommendations.insert(0, "Focus on testing public method interfaces")
|
|
211
|
+
elif current_coverage < 75.0:
|
|
212
|
+
recommendations.insert(0, "Add tests for internal helper methods")
|
|
213
|
+
else:
|
|
214
|
+
recommendations.insert(0, "Target remaining edge cases and error paths")
|
|
215
|
+
|
|
216
|
+
return recommendations
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
async def create_coverage_improvement_orchestrator(
|
|
220
|
+
project_path: Path, console: t.Any = None
|
|
221
|
+
) -> CoverageImprovementOrchestrator:
|
|
222
|
+
"""Create a coverage improvement orchestrator instance."""
|
|
223
|
+
return CoverageImprovementOrchestrator(project_path, console)
|
crackerjack/services/config.py
CHANGED
|
@@ -26,6 +26,12 @@ class ConfigurationService:
|
|
|
26
26
|
|
|
27
27
|
config_file = self.pkg_path / ".pre-commit-config.yaml"
|
|
28
28
|
config_content = config_temp_path.read_text()
|
|
29
|
+
# Clean trailing whitespace and ensure single trailing newline
|
|
30
|
+
from crackerjack.services.filesystem import FileSystemService
|
|
31
|
+
|
|
32
|
+
config_content = FileSystemService.clean_trailing_whitespace_and_newlines(
|
|
33
|
+
config_content
|
|
34
|
+
)
|
|
29
35
|
config_file.write_text(config_content)
|
|
30
36
|
|
|
31
37
|
self._temp_config_path = config_temp_path
|
|
@@ -206,8 +212,13 @@ class ConfigurationService:
|
|
|
206
212
|
],
|
|
207
213
|
},
|
|
208
214
|
}
|
|
215
|
+
# Clean the content before writing to prevent hook failures
|
|
216
|
+
from crackerjack.services.filesystem import FileSystemService
|
|
217
|
+
|
|
218
|
+
content = dumps(config)
|
|
219
|
+
content = FileSystemService.clean_trailing_whitespace_and_newlines(content)
|
|
209
220
|
with pyproject_file.open("w") as f:
|
|
210
|
-
f.write(
|
|
221
|
+
f.write(content)
|
|
211
222
|
self.console.print("[green]✅[/green] pyproject.toml configuration updated")
|
|
212
223
|
return True
|
|
213
224
|
except Exception as e:
|
|
@@ -189,6 +189,15 @@ class CoverageRatchetService:
|
|
|
189
189
|
updated_content = re.sub(pattern, replacement, content)
|
|
190
190
|
|
|
191
191
|
if updated_content != content:
|
|
192
|
+
# Clean trailing whitespace and ensure single trailing newline
|
|
193
|
+
from crackerjack.services.filesystem import FileSystemService
|
|
194
|
+
|
|
195
|
+
updated_content = (
|
|
196
|
+
FileSystemService.clean_trailing_whitespace_and_newlines(
|
|
197
|
+
updated_content
|
|
198
|
+
)
|
|
199
|
+
)
|
|
200
|
+
|
|
192
201
|
self.pyproject_file.write_text(updated_content)
|
|
193
202
|
self.console.print(
|
|
194
203
|
f"[cyan]📝[/cyan] Updated pyproject.toml coverage requirement to {new_coverage:.0f}%"
|
|
@@ -6,6 +6,27 @@ from crackerjack.errors import ErrorCode, FileError, ResourceError
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class FileSystemService:
|
|
9
|
+
@staticmethod
|
|
10
|
+
def clean_trailing_whitespace_and_newlines(content: str) -> str:
|
|
11
|
+
"""Clean trailing whitespace from all lines and ensure single trailing newline.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
content: File content to clean
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
Cleaned content with no trailing whitespace and single trailing newline
|
|
18
|
+
"""
|
|
19
|
+
# Remove trailing whitespace from each line
|
|
20
|
+
lines = content.splitlines()
|
|
21
|
+
cleaned_lines = [line.rstrip() for line in lines]
|
|
22
|
+
|
|
23
|
+
# Join lines and ensure exactly one trailing newline
|
|
24
|
+
result = "\n".join(cleaned_lines)
|
|
25
|
+
if result and not result.endswith("\n"):
|
|
26
|
+
result += "\n"
|
|
27
|
+
|
|
28
|
+
return result
|
|
29
|
+
|
|
9
30
|
def read_file(self, path: str | Path) -> str:
|
|
10
31
|
try:
|
|
11
32
|
path_obj = Path(path) if isinstance(path, str) else path
|
|
@@ -50,6 +71,11 @@ class FileSystemService:
|
|
|
50
71
|
details=str(e),
|
|
51
72
|
recovery="Check disk space and directory permissions",
|
|
52
73
|
) from e
|
|
74
|
+
|
|
75
|
+
# Auto-clean configuration files to prevent pre-commit hook failures
|
|
76
|
+
if path_obj.name in {".pre-commit-config.yaml", "pyproject.toml"}:
|
|
77
|
+
content = self.clean_trailing_whitespace_and_newlines(content)
|
|
78
|
+
|
|
53
79
|
path_obj.write_text(content, encoding="utf-8")
|
|
54
80
|
except PermissionError as e:
|
|
55
81
|
raise FileError(
|
crackerjack/services/git.py
CHANGED
|
@@ -83,7 +83,18 @@ class GitService:
|
|
|
83
83
|
if result.returncode == 0:
|
|
84
84
|
self.console.print(f"[green]✅[/green] Committed: {message}")
|
|
85
85
|
return True
|
|
86
|
-
|
|
86
|
+
|
|
87
|
+
# When git commit fails due to pre-commit hooks, stderr contains hook output
|
|
88
|
+
# Use a more appropriate error message for commit failures
|
|
89
|
+
if "pre-commit" in result.stderr or "hook" in result.stderr.lower():
|
|
90
|
+
self.console.print("[red]❌[/red] Commit blocked by pre-commit hooks")
|
|
91
|
+
if result.stderr.strip():
|
|
92
|
+
# Show hook output in a more readable way
|
|
93
|
+
self.console.print(
|
|
94
|
+
f"[yellow]Hook output:[/yellow]\n{result.stderr.strip()}"
|
|
95
|
+
)
|
|
96
|
+
else:
|
|
97
|
+
self.console.print(f"[red]❌[/red] Commit failed: {result.stderr}")
|
|
87
98
|
return False
|
|
88
99
|
except Exception as e:
|
|
89
100
|
self.console.print(f"[red]❌[/red] Error committing: {e}")
|
|
@@ -589,9 +589,21 @@ python -m crackerjack -a patch
|
|
|
589
589
|
# 3. Remove any fixed coverage requirements (use ratchet system instead)
|
|
590
590
|
self._remove_fixed_coverage_requirements(target_config)
|
|
591
591
|
|
|
592
|
-
# Write merged config
|
|
593
|
-
|
|
594
|
-
|
|
592
|
+
# Write merged config with proper formatting
|
|
593
|
+
import io
|
|
594
|
+
|
|
595
|
+
# Use in-memory buffer to clean content before writing
|
|
596
|
+
buffer = io.BytesIO()
|
|
597
|
+
tomli_w.dump(target_config, buffer)
|
|
598
|
+
content = buffer.getvalue().decode("utf-8")
|
|
599
|
+
|
|
600
|
+
# Clean trailing whitespace and ensure single trailing newline
|
|
601
|
+
from crackerjack.services.filesystem import FileSystemService
|
|
602
|
+
|
|
603
|
+
content = FileSystemService.clean_trailing_whitespace_and_newlines(content)
|
|
604
|
+
|
|
605
|
+
with target_file.open("w", encoding="utf-8") as f:
|
|
606
|
+
f.write(content)
|
|
595
607
|
|
|
596
608
|
t.cast("list[str]", results["files_copied"]).append("pyproject.toml (merged)")
|
|
597
609
|
|
|
@@ -776,8 +788,12 @@ python -m crackerjack -a patch
|
|
|
776
788
|
source_config = yaml.safe_load(f)
|
|
777
789
|
|
|
778
790
|
if not target_file.exists():
|
|
779
|
-
# No existing file, just copy
|
|
780
|
-
content = source_file.read_text()
|
|
791
|
+
# No existing file, just copy with proper formatting
|
|
792
|
+
content = source_file.read_text()
|
|
793
|
+
# Clean trailing whitespace and ensure single trailing newline
|
|
794
|
+
from crackerjack.services.filesystem import FileSystemService
|
|
795
|
+
|
|
796
|
+
content = FileSystemService.clean_trailing_whitespace_and_newlines(content)
|
|
781
797
|
self._write_file_and_track(
|
|
782
798
|
target_file,
|
|
783
799
|
content,
|
|
@@ -814,20 +830,30 @@ python -m crackerjack -a patch
|
|
|
814
830
|
target_repos.extend(new_repos)
|
|
815
831
|
target_config["repos"] = target_repos
|
|
816
832
|
|
|
817
|
-
# Write merged config
|
|
833
|
+
# Write merged config with proper formatting
|
|
818
834
|
yaml_content = yaml.dump(
|
|
819
835
|
target_config,
|
|
820
836
|
default_flow_style=False,
|
|
821
837
|
sort_keys=False,
|
|
822
838
|
width=float("inf"),
|
|
823
839
|
)
|
|
840
|
+
content = (
|
|
841
|
+
yaml_content.decode()
|
|
842
|
+
if isinstance(yaml_content, bytes)
|
|
843
|
+
else yaml_content
|
|
844
|
+
)
|
|
845
|
+
|
|
846
|
+
# Ensure content is not None before cleaning
|
|
847
|
+
if content is None:
|
|
848
|
+
content = ""
|
|
849
|
+
|
|
850
|
+
# Clean trailing whitespace and ensure single trailing newline
|
|
851
|
+
from crackerjack.services.filesystem import FileSystemService
|
|
852
|
+
|
|
853
|
+
content = FileSystemService.clean_trailing_whitespace_and_newlines(content)
|
|
854
|
+
|
|
824
855
|
with target_file.open("w") as f:
|
|
825
|
-
content
|
|
826
|
-
yaml_content.decode()
|
|
827
|
-
if isinstance(yaml_content, bytes)
|
|
828
|
-
else yaml_content
|
|
829
|
-
)
|
|
830
|
-
f.write(content.rstrip("\n"))
|
|
856
|
+
f.write(content)
|
|
831
857
|
|
|
832
858
|
t.cast("list[str]", results["files_copied"]).append(
|
|
833
859
|
".pre-commit-config.yaml (merged)",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: crackerjack
|
|
3
|
-
Version: 0.31.
|
|
3
|
+
Version: 0.31.8
|
|
4
4
|
Summary: Opinionated Python project management tool
|
|
5
5
|
Project-URL: documentation, https://github.com/lesleslie/crackerjack
|
|
6
6
|
Project-URL: homepage, https://github.com/lesleslie/crackerjack
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
crackerjack/CLAUDE.md,sha256=MbWyMBI57MVoyhJqww3Rb7ol1HfUDzne_sVdzwi8E20,40704
|
|
2
2
|
crackerjack/RULES.md,sha256=TdhFLM4db7tXORebYvyAohnEWNJnBR-qtA0aVfbvttY,15725
|
|
3
3
|
crackerjack/__init__.py,sha256=k8_Ev_3fWdjFtGNSJdSOvyaSLW54y3j484d3a8k_Ob4,1396
|
|
4
|
-
crackerjack/__main__.py,sha256=
|
|
4
|
+
crackerjack/__main__.py,sha256=66O5FzXWcjSopeEnHsQ48bX_aRvwzSMYEkhXNGC8o_A,7372
|
|
5
5
|
crackerjack/api.py,sha256=m4KaQt40uFTGYnj18ybQE4zTWZrjnpM0VvOfBN3cObo,18422
|
|
6
6
|
crackerjack/code_cleaner.py,sha256=XcW_sooKLVS31CIvjlfnoIbbK1GaS12A5uKI_8iAVJM,23576
|
|
7
|
-
crackerjack/dynamic_config.py,sha256=
|
|
7
|
+
crackerjack/dynamic_config.py,sha256=aKk876NODXGY4L7FwXlyLeznVQpYnWPikWblQ_y01fI,17461
|
|
8
8
|
crackerjack/errors.py,sha256=OTLutJqkTgMnOE2mItFHFumnh1fePHTZE__g-65JOwo,10096
|
|
9
9
|
crackerjack/interactive.py,sha256=BWMOHAFtv8AL1Ypjznpwr8BNcOrYVIgXKmh2KyjAVAw,21310
|
|
10
10
|
crackerjack/py313.py,sha256=i3Z6_JzHbMdmd4cH9ShqZ1CI5gCXivWtGIWJcJM3ZSI,6058
|
|
11
11
|
crackerjack/agents/__init__.py,sha256=pFXHd0hZkLTzxGGE9PB44HmLlWN8SLmVzE5GPLVjh0I,1030
|
|
12
12
|
crackerjack/agents/architect_agent.py,sha256=N6J7wjbd0eRPxy86IiSn--R-YnLf7pLA0JINiD3BWWA,10540
|
|
13
|
-
crackerjack/agents/base.py,sha256=
|
|
13
|
+
crackerjack/agents/base.py,sha256=dR_Da5f1_DtAQfeERu1iSgJnBmCZlRlCfR3DXyGw0yA,5120
|
|
14
14
|
crackerjack/agents/coordinator.py,sha256=jnKelnJGQDjSbjL2f6DyVB98FAm3c5FJF86MCX7Lpu0,18449
|
|
15
15
|
crackerjack/agents/documentation_agent.py,sha256=0V_vfpYL8L00GiMCApIbMcaUznHSGRQS8oAHBDRpP6Y,17412
|
|
16
16
|
crackerjack/agents/dry_agent.py,sha256=pzzQV5YS7NBox9YWdNIW6QxwLrrxKzpsr_w0e7Jzy18,13859
|
|
@@ -20,14 +20,14 @@ crackerjack/agents/performance_agent.py,sha256=bwBK9kmYYA-Pu0o5uks2Fyna8WXt2zrpR
|
|
|
20
20
|
crackerjack/agents/proactive_agent.py,sha256=0lPVrehnUu0ipasly0zx81BaihFQYd_a0-_U8JcHTJ8,3902
|
|
21
21
|
crackerjack/agents/refactoring_agent.py,sha256=15eL-p0o8RWu5n6hnqmBqKK9NIOfInVdQYguikpevaU,28939
|
|
22
22
|
crackerjack/agents/security_agent.py,sha256=_AJWx2a7l-HiJNKGpnTKfFC3Y8iwg2ljdnk78Abu6s8,18384
|
|
23
|
-
crackerjack/agents/test_creation_agent.py,sha256=
|
|
23
|
+
crackerjack/agents/test_creation_agent.py,sha256=XpNXgd0EqzT_UtiLYxpcAg4VL5jFonWCdo4msTX2ajE,22452
|
|
24
24
|
crackerjack/agents/test_specialist_agent.py,sha256=3QPwQQTRTc3KU7o3ya8xRsJW5Xg-YJ0q4C7ddGkgaeU,16276
|
|
25
25
|
crackerjack/agents/tracker.py,sha256=B4PuxdJ3g-K5i-Z1svvhx8KRhsZr4PtVOTL1SLfpeMg,7046
|
|
26
26
|
crackerjack/cli/__init__.py,sha256=6pnXZIglNzax4XA2lWfiqAZQs24Dr7GbXUwIwCF_9_w,583
|
|
27
27
|
crackerjack/cli/facade.py,sha256=2WoFl639mghopyTvRMVhtdgIZsWg3JdetRMgp6wYUBA,3904
|
|
28
28
|
crackerjack/cli/handlers.py,sha256=e6YigW9CgmzU5bvtRqrXMmlxRlHm2i4jSesOe9pLK7Q,9013
|
|
29
29
|
crackerjack/cli/interactive.py,sha256=KSLHce1EvzxFML7xBut1fpBqjLkG41HNoJKgLuzWgK0,16895
|
|
30
|
-
crackerjack/cli/options.py,sha256=
|
|
30
|
+
crackerjack/cli/options.py,sha256=qsHT629YmQBrU8ycBsYbAI1FqJGFcpheBrW53DBA8R8,12646
|
|
31
31
|
crackerjack/cli/utils.py,sha256=VHR-PALgA8fsKiPytH0cl8feXrtWKCajjk9TS2piK5w,537
|
|
32
32
|
crackerjack/config/__init__.py,sha256=b0481N2f_JvGufMPcbo5IXu2VjYd111r1BHw0oD3x7o,330
|
|
33
33
|
crackerjack/config/hooks.py,sha256=6DHJkWRL5c5Ip2bw0tevRt_xzRFKSfeO7tQkGtoZtjs,5367
|
|
@@ -37,10 +37,10 @@ crackerjack/core/autofix_coordinator.py,sha256=txbXTeGm-gJwuyRekVDbvvKgG0gQ1GqB3
|
|
|
37
37
|
crackerjack/core/container.py,sha256=e9_1YnWHijUJ0yl23lpgf9mennVQy8NkgJBKtZstG-M,2889
|
|
38
38
|
crackerjack/core/enhanced_container.py,sha256=fl5XvhNY0fzDnD5hSr16yQXGtL_AW01Wf4F4PL1L0P4,18169
|
|
39
39
|
crackerjack/core/performance.py,sha256=sL9g2-_JflofnsXW6LUCwp9MaUDQprfV8lSG18s9mns,7601
|
|
40
|
-
crackerjack/core/phase_coordinator.py,sha256=
|
|
40
|
+
crackerjack/core/phase_coordinator.py,sha256=iWPVB3A5CFfHwqc3wFXGEQwBhzaa-VlGsvhvRid5FKE,21236
|
|
41
41
|
crackerjack/core/proactive_workflow.py,sha256=ML1amNJI4Gx0dFJK5AKdvB0zNc1chbq-ZyqnhUi4tms,12677
|
|
42
42
|
crackerjack/core/session_coordinator.py,sha256=hJKLthZBzX7fXm8AmNMFLEjITNmKxDGqM58Om6p7fr0,9893
|
|
43
|
-
crackerjack/core/workflow_orchestrator.py,sha256=
|
|
43
|
+
crackerjack/core/workflow_orchestrator.py,sha256=eQl4y5ni0ajVuwtZf4z5cmsi10aTs-k7nVcEBgDHNEo,31412
|
|
44
44
|
crackerjack/executors/__init__.py,sha256=HF-DmXvKN45uKKDdiMxOT9bYxuy1B-Z91BihOhkK5lg,322
|
|
45
45
|
crackerjack/executors/async_hook_executor.py,sha256=3U-AHToGNBojnlDsXK6HLv4CfJvv64UqTmCWYAoLcb8,15958
|
|
46
46
|
crackerjack/executors/cached_hook_executor.py,sha256=LyrFINWbixB-0xEnaU0F2ZUBFUWrAdaTKvj_JW1Wss0,8186
|
|
@@ -55,16 +55,16 @@ crackerjack/intelligence/integration.py,sha256=AATxpzwfz3zfZHlnRvmyo4MnM8RM84Qfl
|
|
|
55
55
|
crackerjack/managers/__init__.py,sha256=PFWccXx4hDQA76T02idAViOLVD-aPeVpgjdfSkh_Dmk,298
|
|
56
56
|
crackerjack/managers/async_hook_manager.py,sha256=MysMwbCww-mImoDdhV0PzHxRKFw8N_YKp8S-Sbx4GLU,4638
|
|
57
57
|
crackerjack/managers/hook_manager.py,sha256=3qAKLYqoJGPJ8NAUB1KEoWHZafjs6564P9udzklW-rg,4704
|
|
58
|
-
crackerjack/managers/publish_manager.py,sha256=
|
|
58
|
+
crackerjack/managers/publish_manager.py,sha256=7bBXkaHm1Ou-tMLvUqNQZScp_onZ2SJgB0o3kwThUDE,16084
|
|
59
59
|
crackerjack/managers/test_command_builder.py,sha256=MdDz9AYSLOoLmI-8zoq3zd2SXF3DeuIkANa76h9cINI,5295
|
|
60
|
-
crackerjack/managers/test_executor.py,sha256=
|
|
60
|
+
crackerjack/managers/test_executor.py,sha256=XCMuJPssTV2Glb0hDPHvoDbVrJHVJpZrsAIltegMMfE,16337
|
|
61
61
|
crackerjack/managers/test_manager.py,sha256=BqCaMCUhXx_MJV8CmqXQ-54gZErfdCU5ejgvps4vXPo,9735
|
|
62
62
|
crackerjack/managers/test_manager_backup.py,sha256=tptpX99nw-caLJMVga4Hss7grJRqcFHz1JkRBqro4sE,41307
|
|
63
|
-
crackerjack/managers/test_progress.py,sha256=
|
|
63
|
+
crackerjack/managers/test_progress.py,sha256=gCNKdE7Bh7RS3K7Ekj2MGKCqiY4px54AzPNi0gMhAL0,3908
|
|
64
64
|
crackerjack/mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
65
65
|
crackerjack/mcp/cache.py,sha256=U_SFGnrTkHZFPkm1h93pYYGhkdZkjyCeocCMjWEev5Y,12057
|
|
66
66
|
crackerjack/mcp/client_runner.py,sha256=mLyOwsi8VwX7Zi4bxqjYzGSoM8JcKuN-Ex9SJqNa1m8,2973
|
|
67
|
-
crackerjack/mcp/context.py,sha256=
|
|
67
|
+
crackerjack/mcp/context.py,sha256=rnCfjAh3CN4taJaZ8EzvgHtH6h5o2JYHT4XjoYqnmA8,21440
|
|
68
68
|
crackerjack/mcp/dashboard.py,sha256=0pQoI_eInqSvMp24VwjsZ1yig-1FNjGE5K_1CFHn89k,19322
|
|
69
69
|
crackerjack/mcp/enhanced_progress_monitor.py,sha256=lZ1MF7B_Mc9Xe4oRDNNzhlBVuCG1eds1cD0NIC56-vc,16329
|
|
70
70
|
crackerjack/mcp/file_monitor.py,sha256=8n4EQfQawU2dyAU3C1GWw0PdGkdn-xsdOQUfom7DuQ0,11376
|
|
@@ -80,15 +80,15 @@ crackerjack/mcp/websocket_server.py,sha256=Dsw_orJOSeO7t7zRiVErh8GLp5jAaGab6shOe
|
|
|
80
80
|
crackerjack/mcp/tools/__init__.py,sha256=T_RMPXHQQWJLvSJjrPkJYtWi5tmyoRrzm0WS2G--iwU,613
|
|
81
81
|
crackerjack/mcp/tools/core_tools.py,sha256=SXkYo5knJYKZRVdXjgobTcOXllCsCVTkM7orRM5NcI4,8476
|
|
82
82
|
crackerjack/mcp/tools/error_analyzer.py,sha256=VwYdSL4OyYsbjbSTeZBmTLhjKu5Vm-CC7nCzX2lF620,9592
|
|
83
|
-
crackerjack/mcp/tools/execution_tools.py,sha256=
|
|
83
|
+
crackerjack/mcp/tools/execution_tools.py,sha256=_ZuGhUUzZrC8E8quju6o9xE4ImqXQbZLiN64_z_8tcs,11940
|
|
84
84
|
crackerjack/mcp/tools/execution_tools_backup.py,sha256=3kl2ACo8zwkof8I7OC4PMJez3kJYDGqZQp1lpa9XRqE,37392
|
|
85
85
|
crackerjack/mcp/tools/intelligence_tool_registry.py,sha256=4vSmxdJeBre5EOBu173SmRHPdYQyjazWSngKfsBp2ms,2501
|
|
86
86
|
crackerjack/mcp/tools/intelligence_tools.py,sha256=MteNXiCzEVA12-qJl0NMfIYmRG5nxQStTBugub03ths,10798
|
|
87
87
|
crackerjack/mcp/tools/monitoring_tools.py,sha256=tcMIc0-qj35QbQp-5fNM47tnyLmjieYekKmKxmnfxns,18542
|
|
88
88
|
crackerjack/mcp/tools/proactive_tools.py,sha256=0ax3clOEJ9yoHTTnvE3IFoutjoDZIpvFgIBowL6ANfU,14067
|
|
89
|
-
crackerjack/mcp/tools/progress_tools.py,sha256=
|
|
89
|
+
crackerjack/mcp/tools/progress_tools.py,sha256=l9MzVRUxO19FNpHn67zWbhyUeXyJOVxlnAQLJiVJBIg,6822
|
|
90
90
|
crackerjack/mcp/tools/utility_tools.py,sha256=MIv1CGR8vLeQEdKzR8xsNYj5A9TG_LXWp86drdKReXY,11849
|
|
91
|
-
crackerjack/mcp/tools/workflow_executor.py,sha256=
|
|
91
|
+
crackerjack/mcp/tools/workflow_executor.py,sha256=_bA8lNV5ywxPVmSM_PY4NzdTUY3FH9ddHnPkrrFqksU,17756
|
|
92
92
|
crackerjack/mcp/websocket/__init__.py,sha256=lZzyfvYjywHfqyy5X3wWR_jgBkRUxYSpgjdKALBzZcI,345
|
|
93
93
|
crackerjack/mcp/websocket/app.py,sha256=AXijAplfW-8NwWDrOON30Ol5qcMKdc64npTY2YEkX8s,1193
|
|
94
94
|
crackerjack/mcp/websocket/endpoints.py,sha256=L5zZzqhZtLFKF-Eh928jnwQIAIwunBSMrIaBoyaOaAE,20888
|
|
@@ -104,6 +104,7 @@ crackerjack/monitoring/ai_agent_watchdog.py,sha256=VkEoSufouyzfALUS0C9ttvu9bxKgy
|
|
|
104
104
|
crackerjack/monitoring/regression_prevention.py,sha256=f3midxG249E8pMYUulnllJR1i8mLG8aFkwbPSNzDe-Y,23771
|
|
105
105
|
crackerjack/orchestration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
106
106
|
crackerjack/orchestration/advanced_orchestrator.py,sha256=_a_uvKgDajA6WGvrtU8QJgMz3w-4IEae066E74YKD2Y,35868
|
|
107
|
+
crackerjack/orchestration/coverage_improvement.py,sha256=rc4eetbmziNDPwUTczkYH7Xim4vLFH_yobTFYazUfMU,8798
|
|
107
108
|
crackerjack/orchestration/execution_strategies.py,sha256=W5kV664X85C2T2NtbDFLZ8sNbOwgMup7GfDhoQ255Pw,11811
|
|
108
109
|
crackerjack/orchestration/test_progress_streamer.py,sha256=7xuavs_TMVfN8EP-BJo2tOfmh0aPsz8_wcb6pQ2WPU8,21726
|
|
109
110
|
crackerjack/plugins/__init__.py,sha256=B7hy9b9amJVbYLHgIz8kgTI29j-vYxsUY_sZ5ISbXU0,386
|
|
@@ -113,18 +114,18 @@ crackerjack/plugins/loader.py,sha256=9RmA5Lkizz5BADn-aJDGekISyL7C_O2Grr1tB6undHY
|
|
|
113
114
|
crackerjack/plugins/managers.py,sha256=UBILasJgJrs1cRS8WZUBs91EmoZiTDgLxkDEsX1YPAA,8585
|
|
114
115
|
crackerjack/services/__init__.py,sha256=thXyf5Yh6WRsnGjG3onf5Obe1xbd_p72Fm2tIl1IA3s,617
|
|
115
116
|
crackerjack/services/cache.py,sha256=LKZIa8xZ6SzwdTBttO1W6VEBxaTgMNI5Paz_IgrqoaI,9841
|
|
116
|
-
crackerjack/services/config.py,sha256=
|
|
117
|
+
crackerjack/services/config.py,sha256=BrIJoKKi0qyQg2lcZZhTTUpAVB6ej6gkbPv95o2rVvc,14050
|
|
117
118
|
crackerjack/services/config_integrity.py,sha256=wn6b0x90wXNRSj64J_kOQ5JMQvG_9FwtOno0ITVJGwM,3416
|
|
118
119
|
crackerjack/services/contextual_ai_assistant.py,sha256=QnJvJNdGimk-u6XxPm9D7F516AmbueNnAmky42D2caQ,19206
|
|
119
|
-
crackerjack/services/coverage_ratchet.py,sha256
|
|
120
|
+
crackerjack/services/coverage_ratchet.py,sha256=i12mOg5kB2iU3i4hn0LVLcVXJSPkBorO6Xu_nIiGrfs,13567
|
|
120
121
|
crackerjack/services/debug.py,sha256=crjsUZwVjP92aCEOEmtpEJwNf5gtlwNeZF_eB9JSfiI,24018
|
|
121
122
|
crackerjack/services/dependency_monitor.py,sha256=axBXFGBdezoPK9ph5_ZGxIwhSJhurgdvCSiuaCWSrKY,21085
|
|
122
123
|
crackerjack/services/enhanced_filesystem.py,sha256=MQj5zqvkNc5U6ZUmSVzgFQWKfnizD1lv4SJ2pt-w8W4,15424
|
|
123
124
|
crackerjack/services/file_hasher.py,sha256=vHSJ6QbWU5Q5JPLYuQkyRMRXCpDC_hsxToaM83vI58U,5201
|
|
124
|
-
crackerjack/services/filesystem.py,sha256=
|
|
125
|
-
crackerjack/services/git.py,sha256=
|
|
125
|
+
crackerjack/services/filesystem.py,sha256=Re5VyP7H8W6T2tpDakoaghEivdR2VmshJgnZ9Y3QkH8,17932
|
|
126
|
+
crackerjack/services/git.py,sha256=uR5uNnyW9mkOz_fRzJkhLQWErEV4ATtJLhIeX4MYMFE,7105
|
|
126
127
|
crackerjack/services/health_metrics.py,sha256=M2OBqwwnGvnJB3eXIXXh5SgMuckYCjHIrD0RkYFAbQU,21458
|
|
127
|
-
crackerjack/services/initialization.py,sha256=
|
|
128
|
+
crackerjack/services/initialization.py,sha256=iNXGn1OEVKfGNJAJXdqjcqGKvvXFKdaVfrDMnyTBAtw,31476
|
|
128
129
|
crackerjack/services/log_manager.py,sha256=deM_i97biZVyuZJoHaGlnBitc5QV4WaaZHEb70N5LV0,8388
|
|
129
130
|
crackerjack/services/logging.py,sha256=c15gVCLR_yRhqaza7f1pLLYL-xQ3Oi_OMWL_mR5G46k,5354
|
|
130
131
|
crackerjack/services/metrics.py,sha256=kInkb2G0ML8hAtmEG1jK04b-F1hT_fZjHvYJKisyr1Y,22894
|
|
@@ -141,8 +142,8 @@ crackerjack/slash_commands/__init__.py,sha256=ZHfKjluj9dX88zDYN6Saj7tGUMdMnh37Q8
|
|
|
141
142
|
crackerjack/slash_commands/init.md,sha256=mANRdCiFAzaTw29lKNrI1JFthK4pxVdtiFC5lN2SDSQ,4581
|
|
142
143
|
crackerjack/slash_commands/run.md,sha256=bf_mEtnXagUuw3w8os5h3t1Yi3vjpfiNbkMJvuFEu-Y,6500
|
|
143
144
|
crackerjack/slash_commands/status.md,sha256=U3qqppVLtIIm2lEiMYaKagaHYLI9UplL7OH1j6SRJGw,3921
|
|
144
|
-
crackerjack-0.31.
|
|
145
|
-
crackerjack-0.31.
|
|
146
|
-
crackerjack-0.31.
|
|
147
|
-
crackerjack-0.31.
|
|
148
|
-
crackerjack-0.31.
|
|
145
|
+
crackerjack-0.31.8.dist-info/METADATA,sha256=IoaiWGfqr7QWW5nPAVCq0taM0qHya4yh8UU4ptfHLso,22437
|
|
146
|
+
crackerjack-0.31.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
147
|
+
crackerjack-0.31.8.dist-info/entry_points.txt,sha256=AJKNft0WXm9xoGUJ3Trl-iXHOWxRAYbagQiza3AILr4,57
|
|
148
|
+
crackerjack-0.31.8.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
|
|
149
|
+
crackerjack-0.31.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|