crackerjack 0.33.0__py3-none-any.whl → 0.33.2__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.

Files changed (198) hide show
  1. crackerjack/__main__.py +1350 -34
  2. crackerjack/adapters/__init__.py +17 -0
  3. crackerjack/adapters/lsp_client.py +358 -0
  4. crackerjack/adapters/rust_tool_adapter.py +194 -0
  5. crackerjack/adapters/rust_tool_manager.py +193 -0
  6. crackerjack/adapters/skylos_adapter.py +231 -0
  7. crackerjack/adapters/zuban_adapter.py +560 -0
  8. crackerjack/agents/base.py +7 -3
  9. crackerjack/agents/coordinator.py +271 -33
  10. crackerjack/agents/documentation_agent.py +9 -15
  11. crackerjack/agents/dry_agent.py +3 -15
  12. crackerjack/agents/formatting_agent.py +1 -1
  13. crackerjack/agents/import_optimization_agent.py +36 -180
  14. crackerjack/agents/performance_agent.py +17 -98
  15. crackerjack/agents/performance_helpers.py +7 -31
  16. crackerjack/agents/proactive_agent.py +1 -3
  17. crackerjack/agents/refactoring_agent.py +16 -85
  18. crackerjack/agents/refactoring_helpers.py +7 -42
  19. crackerjack/agents/security_agent.py +9 -48
  20. crackerjack/agents/test_creation_agent.py +356 -513
  21. crackerjack/agents/test_specialist_agent.py +0 -4
  22. crackerjack/api.py +6 -25
  23. crackerjack/cli/cache_handlers.py +204 -0
  24. crackerjack/cli/cache_handlers_enhanced.py +683 -0
  25. crackerjack/cli/facade.py +100 -0
  26. crackerjack/cli/handlers.py +224 -9
  27. crackerjack/cli/interactive.py +6 -4
  28. crackerjack/cli/options.py +642 -55
  29. crackerjack/cli/utils.py +2 -1
  30. crackerjack/code_cleaner.py +58 -117
  31. crackerjack/config/global_lock_config.py +8 -48
  32. crackerjack/config/hooks.py +53 -62
  33. crackerjack/core/async_workflow_orchestrator.py +24 -34
  34. crackerjack/core/autofix_coordinator.py +3 -17
  35. crackerjack/core/enhanced_container.py +4 -13
  36. crackerjack/core/file_lifecycle.py +12 -89
  37. crackerjack/core/performance.py +2 -2
  38. crackerjack/core/performance_monitor.py +15 -55
  39. crackerjack/core/phase_coordinator.py +104 -204
  40. crackerjack/core/resource_manager.py +14 -90
  41. crackerjack/core/service_watchdog.py +62 -95
  42. crackerjack/core/session_coordinator.py +149 -0
  43. crackerjack/core/timeout_manager.py +14 -72
  44. crackerjack/core/websocket_lifecycle.py +13 -78
  45. crackerjack/core/workflow_orchestrator.py +171 -174
  46. crackerjack/docs/INDEX.md +11 -0
  47. crackerjack/docs/generated/api/API_REFERENCE.md +10895 -0
  48. crackerjack/docs/generated/api/CLI_REFERENCE.md +109 -0
  49. crackerjack/docs/generated/api/CROSS_REFERENCES.md +1755 -0
  50. crackerjack/docs/generated/api/PROTOCOLS.md +3 -0
  51. crackerjack/docs/generated/api/SERVICES.md +1252 -0
  52. crackerjack/documentation/__init__.py +31 -0
  53. crackerjack/documentation/ai_templates.py +756 -0
  54. crackerjack/documentation/dual_output_generator.py +765 -0
  55. crackerjack/documentation/mkdocs_integration.py +518 -0
  56. crackerjack/documentation/reference_generator.py +977 -0
  57. crackerjack/dynamic_config.py +55 -50
  58. crackerjack/executors/async_hook_executor.py +10 -15
  59. crackerjack/executors/cached_hook_executor.py +117 -43
  60. crackerjack/executors/hook_executor.py +8 -34
  61. crackerjack/executors/hook_lock_manager.py +26 -183
  62. crackerjack/executors/individual_hook_executor.py +13 -11
  63. crackerjack/executors/lsp_aware_hook_executor.py +270 -0
  64. crackerjack/executors/tool_proxy.py +417 -0
  65. crackerjack/hooks/lsp_hook.py +79 -0
  66. crackerjack/intelligence/adaptive_learning.py +25 -10
  67. crackerjack/intelligence/agent_orchestrator.py +2 -5
  68. crackerjack/intelligence/agent_registry.py +34 -24
  69. crackerjack/intelligence/agent_selector.py +5 -7
  70. crackerjack/interactive.py +17 -6
  71. crackerjack/managers/async_hook_manager.py +0 -1
  72. crackerjack/managers/hook_manager.py +79 -1
  73. crackerjack/managers/publish_manager.py +44 -8
  74. crackerjack/managers/test_command_builder.py +1 -15
  75. crackerjack/managers/test_executor.py +1 -3
  76. crackerjack/managers/test_manager.py +98 -7
  77. crackerjack/managers/test_manager_backup.py +10 -9
  78. crackerjack/mcp/cache.py +2 -2
  79. crackerjack/mcp/client_runner.py +1 -1
  80. crackerjack/mcp/context.py +191 -68
  81. crackerjack/mcp/dashboard.py +7 -5
  82. crackerjack/mcp/enhanced_progress_monitor.py +31 -28
  83. crackerjack/mcp/file_monitor.py +30 -23
  84. crackerjack/mcp/progress_components.py +31 -21
  85. crackerjack/mcp/progress_monitor.py +50 -53
  86. crackerjack/mcp/rate_limiter.py +6 -6
  87. crackerjack/mcp/server_core.py +17 -16
  88. crackerjack/mcp/service_watchdog.py +2 -1
  89. crackerjack/mcp/state.py +4 -7
  90. crackerjack/mcp/task_manager.py +11 -9
  91. crackerjack/mcp/tools/core_tools.py +173 -32
  92. crackerjack/mcp/tools/error_analyzer.py +3 -2
  93. crackerjack/mcp/tools/execution_tools.py +8 -10
  94. crackerjack/mcp/tools/execution_tools_backup.py +42 -30
  95. crackerjack/mcp/tools/intelligence_tool_registry.py +7 -5
  96. crackerjack/mcp/tools/intelligence_tools.py +5 -2
  97. crackerjack/mcp/tools/monitoring_tools.py +33 -70
  98. crackerjack/mcp/tools/proactive_tools.py +24 -11
  99. crackerjack/mcp/tools/progress_tools.py +5 -8
  100. crackerjack/mcp/tools/utility_tools.py +20 -14
  101. crackerjack/mcp/tools/workflow_executor.py +62 -40
  102. crackerjack/mcp/websocket/app.py +8 -0
  103. crackerjack/mcp/websocket/endpoints.py +352 -357
  104. crackerjack/mcp/websocket/jobs.py +40 -57
  105. crackerjack/mcp/websocket/monitoring_endpoints.py +2935 -0
  106. crackerjack/mcp/websocket/server.py +7 -25
  107. crackerjack/mcp/websocket/websocket_handler.py +6 -17
  108. crackerjack/mixins/__init__.py +0 -2
  109. crackerjack/mixins/error_handling.py +1 -70
  110. crackerjack/models/config.py +12 -1
  111. crackerjack/models/config_adapter.py +49 -1
  112. crackerjack/models/protocols.py +122 -122
  113. crackerjack/models/resource_protocols.py +55 -210
  114. crackerjack/monitoring/ai_agent_watchdog.py +13 -13
  115. crackerjack/monitoring/metrics_collector.py +426 -0
  116. crackerjack/monitoring/regression_prevention.py +8 -8
  117. crackerjack/monitoring/websocket_server.py +643 -0
  118. crackerjack/orchestration/advanced_orchestrator.py +11 -6
  119. crackerjack/orchestration/coverage_improvement.py +3 -3
  120. crackerjack/orchestration/execution_strategies.py +26 -6
  121. crackerjack/orchestration/test_progress_streamer.py +8 -5
  122. crackerjack/plugins/base.py +2 -2
  123. crackerjack/plugins/hooks.py +7 -0
  124. crackerjack/plugins/managers.py +11 -8
  125. crackerjack/security/__init__.py +0 -1
  126. crackerjack/security/audit.py +6 -35
  127. crackerjack/services/anomaly_detector.py +392 -0
  128. crackerjack/services/api_extractor.py +615 -0
  129. crackerjack/services/backup_service.py +2 -2
  130. crackerjack/services/bounded_status_operations.py +15 -152
  131. crackerjack/services/cache.py +127 -1
  132. crackerjack/services/changelog_automation.py +395 -0
  133. crackerjack/services/config.py +15 -9
  134. crackerjack/services/config_merge.py +19 -80
  135. crackerjack/services/config_template.py +506 -0
  136. crackerjack/services/contextual_ai_assistant.py +48 -22
  137. crackerjack/services/coverage_badge_service.py +171 -0
  138. crackerjack/services/coverage_ratchet.py +27 -25
  139. crackerjack/services/debug.py +3 -3
  140. crackerjack/services/dependency_analyzer.py +460 -0
  141. crackerjack/services/dependency_monitor.py +14 -11
  142. crackerjack/services/documentation_generator.py +491 -0
  143. crackerjack/services/documentation_service.py +675 -0
  144. crackerjack/services/enhanced_filesystem.py +6 -5
  145. crackerjack/services/enterprise_optimizer.py +865 -0
  146. crackerjack/services/error_pattern_analyzer.py +676 -0
  147. crackerjack/services/file_hasher.py +1 -1
  148. crackerjack/services/git.py +8 -25
  149. crackerjack/services/health_metrics.py +10 -8
  150. crackerjack/services/heatmap_generator.py +735 -0
  151. crackerjack/services/initialization.py +11 -30
  152. crackerjack/services/input_validator.py +5 -97
  153. crackerjack/services/intelligent_commit.py +327 -0
  154. crackerjack/services/log_manager.py +15 -12
  155. crackerjack/services/logging.py +4 -3
  156. crackerjack/services/lsp_client.py +628 -0
  157. crackerjack/services/memory_optimizer.py +19 -87
  158. crackerjack/services/metrics.py +42 -33
  159. crackerjack/services/parallel_executor.py +9 -67
  160. crackerjack/services/pattern_cache.py +1 -1
  161. crackerjack/services/pattern_detector.py +6 -6
  162. crackerjack/services/performance_benchmarks.py +18 -59
  163. crackerjack/services/performance_cache.py +20 -81
  164. crackerjack/services/performance_monitor.py +27 -95
  165. crackerjack/services/predictive_analytics.py +510 -0
  166. crackerjack/services/quality_baseline.py +234 -0
  167. crackerjack/services/quality_baseline_enhanced.py +646 -0
  168. crackerjack/services/quality_intelligence.py +785 -0
  169. crackerjack/services/regex_patterns.py +618 -524
  170. crackerjack/services/regex_utils.py +43 -123
  171. crackerjack/services/secure_path_utils.py +5 -164
  172. crackerjack/services/secure_status_formatter.py +30 -141
  173. crackerjack/services/secure_subprocess.py +11 -92
  174. crackerjack/services/security.py +9 -41
  175. crackerjack/services/security_logger.py +12 -24
  176. crackerjack/services/server_manager.py +124 -16
  177. crackerjack/services/status_authentication.py +16 -159
  178. crackerjack/services/status_security_manager.py +4 -131
  179. crackerjack/services/thread_safe_status_collector.py +19 -125
  180. crackerjack/services/unified_config.py +21 -13
  181. crackerjack/services/validation_rate_limiter.py +5 -54
  182. crackerjack/services/version_analyzer.py +459 -0
  183. crackerjack/services/version_checker.py +1 -1
  184. crackerjack/services/websocket_resource_limiter.py +10 -144
  185. crackerjack/services/zuban_lsp_service.py +390 -0
  186. crackerjack/slash_commands/__init__.py +2 -7
  187. crackerjack/slash_commands/run.md +2 -2
  188. crackerjack/tools/validate_input_validator_patterns.py +14 -40
  189. crackerjack/tools/validate_regex_patterns.py +19 -48
  190. {crackerjack-0.33.0.dist-info → crackerjack-0.33.2.dist-info}/METADATA +196 -25
  191. crackerjack-0.33.2.dist-info/RECORD +229 -0
  192. crackerjack/CLAUDE.md +0 -207
  193. crackerjack/RULES.md +0 -380
  194. crackerjack/py313.py +0 -234
  195. crackerjack-0.33.0.dist-info/RECORD +0 -187
  196. {crackerjack-0.33.0.dist-info → crackerjack-0.33.2.dist-info}/WHEEL +0 -0
  197. {crackerjack-0.33.0.dist-info → crackerjack-0.33.2.dist-info}/entry_points.txt +0 -0
  198. {crackerjack-0.33.0.dist-info → crackerjack-0.33.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,234 @@
1
+ import subprocess
2
+ import typing as t
3
+ from dataclasses import asdict, dataclass
4
+ from datetime import datetime
5
+
6
+ from crackerjack.services.cache import CrackerjackCache
7
+
8
+
9
+ @dataclass
10
+ class QualityMetrics:
11
+ """Quality metrics for a specific commit/session."""
12
+
13
+ git_hash: str
14
+ timestamp: datetime
15
+ coverage_percent: float
16
+ test_count: int
17
+ test_pass_rate: float
18
+ hook_failures: int
19
+ complexity_violations: int
20
+ security_issues: int
21
+ type_errors: int
22
+ linting_issues: int
23
+ quality_score: int # Overall score 0-100
24
+
25
+ def to_dict(self) -> dict[str, t.Any]:
26
+ data = asdict(self)
27
+ data["timestamp"] = self.timestamp.isoformat()
28
+ return data
29
+
30
+ @classmethod
31
+ def from_dict(cls, data: dict[str, t.Any]) -> "QualityMetrics":
32
+ data = data.copy()
33
+ if isinstance(data["timestamp"], str):
34
+ data["timestamp"] = datetime.fromisoformat(data["timestamp"])
35
+ return cls(**data)
36
+
37
+
38
+ class QualityBaselineService:
39
+ """Service for tracking and persisting quality baselines across sessions."""
40
+
41
+ def __init__(self, cache: CrackerjackCache | None = None) -> None:
42
+ self.cache = cache or CrackerjackCache()
43
+
44
+ def get_current_git_hash(self) -> str | None:
45
+ """Get current git commit hash."""
46
+ try:
47
+ result = subprocess.run(
48
+ ["git", "rev-parse", "HEAD"],
49
+ capture_output=True,
50
+ text=True,
51
+ check=True,
52
+ )
53
+ return result.stdout.strip()
54
+ except (subprocess.CalledProcessError, FileNotFoundError):
55
+ return None
56
+
57
+ def calculate_quality_score(
58
+ self,
59
+ coverage_percent: float,
60
+ test_pass_rate: float,
61
+ hook_failures: int,
62
+ complexity_violations: int,
63
+ security_issues: int,
64
+ type_errors: int,
65
+ linting_issues: int,
66
+ ) -> int:
67
+ """Calculate overall quality score (0-100)."""
68
+ # Base score from coverage and tests
69
+ base_score = (coverage_percent * 0.4) + (test_pass_rate * 0.3)
70
+
71
+ # Penalty for issues (each issue type has different weight)
72
+ penalties = (
73
+ hook_failures * 2.0 # Hook failures are serious
74
+ + complexity_violations * 1.5 # Complexity is important
75
+ + security_issues * 3.0 # Security is critical
76
+ + type_errors * 2.0 # Type errors are serious
77
+ + linting_issues * 0.5 # Linting is less critical
78
+ )
79
+
80
+ # Apply penalties with diminishing returns
81
+ penalty_score = max(0, 30 - (penalties * 0.8))
82
+
83
+ return max(0, min(100, int(base_score + penalty_score)))
84
+
85
+ def record_baseline(
86
+ self,
87
+ coverage_percent: float,
88
+ test_count: int,
89
+ test_pass_rate: float,
90
+ hook_failures: int = 0,
91
+ complexity_violations: int = 0,
92
+ security_issues: int = 0,
93
+ type_errors: int = 0,
94
+ linting_issues: int = 0,
95
+ ) -> QualityMetrics | None:
96
+ """Record quality baseline for current commit."""
97
+ git_hash = self.get_current_git_hash()
98
+ if not git_hash:
99
+ return None
100
+
101
+ quality_score = self.calculate_quality_score(
102
+ coverage_percent=coverage_percent,
103
+ test_pass_rate=test_pass_rate,
104
+ hook_failures=hook_failures,
105
+ complexity_violations=complexity_violations,
106
+ security_issues=security_issues,
107
+ type_errors=type_errors,
108
+ linting_issues=linting_issues,
109
+ )
110
+
111
+ metrics = QualityMetrics(
112
+ git_hash=git_hash,
113
+ timestamp=datetime.now(),
114
+ coverage_percent=coverage_percent,
115
+ test_count=test_count,
116
+ test_pass_rate=test_pass_rate,
117
+ hook_failures=hook_failures,
118
+ complexity_violations=complexity_violations,
119
+ security_issues=security_issues,
120
+ type_errors=type_errors,
121
+ linting_issues=linting_issues,
122
+ quality_score=quality_score,
123
+ )
124
+
125
+ # Store in cache for persistence across sessions
126
+ self.cache.set_quality_baseline(git_hash, metrics.to_dict())
127
+ return metrics
128
+
129
+ def get_baseline(self, git_hash: str | None = None) -> QualityMetrics | None:
130
+ """Get quality baseline for specific commit (or current commit)."""
131
+ if not git_hash:
132
+ git_hash = self.get_current_git_hash()
133
+
134
+ if not git_hash:
135
+ return None
136
+
137
+ baseline_data = self.cache.get_quality_baseline(git_hash)
138
+ if baseline_data:
139
+ return QualityMetrics.from_dict(baseline_data)
140
+
141
+ return None
142
+
143
+ def compare_with_baseline(
144
+ self,
145
+ current_metrics: dict[str, t.Any],
146
+ baseline_git_hash: str | None = None,
147
+ ) -> dict[str, t.Any]:
148
+ """Compare current metrics with baseline."""
149
+ baseline = self.get_baseline(baseline_git_hash)
150
+ if not baseline:
151
+ return {
152
+ "comparison_available": False,
153
+ "message": "No baseline found for comparison",
154
+ }
155
+
156
+ current_score = self.calculate_quality_score(**current_metrics)
157
+
158
+ return {
159
+ "comparison_available": True,
160
+ "baseline_score": baseline.quality_score,
161
+ "current_score": current_score,
162
+ "score_change": current_score - baseline.quality_score,
163
+ "baseline_timestamp": baseline.timestamp.isoformat(),
164
+ "improvements": self._identify_improvements(baseline, current_metrics),
165
+ "regressions": self._identify_regressions(baseline, current_metrics),
166
+ }
167
+
168
+ def _identify_improvements(
169
+ self, baseline: QualityMetrics, current: dict[str, t.Any]
170
+ ) -> list[str]:
171
+ """Identify areas that improved since baseline."""
172
+ improvements = []
173
+
174
+ if current["coverage_percent"] > baseline.coverage_percent:
175
+ improvements.append(
176
+ f"Coverage increased by {current['coverage_percent'] - baseline.coverage_percent:.1f}%"
177
+ )
178
+
179
+ if current["test_pass_rate"] > baseline.test_pass_rate:
180
+ improvements.append(
181
+ f"Test pass rate improved by {current['test_pass_rate'] - baseline.test_pass_rate:.1f}%"
182
+ )
183
+
184
+ if current.get("hook_failures", 0) < baseline.hook_failures:
185
+ improvements.append(
186
+ f"Hook failures reduced by {baseline.hook_failures - current.get('hook_failures', 0)}"
187
+ )
188
+
189
+ return improvements
190
+
191
+ def _identify_regressions(
192
+ self, baseline: QualityMetrics, current: dict[str, t.Any]
193
+ ) -> list[str]:
194
+ """Identify areas that regressed since baseline."""
195
+ regressions = []
196
+
197
+ if current["coverage_percent"] < baseline.coverage_percent:
198
+ regressions.append(
199
+ f"Coverage decreased by {baseline.coverage_percent - current['coverage_percent']:.1f}%"
200
+ )
201
+
202
+ if current["test_pass_rate"] < baseline.test_pass_rate:
203
+ regressions.append(
204
+ f"Test pass rate decreased by {baseline.test_pass_rate - current['test_pass_rate']:.1f}%"
205
+ )
206
+
207
+ if current.get("security_issues", 0) > baseline.security_issues:
208
+ regressions.append(
209
+ f"Security issues increased by {current.get('security_issues', 0) - baseline.security_issues}"
210
+ )
211
+
212
+ return regressions
213
+
214
+ def get_recent_baselines(self, limit: int = 10) -> list[QualityMetrics]:
215
+ """Get recent baselines (requires git log parsing since cache is keyed by hash)."""
216
+ try:
217
+ result = subprocess.run(
218
+ ["git", "log", "--oneline", "-n", str(limit), "--format=%H"],
219
+ capture_output=True,
220
+ text=True,
221
+ check=True,
222
+ )
223
+ git_hashes = result.stdout.strip().split("\n")
224
+
225
+ baselines = []
226
+ for git_hash in git_hashes:
227
+ baseline = self.get_baseline(git_hash.strip())
228
+ if baseline:
229
+ baselines.append(baseline)
230
+
231
+ return sorted(baselines, key=lambda b: b.timestamp, reverse=True)
232
+
233
+ except (subprocess.CalledProcessError, FileNotFoundError):
234
+ return []