crackerjack 0.33.0__py3-none-any.whl → 0.33.1__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 +605 -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.1.dist-info}/METADATA +196 -25
  191. crackerjack-0.33.1.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.1.dist-info}/WHEEL +0 -0
  197. {crackerjack-0.33.0.dist-info → crackerjack-0.33.1.dist-info}/entry_points.txt +0 -0
  198. {crackerjack-0.33.0.dist-info → crackerjack-0.33.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,5 @@
1
1
  import subprocess
2
+ import typing as t
2
3
  from pathlib import Path
3
4
 
4
5
  from rich.console import Console
@@ -6,26 +7,23 @@ from rich.console import Console
6
7
  from .secure_subprocess import execute_secure_subprocess
7
8
  from .security_logger import get_security_logger
8
9
 
9
- # Centralized Git command registry for security validation
10
10
  GIT_COMMANDS = {
11
11
  "git_dir": ["rev-parse", "--git-dir"],
12
12
  "staged_files": ["diff", "--cached", "--name-only", "--diff-filter=ACMRT"],
13
13
  "unstaged_files": ["diff", "--name-only", "--diff-filter=ACMRT"],
14
14
  "untracked_files": ["ls-files", "--others", "--exclude-standard"],
15
15
  "staged_files_simple": ["diff", "--cached", "--name-only"],
16
- "add_file": ["add"], # File path will be appended
16
+ "add_file": ["add"],
17
17
  "add_all": ["add", "-A", "."],
18
- "commit": ["commit", "-m"], # Message will be appended
18
+ "commit": ["commit", "-m"],
19
19
  "add_updated": ["add", "-u"],
20
20
  "push_porcelain": ["push", "--porcelain"],
21
21
  "current_branch": ["branch", "--show-current"],
22
- "commits_ahead": ["rev-list", "--count", "@{u}..HEAD"],
22
+ "commits_ahead": ["rev-list[t.Any]", "--count", "@{u}..HEAD"],
23
23
  }
24
24
 
25
25
 
26
26
  class FailedGitResult:
27
- """A Git result object compatible with subprocess.CompletedProcess."""
28
-
29
27
  def __init__(self, command: list[str], error: str) -> None:
30
28
  self.args = command
31
29
  self.returncode = -1
@@ -41,7 +39,6 @@ class GitService:
41
39
  def _run_git_command(
42
40
  self, args: list[str]
43
41
  ) -> subprocess.CompletedProcess[str] | FailedGitResult:
44
- """Execute Git commands with secure subprocess validation."""
45
42
  cmd = ["git", *args]
46
43
 
47
44
  try:
@@ -51,10 +48,9 @@ class GitService:
51
48
  capture_output=True,
52
49
  text=True,
53
50
  timeout=60,
54
- check=False, # Don't raise on non-zero exit codes
51
+ check=False,
55
52
  )
56
53
  except Exception as e:
57
- # Log security issues but return a compatible result
58
54
  security_logger = get_security_logger()
59
55
  security_logger.log_subprocess_failure(
60
56
  command=cmd,
@@ -62,7 +58,6 @@ class GitService:
62
58
  error_output=str(e),
63
59
  )
64
60
 
65
- # Create compatible result for Git operations
66
61
  return FailedGitResult(cmd, str(e))
67
62
 
68
63
  def is_git_repo(self) -> bool:
@@ -95,7 +90,7 @@ class GitService:
95
90
  else []
96
91
  )
97
92
 
98
- all_files = set(staged_files + unstaged_files + untracked_files)
93
+ all_files = set[t.Any](staged_files + unstaged_files + untracked_files)
99
94
  return [f for f in all_files if f]
100
95
  except Exception as e:
101
96
  self.console.print(f"[yellow]⚠️[/ yellow] Error getting changed files: {e}")
@@ -125,7 +120,6 @@ class GitService:
125
120
  return False
126
121
 
127
122
  def add_all_files(self) -> bool:
128
- """Stage all changes including new, modified, and deleted files."""
129
123
  try:
130
124
  result = self._run_git_command(GIT_COMMANDS["add_all"])
131
125
  if result.returncode == 0:
@@ -200,7 +194,6 @@ class GitService:
200
194
 
201
195
  def push(self) -> bool:
202
196
  try:
203
- # Get detailed push information
204
197
  result = self._run_git_command(GIT_COMMANDS["push_porcelain"])
205
198
  if result.returncode == 0:
206
199
  self._display_push_success(result.stdout)
@@ -212,7 +205,6 @@ class GitService:
212
205
  return False
213
206
 
214
207
  def _display_push_success(self, push_output: str) -> None:
215
- """Display detailed push success information."""
216
208
  lines = push_output.strip().split("\n") if push_output.strip() else []
217
209
 
218
210
  if not lines:
@@ -223,15 +215,12 @@ class GitService:
223
215
  self._display_push_results(pushed_refs)
224
216
 
225
217
  def _display_no_commits_message(self) -> None:
226
- """Display message for no new commits."""
227
218
  self.console.print("[green]✅[/ green] Pushed to remote (no new commits)")
228
219
 
229
220
  def _parse_pushed_refs(self, lines: list[str]) -> list[str]:
230
- """Parse pushed references from git output."""
231
221
  pushed_refs = []
232
222
  for line in lines:
233
223
  if line.startswith(("*", "+", "=")):
234
- # Parse porcelain output: flag:from:to summary
235
224
  parts = line.split("\t")
236
225
  if len(parts) >= 2:
237
226
  summary = parts[1] if len(parts) > 1 else ""
@@ -239,21 +228,17 @@ class GitService:
239
228
  return pushed_refs
240
229
 
241
230
  def _display_push_results(self, pushed_refs: list[str]) -> None:
242
- """Display the push results to console."""
243
231
  if pushed_refs:
244
232
  self.console.print(
245
- f"[green]✅[/ green] Successfully pushed {len(pushed_refs)} ref(s) to remote:"
233
+ f"[green]✅[/ green] Successfully pushed {len(pushed_refs)} ref(s) to remote: "
246
234
  )
247
235
  for ref in pushed_refs:
248
- self.console.print(f" [dim]→ {ref}[/ dim]")
236
+ self.console.print(f" [dim]→ {ref}[/ dim]")
249
237
  else:
250
- # Get commit count as fallback
251
238
  self._display_commit_count_push()
252
239
 
253
240
  def _display_commit_count_push(self) -> None:
254
- """Fallback method to show commit count information."""
255
241
  try:
256
- # Get commits ahead of remote
257
242
  result = self._run_git_command(GIT_COMMANDS["commits_ahead"])
258
243
  if result.returncode == 0 and result.stdout.strip().isdigit():
259
244
  commit_count = int(result.stdout.strip())
@@ -266,7 +251,6 @@ class GitService:
266
251
  "[green]✅[/ green] Pushed to remote (up to date)"
267
252
  )
268
253
  else:
269
- # Even more basic fallback
270
254
  self.console.print("[green]✅[/ green] Successfully pushed to remote")
271
255
  except (ValueError, Exception):
272
256
  self.console.print("[green]✅[/ green] Successfully pushed to remote")
@@ -335,7 +319,6 @@ class GitService:
335
319
  return messages
336
320
 
337
321
  def get_unpushed_commit_count(self) -> int:
338
- """Get the number of unpushed commits."""
339
322
  from contextlib import suppress
340
323
 
341
324
  with suppress(ValueError, Exception):
@@ -9,6 +9,7 @@ from datetime import datetime
9
9
  from pathlib import Path
10
10
  from typing import Any
11
11
 
12
+ import requests
12
13
  from rich.console import Console
13
14
 
14
15
  from crackerjack.models.protocols import FileSystemInterface
@@ -18,7 +19,7 @@ from crackerjack.models.protocols import FileSystemInterface
18
19
  class ProjectHealth:
19
20
  lint_error_trend: list[int] = field(default_factory=list)
20
21
  test_coverage_trend: list[float] = field(default_factory=list)
21
- dependency_age: dict[str, int] = field(default_factory=dict)
22
+ dependency_age: dict[str, int] = field(default_factory=dict[str, t.Any])
22
23
  config_completeness: float = 0.0
23
24
  last_updated: float = field(default_factory=time.time)
24
25
 
@@ -344,14 +345,13 @@ class HealthMetricsService:
344
345
 
345
346
  def _fetch_package_data(self, package_name: str) -> dict[str, t.Any] | None:
346
347
  try:
347
- import urllib.request
348
348
  from urllib.parse import urlparse
349
349
 
350
- url = f"https://pypi.org/pypi/{package_name}/json"
350
+ url = f"https: //pypi.org/pypi/{package_name}/json"
351
351
 
352
352
  parsed = urlparse(url)
353
353
  if parsed.scheme != "https" or parsed.netloc != "pypi.org":
354
- msg = f"Invalid URL: only https://pypi.org URLs are allowed, got {url}"
354
+ msg = f"Invalid URL: only https: //pypi.org URLs are allowed, got {url}"
355
355
  raise ValueError(msg)
356
356
 
357
357
  if not parsed.path.startswith("/pypi/") or not parsed.path.endswith(
@@ -360,9 +360,10 @@ class HealthMetricsService:
360
360
  msg = f"Invalid PyPI API path: {parsed.path}"
361
361
  raise ValueError(msg)
362
362
 
363
- # B310: Safe urllib.urlopen with scheme validation above
364
- with urllib.request.urlopen(url, timeout=10) as response: # nosec B310
365
- return json.load(response)
363
+ response = requests.get(url, timeout=10, verify=True)
364
+ response.raise_for_status()
365
+ json_result = response.json()
366
+ return t.cast(dict[str, t.Any] | None, json_result)
366
367
  except Exception:
367
368
  return None
368
369
 
@@ -378,7 +379,8 @@ class HealthMetricsService:
378
379
  if not release_info:
379
380
  return None
380
381
 
381
- return release_info[0].get("upload_time", "")
382
+ upload_time_raw = release_info[0].get("upload_time", "")
383
+ return t.cast(str | None, upload_time_raw)
382
384
 
383
385
  def _calculate_days_since_upload(self, upload_time: str) -> int | None:
384
386
  try: