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.

@@ -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)
@@ -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(dumps(config))
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(
@@ -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
- self.console.print(f"[red]❌[/red] Commit failed: {result.stderr}")
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
- with target_file.open("wb") as f:
594
- tomli_w.dump(target_config, f)
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 without trailing newline
780
- content = source_file.read_text().rstrip("\n")
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 without trailing newline
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.4
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=KxcNONKnvagCJ7pXAj-f4LQNANQBvYsj81siDwDg6lo,7290
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=EuhiLNUUsO6sv-1nTzSxUkL4FY3LIn2-wqRova7IRlI,17461
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=RT1dYSaNNoffr-a2rfqLmvR_4415GwAYUBDWCel19vE,5070
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=mhavBlQojP2iV15wOps0xLpyGWqUYCXUUY1WQJTkgUk,22256
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=75zoKNcxn9HUsXkWqeYvvzNvhETDH45inP6gLl3o-KQ,12339
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=bgVrcA2C0E2UD29wjYArlsN3lzupYUZ8DV4DhzOQgP8,20334
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=lTEgmmLMeigOjY2TzNRr1mF4Bgl6aup9wYIB-UaaNCE,24144
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=V0Rmc5azG8TsxPknr-1MB2JtemWv_HwIGffssf8kYOs,15216
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=Kduf_TNu12uYdyCGiMsRqdpgmVKVybCaNIMEqZoKXEE,16055
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=HqIqvKzguy8zj9XLyKtQwm9UVCfKukAZ8kL5Bb0CPr8,5037
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=WSkFqbEjrNWQEuLuApI_h82GjQkEJCZ_laAWYVuU24I,21255
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=AAv1iLumpIvGWdvtYnRKTlo5M0YZS7lVEWcpumk15rM,11875
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=e38tUa4Pqq_ZQrDKrQIag-WmaVqW7BkhH0x4IfcMeRI,4600
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=vusojdQSCa2TXGZ-Wb_pZKSPVsXtlFqqhgLS3Zmqn4s,10337
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=74S70yZ0KJNph4Mi9KOLukt0nVkp3HKzWp4F-n9Dr28,13503
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=-ybEb2y2uVFCBDd5dHh9GMmYSiyw2e8pt7ZEexgIef0,13214
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=jzoO9q1kCYhfULpdfKCX5wDCzHrrU_giw86fvhmz-Kw,16993
125
- crackerjack/services/git.py,sha256=5Gs_oLjjhVLhjZILYSmhfUAJNgrVW99A1ctGMM32ar4,6505
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=CMf7eZsUCldu-OfEc2exaz3JF7Hlkq2sOrNhY73gEIY,30467
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.4.dist-info/METADATA,sha256=mctlhYxn0KOpOy8P4PhaQWpX-svROOCyx35Z-beUqU0,22437
145
- crackerjack-0.31.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
146
- crackerjack-0.31.4.dist-info/entry_points.txt,sha256=AJKNft0WXm9xoGUJ3Trl-iXHOWxRAYbagQiza3AILr4,57
147
- crackerjack-0.31.4.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
148
- crackerjack-0.31.4.dist-info/RECORD,,
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,,