crackerjack 0.18.2__py3-none-any.whl → 0.45.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.
Files changed (533) hide show
  1. crackerjack/README.md +19 -0
  2. crackerjack/__init__.py +96 -2
  3. crackerjack/__main__.py +637 -138
  4. crackerjack/adapters/README.md +18 -0
  5. crackerjack/adapters/__init__.py +39 -0
  6. crackerjack/adapters/_output_paths.py +167 -0
  7. crackerjack/adapters/_qa_adapter_base.py +309 -0
  8. crackerjack/adapters/_tool_adapter_base.py +706 -0
  9. crackerjack/adapters/ai/README.md +65 -0
  10. crackerjack/adapters/ai/__init__.py +5 -0
  11. crackerjack/adapters/ai/claude.py +853 -0
  12. crackerjack/adapters/complexity/README.md +53 -0
  13. crackerjack/adapters/complexity/__init__.py +10 -0
  14. crackerjack/adapters/complexity/complexipy.py +641 -0
  15. crackerjack/adapters/dependency/__init__.py +22 -0
  16. crackerjack/adapters/dependency/pip_audit.py +418 -0
  17. crackerjack/adapters/format/README.md +72 -0
  18. crackerjack/adapters/format/__init__.py +11 -0
  19. crackerjack/adapters/format/mdformat.py +313 -0
  20. crackerjack/adapters/format/ruff.py +516 -0
  21. crackerjack/adapters/lint/README.md +47 -0
  22. crackerjack/adapters/lint/__init__.py +11 -0
  23. crackerjack/adapters/lint/codespell.py +273 -0
  24. crackerjack/adapters/lsp/README.md +49 -0
  25. crackerjack/adapters/lsp/__init__.py +27 -0
  26. crackerjack/adapters/lsp/_base.py +194 -0
  27. crackerjack/adapters/lsp/_client.py +358 -0
  28. crackerjack/adapters/lsp/_manager.py +193 -0
  29. crackerjack/adapters/lsp/skylos.py +283 -0
  30. crackerjack/adapters/lsp/zuban.py +557 -0
  31. crackerjack/adapters/refactor/README.md +59 -0
  32. crackerjack/adapters/refactor/__init__.py +12 -0
  33. crackerjack/adapters/refactor/creosote.py +318 -0
  34. crackerjack/adapters/refactor/refurb.py +406 -0
  35. crackerjack/adapters/refactor/skylos.py +494 -0
  36. crackerjack/adapters/sast/README.md +132 -0
  37. crackerjack/adapters/sast/__init__.py +32 -0
  38. crackerjack/adapters/sast/_base.py +201 -0
  39. crackerjack/adapters/sast/bandit.py +423 -0
  40. crackerjack/adapters/sast/pyscn.py +405 -0
  41. crackerjack/adapters/sast/semgrep.py +241 -0
  42. crackerjack/adapters/security/README.md +111 -0
  43. crackerjack/adapters/security/__init__.py +17 -0
  44. crackerjack/adapters/security/gitleaks.py +339 -0
  45. crackerjack/adapters/type/README.md +52 -0
  46. crackerjack/adapters/type/__init__.py +12 -0
  47. crackerjack/adapters/type/pyrefly.py +402 -0
  48. crackerjack/adapters/type/ty.py +402 -0
  49. crackerjack/adapters/type/zuban.py +522 -0
  50. crackerjack/adapters/utility/README.md +51 -0
  51. crackerjack/adapters/utility/__init__.py +10 -0
  52. crackerjack/adapters/utility/checks.py +884 -0
  53. crackerjack/agents/README.md +264 -0
  54. crackerjack/agents/__init__.py +66 -0
  55. crackerjack/agents/architect_agent.py +238 -0
  56. crackerjack/agents/base.py +167 -0
  57. crackerjack/agents/claude_code_bridge.py +641 -0
  58. crackerjack/agents/coordinator.py +600 -0
  59. crackerjack/agents/documentation_agent.py +520 -0
  60. crackerjack/agents/dry_agent.py +585 -0
  61. crackerjack/agents/enhanced_coordinator.py +279 -0
  62. crackerjack/agents/enhanced_proactive_agent.py +185 -0
  63. crackerjack/agents/error_middleware.py +53 -0
  64. crackerjack/agents/formatting_agent.py +230 -0
  65. crackerjack/agents/helpers/__init__.py +9 -0
  66. crackerjack/agents/helpers/performance/__init__.py +22 -0
  67. crackerjack/agents/helpers/performance/performance_ast_analyzer.py +357 -0
  68. crackerjack/agents/helpers/performance/performance_pattern_detector.py +909 -0
  69. crackerjack/agents/helpers/performance/performance_recommender.py +572 -0
  70. crackerjack/agents/helpers/refactoring/__init__.py +22 -0
  71. crackerjack/agents/helpers/refactoring/code_transformer.py +536 -0
  72. crackerjack/agents/helpers/refactoring/complexity_analyzer.py +344 -0
  73. crackerjack/agents/helpers/refactoring/dead_code_detector.py +437 -0
  74. crackerjack/agents/helpers/test_creation/__init__.py +19 -0
  75. crackerjack/agents/helpers/test_creation/test_ast_analyzer.py +216 -0
  76. crackerjack/agents/helpers/test_creation/test_coverage_analyzer.py +643 -0
  77. crackerjack/agents/helpers/test_creation/test_template_generator.py +1031 -0
  78. crackerjack/agents/import_optimization_agent.py +1181 -0
  79. crackerjack/agents/performance_agent.py +325 -0
  80. crackerjack/agents/performance_helpers.py +205 -0
  81. crackerjack/agents/proactive_agent.py +55 -0
  82. crackerjack/agents/refactoring_agent.py +511 -0
  83. crackerjack/agents/refactoring_helpers.py +247 -0
  84. crackerjack/agents/security_agent.py +793 -0
  85. crackerjack/agents/semantic_agent.py +479 -0
  86. crackerjack/agents/semantic_helpers.py +356 -0
  87. crackerjack/agents/test_creation_agent.py +570 -0
  88. crackerjack/agents/test_specialist_agent.py +526 -0
  89. crackerjack/agents/tracker.py +110 -0
  90. crackerjack/api.py +647 -0
  91. crackerjack/cli/README.md +394 -0
  92. crackerjack/cli/__init__.py +24 -0
  93. crackerjack/cli/cache_handlers.py +209 -0
  94. crackerjack/cli/cache_handlers_enhanced.py +680 -0
  95. crackerjack/cli/facade.py +162 -0
  96. crackerjack/cli/formatting.py +13 -0
  97. crackerjack/cli/handlers/__init__.py +85 -0
  98. crackerjack/cli/handlers/advanced.py +103 -0
  99. crackerjack/cli/handlers/ai_features.py +62 -0
  100. crackerjack/cli/handlers/analytics.py +479 -0
  101. crackerjack/cli/handlers/changelog.py +271 -0
  102. crackerjack/cli/handlers/config_handlers.py +16 -0
  103. crackerjack/cli/handlers/coverage.py +84 -0
  104. crackerjack/cli/handlers/documentation.py +280 -0
  105. crackerjack/cli/handlers/main_handlers.py +497 -0
  106. crackerjack/cli/handlers/monitoring.py +371 -0
  107. crackerjack/cli/handlers.py +700 -0
  108. crackerjack/cli/interactive.py +488 -0
  109. crackerjack/cli/options.py +1216 -0
  110. crackerjack/cli/semantic_handlers.py +292 -0
  111. crackerjack/cli/utils.py +19 -0
  112. crackerjack/cli/version.py +19 -0
  113. crackerjack/code_cleaner.py +1307 -0
  114. crackerjack/config/README.md +472 -0
  115. crackerjack/config/__init__.py +275 -0
  116. crackerjack/config/global_lock_config.py +207 -0
  117. crackerjack/config/hooks.py +390 -0
  118. crackerjack/config/loader.py +239 -0
  119. crackerjack/config/settings.py +141 -0
  120. crackerjack/config/tool_commands.py +331 -0
  121. crackerjack/core/README.md +393 -0
  122. crackerjack/core/__init__.py +0 -0
  123. crackerjack/core/async_workflow_orchestrator.py +738 -0
  124. crackerjack/core/autofix_coordinator.py +282 -0
  125. crackerjack/core/container.py +105 -0
  126. crackerjack/core/enhanced_container.py +583 -0
  127. crackerjack/core/file_lifecycle.py +472 -0
  128. crackerjack/core/performance.py +244 -0
  129. crackerjack/core/performance_monitor.py +357 -0
  130. crackerjack/core/phase_coordinator.py +1227 -0
  131. crackerjack/core/proactive_workflow.py +267 -0
  132. crackerjack/core/resource_manager.py +425 -0
  133. crackerjack/core/retry.py +275 -0
  134. crackerjack/core/service_watchdog.py +601 -0
  135. crackerjack/core/session_coordinator.py +239 -0
  136. crackerjack/core/timeout_manager.py +563 -0
  137. crackerjack/core/websocket_lifecycle.py +410 -0
  138. crackerjack/core/workflow/__init__.py +21 -0
  139. crackerjack/core/workflow/workflow_ai_coordinator.py +863 -0
  140. crackerjack/core/workflow/workflow_event_orchestrator.py +1107 -0
  141. crackerjack/core/workflow/workflow_issue_parser.py +714 -0
  142. crackerjack/core/workflow/workflow_phase_executor.py +1158 -0
  143. crackerjack/core/workflow/workflow_security_gates.py +400 -0
  144. crackerjack/core/workflow_orchestrator.py +2243 -0
  145. crackerjack/data/README.md +11 -0
  146. crackerjack/data/__init__.py +8 -0
  147. crackerjack/data/models.py +79 -0
  148. crackerjack/data/repository.py +210 -0
  149. crackerjack/decorators/README.md +180 -0
  150. crackerjack/decorators/__init__.py +35 -0
  151. crackerjack/decorators/error_handling.py +649 -0
  152. crackerjack/decorators/error_handling_decorators.py +334 -0
  153. crackerjack/decorators/helpers.py +58 -0
  154. crackerjack/decorators/patterns.py +281 -0
  155. crackerjack/decorators/utils.py +58 -0
  156. crackerjack/docs/INDEX.md +11 -0
  157. crackerjack/docs/README.md +11 -0
  158. crackerjack/docs/generated/api/API_REFERENCE.md +10895 -0
  159. crackerjack/docs/generated/api/CLI_REFERENCE.md +109 -0
  160. crackerjack/docs/generated/api/CROSS_REFERENCES.md +1755 -0
  161. crackerjack/docs/generated/api/PROTOCOLS.md +3 -0
  162. crackerjack/docs/generated/api/SERVICES.md +1252 -0
  163. crackerjack/documentation/README.md +11 -0
  164. crackerjack/documentation/__init__.py +31 -0
  165. crackerjack/documentation/ai_templates.py +756 -0
  166. crackerjack/documentation/dual_output_generator.py +767 -0
  167. crackerjack/documentation/mkdocs_integration.py +518 -0
  168. crackerjack/documentation/reference_generator.py +1065 -0
  169. crackerjack/dynamic_config.py +678 -0
  170. crackerjack/errors.py +378 -0
  171. crackerjack/events/README.md +11 -0
  172. crackerjack/events/__init__.py +16 -0
  173. crackerjack/events/telemetry.py +175 -0
  174. crackerjack/events/workflow_bus.py +346 -0
  175. crackerjack/exceptions/README.md +301 -0
  176. crackerjack/exceptions/__init__.py +5 -0
  177. crackerjack/exceptions/config.py +4 -0
  178. crackerjack/exceptions/tool_execution_error.py +245 -0
  179. crackerjack/executors/README.md +591 -0
  180. crackerjack/executors/__init__.py +13 -0
  181. crackerjack/executors/async_hook_executor.py +938 -0
  182. crackerjack/executors/cached_hook_executor.py +316 -0
  183. crackerjack/executors/hook_executor.py +1295 -0
  184. crackerjack/executors/hook_lock_manager.py +708 -0
  185. crackerjack/executors/individual_hook_executor.py +739 -0
  186. crackerjack/executors/lsp_aware_hook_executor.py +349 -0
  187. crackerjack/executors/progress_hook_executor.py +282 -0
  188. crackerjack/executors/tool_proxy.py +433 -0
  189. crackerjack/hooks/README.md +485 -0
  190. crackerjack/hooks/lsp_hook.py +93 -0
  191. crackerjack/intelligence/README.md +557 -0
  192. crackerjack/intelligence/__init__.py +37 -0
  193. crackerjack/intelligence/adaptive_learning.py +693 -0
  194. crackerjack/intelligence/agent_orchestrator.py +485 -0
  195. crackerjack/intelligence/agent_registry.py +377 -0
  196. crackerjack/intelligence/agent_selector.py +439 -0
  197. crackerjack/intelligence/integration.py +250 -0
  198. crackerjack/interactive.py +719 -0
  199. crackerjack/managers/README.md +369 -0
  200. crackerjack/managers/__init__.py +11 -0
  201. crackerjack/managers/async_hook_manager.py +135 -0
  202. crackerjack/managers/hook_manager.py +585 -0
  203. crackerjack/managers/publish_manager.py +631 -0
  204. crackerjack/managers/test_command_builder.py +391 -0
  205. crackerjack/managers/test_executor.py +474 -0
  206. crackerjack/managers/test_manager.py +1357 -0
  207. crackerjack/managers/test_progress.py +187 -0
  208. crackerjack/mcp/README.md +374 -0
  209. crackerjack/mcp/__init__.py +0 -0
  210. crackerjack/mcp/cache.py +352 -0
  211. crackerjack/mcp/client_runner.py +121 -0
  212. crackerjack/mcp/context.py +802 -0
  213. crackerjack/mcp/dashboard.py +657 -0
  214. crackerjack/mcp/enhanced_progress_monitor.py +493 -0
  215. crackerjack/mcp/file_monitor.py +394 -0
  216. crackerjack/mcp/progress_components.py +607 -0
  217. crackerjack/mcp/progress_monitor.py +1016 -0
  218. crackerjack/mcp/rate_limiter.py +336 -0
  219. crackerjack/mcp/server.py +24 -0
  220. crackerjack/mcp/server_core.py +526 -0
  221. crackerjack/mcp/service_watchdog.py +505 -0
  222. crackerjack/mcp/state.py +407 -0
  223. crackerjack/mcp/task_manager.py +259 -0
  224. crackerjack/mcp/tools/README.md +27 -0
  225. crackerjack/mcp/tools/__init__.py +19 -0
  226. crackerjack/mcp/tools/core_tools.py +469 -0
  227. crackerjack/mcp/tools/error_analyzer.py +283 -0
  228. crackerjack/mcp/tools/execution_tools.py +384 -0
  229. crackerjack/mcp/tools/intelligence_tool_registry.py +46 -0
  230. crackerjack/mcp/tools/intelligence_tools.py +264 -0
  231. crackerjack/mcp/tools/monitoring_tools.py +628 -0
  232. crackerjack/mcp/tools/proactive_tools.py +367 -0
  233. crackerjack/mcp/tools/progress_tools.py +222 -0
  234. crackerjack/mcp/tools/semantic_tools.py +584 -0
  235. crackerjack/mcp/tools/utility_tools.py +358 -0
  236. crackerjack/mcp/tools/workflow_executor.py +699 -0
  237. crackerjack/mcp/websocket/README.md +31 -0
  238. crackerjack/mcp/websocket/__init__.py +14 -0
  239. crackerjack/mcp/websocket/app.py +54 -0
  240. crackerjack/mcp/websocket/endpoints.py +492 -0
  241. crackerjack/mcp/websocket/event_bridge.py +188 -0
  242. crackerjack/mcp/websocket/jobs.py +406 -0
  243. crackerjack/mcp/websocket/monitoring/__init__.py +25 -0
  244. crackerjack/mcp/websocket/monitoring/api/__init__.py +19 -0
  245. crackerjack/mcp/websocket/monitoring/api/dependencies.py +141 -0
  246. crackerjack/mcp/websocket/monitoring/api/heatmap.py +154 -0
  247. crackerjack/mcp/websocket/monitoring/api/intelligence.py +199 -0
  248. crackerjack/mcp/websocket/monitoring/api/metrics.py +203 -0
  249. crackerjack/mcp/websocket/monitoring/api/telemetry.py +101 -0
  250. crackerjack/mcp/websocket/monitoring/dashboard.py +18 -0
  251. crackerjack/mcp/websocket/monitoring/factory.py +109 -0
  252. crackerjack/mcp/websocket/monitoring/filters.py +10 -0
  253. crackerjack/mcp/websocket/monitoring/metrics.py +64 -0
  254. crackerjack/mcp/websocket/monitoring/models.py +90 -0
  255. crackerjack/mcp/websocket/monitoring/utils.py +171 -0
  256. crackerjack/mcp/websocket/monitoring/websocket_manager.py +78 -0
  257. crackerjack/mcp/websocket/monitoring/websockets/__init__.py +17 -0
  258. crackerjack/mcp/websocket/monitoring/websockets/dependencies.py +126 -0
  259. crackerjack/mcp/websocket/monitoring/websockets/heatmap.py +176 -0
  260. crackerjack/mcp/websocket/monitoring/websockets/intelligence.py +291 -0
  261. crackerjack/mcp/websocket/monitoring/websockets/metrics.py +291 -0
  262. crackerjack/mcp/websocket/monitoring_endpoints.py +21 -0
  263. crackerjack/mcp/websocket/server.py +174 -0
  264. crackerjack/mcp/websocket/websocket_handler.py +276 -0
  265. crackerjack/mcp/websocket_server.py +10 -0
  266. crackerjack/models/README.md +308 -0
  267. crackerjack/models/__init__.py +40 -0
  268. crackerjack/models/config.py +730 -0
  269. crackerjack/models/config_adapter.py +265 -0
  270. crackerjack/models/protocols.py +1535 -0
  271. crackerjack/models/pydantic_models.py +320 -0
  272. crackerjack/models/qa_config.py +145 -0
  273. crackerjack/models/qa_results.py +134 -0
  274. crackerjack/models/resource_protocols.py +299 -0
  275. crackerjack/models/results.py +35 -0
  276. crackerjack/models/semantic_models.py +258 -0
  277. crackerjack/models/task.py +173 -0
  278. crackerjack/models/test_models.py +60 -0
  279. crackerjack/monitoring/README.md +11 -0
  280. crackerjack/monitoring/__init__.py +0 -0
  281. crackerjack/monitoring/ai_agent_watchdog.py +405 -0
  282. crackerjack/monitoring/metrics_collector.py +427 -0
  283. crackerjack/monitoring/regression_prevention.py +580 -0
  284. crackerjack/monitoring/websocket_server.py +406 -0
  285. crackerjack/orchestration/README.md +340 -0
  286. crackerjack/orchestration/__init__.py +43 -0
  287. crackerjack/orchestration/advanced_orchestrator.py +894 -0
  288. crackerjack/orchestration/cache/README.md +312 -0
  289. crackerjack/orchestration/cache/__init__.py +37 -0
  290. crackerjack/orchestration/cache/memory_cache.py +338 -0
  291. crackerjack/orchestration/cache/tool_proxy_cache.py +340 -0
  292. crackerjack/orchestration/config.py +297 -0
  293. crackerjack/orchestration/coverage_improvement.py +180 -0
  294. crackerjack/orchestration/execution_strategies.py +361 -0
  295. crackerjack/orchestration/hook_orchestrator.py +1398 -0
  296. crackerjack/orchestration/strategies/README.md +401 -0
  297. crackerjack/orchestration/strategies/__init__.py +39 -0
  298. crackerjack/orchestration/strategies/adaptive_strategy.py +630 -0
  299. crackerjack/orchestration/strategies/parallel_strategy.py +237 -0
  300. crackerjack/orchestration/strategies/sequential_strategy.py +299 -0
  301. crackerjack/orchestration/test_progress_streamer.py +647 -0
  302. crackerjack/plugins/README.md +11 -0
  303. crackerjack/plugins/__init__.py +15 -0
  304. crackerjack/plugins/base.py +200 -0
  305. crackerjack/plugins/hooks.py +254 -0
  306. crackerjack/plugins/loader.py +335 -0
  307. crackerjack/plugins/managers.py +264 -0
  308. crackerjack/py313.py +191 -0
  309. crackerjack/security/README.md +11 -0
  310. crackerjack/security/__init__.py +0 -0
  311. crackerjack/security/audit.py +197 -0
  312. crackerjack/services/README.md +374 -0
  313. crackerjack/services/__init__.py +9 -0
  314. crackerjack/services/ai/README.md +295 -0
  315. crackerjack/services/ai/__init__.py +7 -0
  316. crackerjack/services/ai/advanced_optimizer.py +878 -0
  317. crackerjack/services/ai/contextual_ai_assistant.py +542 -0
  318. crackerjack/services/ai/embeddings.py +444 -0
  319. crackerjack/services/ai/intelligent_commit.py +328 -0
  320. crackerjack/services/ai/predictive_analytics.py +510 -0
  321. crackerjack/services/anomaly_detector.py +392 -0
  322. crackerjack/services/api_extractor.py +617 -0
  323. crackerjack/services/backup_service.py +467 -0
  324. crackerjack/services/bounded_status_operations.py +530 -0
  325. crackerjack/services/cache.py +369 -0
  326. crackerjack/services/changelog_automation.py +399 -0
  327. crackerjack/services/command_execution_service.py +305 -0
  328. crackerjack/services/config_integrity.py +132 -0
  329. crackerjack/services/config_merge.py +546 -0
  330. crackerjack/services/config_service.py +198 -0
  331. crackerjack/services/config_template.py +493 -0
  332. crackerjack/services/coverage_badge_service.py +173 -0
  333. crackerjack/services/coverage_ratchet.py +381 -0
  334. crackerjack/services/debug.py +733 -0
  335. crackerjack/services/dependency_analyzer.py +460 -0
  336. crackerjack/services/dependency_monitor.py +622 -0
  337. crackerjack/services/documentation_generator.py +493 -0
  338. crackerjack/services/documentation_service.py +704 -0
  339. crackerjack/services/enhanced_filesystem.py +497 -0
  340. crackerjack/services/enterprise_optimizer.py +865 -0
  341. crackerjack/services/error_pattern_analyzer.py +676 -0
  342. crackerjack/services/file_filter.py +221 -0
  343. crackerjack/services/file_hasher.py +149 -0
  344. crackerjack/services/file_io_service.py +361 -0
  345. crackerjack/services/file_modifier.py +615 -0
  346. crackerjack/services/filesystem.py +381 -0
  347. crackerjack/services/git.py +422 -0
  348. crackerjack/services/health_metrics.py +615 -0
  349. crackerjack/services/heatmap_generator.py +744 -0
  350. crackerjack/services/incremental_executor.py +380 -0
  351. crackerjack/services/initialization.py +823 -0
  352. crackerjack/services/input_validator.py +668 -0
  353. crackerjack/services/intelligent_commit.py +327 -0
  354. crackerjack/services/log_manager.py +289 -0
  355. crackerjack/services/logging.py +228 -0
  356. crackerjack/services/lsp_client.py +628 -0
  357. crackerjack/services/memory_optimizer.py +414 -0
  358. crackerjack/services/metrics.py +587 -0
  359. crackerjack/services/monitoring/README.md +30 -0
  360. crackerjack/services/monitoring/__init__.py +9 -0
  361. crackerjack/services/monitoring/dependency_monitor.py +678 -0
  362. crackerjack/services/monitoring/error_pattern_analyzer.py +676 -0
  363. crackerjack/services/monitoring/health_metrics.py +716 -0
  364. crackerjack/services/monitoring/metrics.py +587 -0
  365. crackerjack/services/monitoring/performance_benchmarks.py +410 -0
  366. crackerjack/services/monitoring/performance_cache.py +388 -0
  367. crackerjack/services/monitoring/performance_monitor.py +569 -0
  368. crackerjack/services/parallel_executor.py +527 -0
  369. crackerjack/services/pattern_cache.py +333 -0
  370. crackerjack/services/pattern_detector.py +478 -0
  371. crackerjack/services/patterns/__init__.py +142 -0
  372. crackerjack/services/patterns/agents.py +107 -0
  373. crackerjack/services/patterns/code/__init__.py +15 -0
  374. crackerjack/services/patterns/code/detection.py +118 -0
  375. crackerjack/services/patterns/code/imports.py +107 -0
  376. crackerjack/services/patterns/code/paths.py +159 -0
  377. crackerjack/services/patterns/code/performance.py +119 -0
  378. crackerjack/services/patterns/code/replacement.py +36 -0
  379. crackerjack/services/patterns/core.py +212 -0
  380. crackerjack/services/patterns/documentation/__init__.py +14 -0
  381. crackerjack/services/patterns/documentation/badges_markdown.py +96 -0
  382. crackerjack/services/patterns/documentation/comments_blocks.py +83 -0
  383. crackerjack/services/patterns/documentation/docstrings.py +89 -0
  384. crackerjack/services/patterns/formatting.py +226 -0
  385. crackerjack/services/patterns/operations.py +339 -0
  386. crackerjack/services/patterns/security/__init__.py +23 -0
  387. crackerjack/services/patterns/security/code_injection.py +122 -0
  388. crackerjack/services/patterns/security/credentials.py +190 -0
  389. crackerjack/services/patterns/security/path_traversal.py +221 -0
  390. crackerjack/services/patterns/security/unsafe_operations.py +216 -0
  391. crackerjack/services/patterns/templates.py +62 -0
  392. crackerjack/services/patterns/testing/__init__.py +18 -0
  393. crackerjack/services/patterns/testing/error_patterns.py +107 -0
  394. crackerjack/services/patterns/testing/pytest_output.py +126 -0
  395. crackerjack/services/patterns/tool_output/__init__.py +16 -0
  396. crackerjack/services/patterns/tool_output/bandit.py +72 -0
  397. crackerjack/services/patterns/tool_output/other.py +97 -0
  398. crackerjack/services/patterns/tool_output/pyright.py +67 -0
  399. crackerjack/services/patterns/tool_output/ruff.py +44 -0
  400. crackerjack/services/patterns/url_sanitization.py +114 -0
  401. crackerjack/services/patterns/utilities.py +42 -0
  402. crackerjack/services/patterns/utils.py +339 -0
  403. crackerjack/services/patterns/validation.py +46 -0
  404. crackerjack/services/patterns/versioning.py +62 -0
  405. crackerjack/services/predictive_analytics.py +523 -0
  406. crackerjack/services/profiler.py +280 -0
  407. crackerjack/services/quality/README.md +415 -0
  408. crackerjack/services/quality/__init__.py +11 -0
  409. crackerjack/services/quality/anomaly_detector.py +392 -0
  410. crackerjack/services/quality/pattern_cache.py +333 -0
  411. crackerjack/services/quality/pattern_detector.py +479 -0
  412. crackerjack/services/quality/qa_orchestrator.py +491 -0
  413. crackerjack/services/quality/quality_baseline.py +395 -0
  414. crackerjack/services/quality/quality_baseline_enhanced.py +649 -0
  415. crackerjack/services/quality/quality_intelligence.py +949 -0
  416. crackerjack/services/regex_patterns.py +58 -0
  417. crackerjack/services/regex_utils.py +483 -0
  418. crackerjack/services/secure_path_utils.py +524 -0
  419. crackerjack/services/secure_status_formatter.py +450 -0
  420. crackerjack/services/secure_subprocess.py +635 -0
  421. crackerjack/services/security.py +239 -0
  422. crackerjack/services/security_logger.py +495 -0
  423. crackerjack/services/server_manager.py +411 -0
  424. crackerjack/services/smart_scheduling.py +167 -0
  425. crackerjack/services/status_authentication.py +460 -0
  426. crackerjack/services/status_security_manager.py +315 -0
  427. crackerjack/services/terminal_utils.py +0 -0
  428. crackerjack/services/thread_safe_status_collector.py +441 -0
  429. crackerjack/services/tool_filter.py +368 -0
  430. crackerjack/services/tool_version_service.py +43 -0
  431. crackerjack/services/unified_config.py +115 -0
  432. crackerjack/services/validation_rate_limiter.py +220 -0
  433. crackerjack/services/vector_store.py +689 -0
  434. crackerjack/services/version_analyzer.py +461 -0
  435. crackerjack/services/version_checker.py +223 -0
  436. crackerjack/services/websocket_resource_limiter.py +438 -0
  437. crackerjack/services/zuban_lsp_service.py +391 -0
  438. crackerjack/slash_commands/README.md +11 -0
  439. crackerjack/slash_commands/__init__.py +59 -0
  440. crackerjack/slash_commands/init.md +112 -0
  441. crackerjack/slash_commands/run.md +197 -0
  442. crackerjack/slash_commands/status.md +127 -0
  443. crackerjack/tools/README.md +11 -0
  444. crackerjack/tools/__init__.py +30 -0
  445. crackerjack/tools/_git_utils.py +105 -0
  446. crackerjack/tools/check_added_large_files.py +139 -0
  447. crackerjack/tools/check_ast.py +105 -0
  448. crackerjack/tools/check_json.py +103 -0
  449. crackerjack/tools/check_jsonschema.py +297 -0
  450. crackerjack/tools/check_toml.py +103 -0
  451. crackerjack/tools/check_yaml.py +110 -0
  452. crackerjack/tools/codespell_wrapper.py +72 -0
  453. crackerjack/tools/end_of_file_fixer.py +202 -0
  454. crackerjack/tools/format_json.py +128 -0
  455. crackerjack/tools/mdformat_wrapper.py +114 -0
  456. crackerjack/tools/trailing_whitespace.py +198 -0
  457. crackerjack/tools/validate_input_validator_patterns.py +236 -0
  458. crackerjack/tools/validate_regex_patterns.py +188 -0
  459. crackerjack/ui/README.md +11 -0
  460. crackerjack/ui/__init__.py +1 -0
  461. crackerjack/ui/dashboard_renderer.py +28 -0
  462. crackerjack/ui/templates/README.md +11 -0
  463. crackerjack/utils/console_utils.py +13 -0
  464. crackerjack/utils/dependency_guard.py +230 -0
  465. crackerjack/utils/retry_utils.py +275 -0
  466. crackerjack/workflows/README.md +590 -0
  467. crackerjack/workflows/__init__.py +46 -0
  468. crackerjack/workflows/actions.py +811 -0
  469. crackerjack/workflows/auto_fix.py +444 -0
  470. crackerjack/workflows/container_builder.py +499 -0
  471. crackerjack/workflows/definitions.py +443 -0
  472. crackerjack/workflows/engine.py +177 -0
  473. crackerjack/workflows/event_bridge.py +242 -0
  474. crackerjack-0.45.2.dist-info/METADATA +1678 -0
  475. crackerjack-0.45.2.dist-info/RECORD +478 -0
  476. {crackerjack-0.18.2.dist-info → crackerjack-0.45.2.dist-info}/WHEEL +1 -1
  477. crackerjack-0.45.2.dist-info/entry_points.txt +2 -0
  478. crackerjack/.gitignore +0 -14
  479. crackerjack/.libcst.codemod.yaml +0 -18
  480. crackerjack/.pdm.toml +0 -1
  481. crackerjack/.pre-commit-config.yaml +0 -91
  482. crackerjack/.pytest_cache/.gitignore +0 -2
  483. crackerjack/.pytest_cache/CACHEDIR.TAG +0 -4
  484. crackerjack/.pytest_cache/README.md +0 -8
  485. crackerjack/.pytest_cache/v/cache/nodeids +0 -1
  486. crackerjack/.pytest_cache/v/cache/stepwise +0 -1
  487. crackerjack/.ruff_cache/.gitignore +0 -1
  488. crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
  489. crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
  490. crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
  491. crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
  492. crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
  493. crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
  494. crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
  495. crackerjack/.ruff_cache/0.11.3/9818742842212983150 +0 -0
  496. crackerjack/.ruff_cache/0.11.4/9818742842212983150 +0 -0
  497. crackerjack/.ruff_cache/0.11.6/3557596832929915217 +0 -0
  498. crackerjack/.ruff_cache/0.11.7/10386934055395314831 +0 -0
  499. crackerjack/.ruff_cache/0.11.7/3557596832929915217 +0 -0
  500. crackerjack/.ruff_cache/0.11.8/530407680854991027 +0 -0
  501. crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
  502. crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
  503. crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
  504. crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
  505. crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
  506. crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
  507. crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
  508. crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
  509. crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
  510. crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
  511. crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
  512. crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
  513. crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
  514. crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
  515. crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
  516. crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
  517. crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
  518. crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
  519. crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
  520. crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
  521. crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
  522. crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
  523. crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
  524. crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
  525. crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
  526. crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
  527. crackerjack/.ruff_cache/CACHEDIR.TAG +0 -1
  528. crackerjack/crackerjack.py +0 -855
  529. crackerjack/pyproject.toml +0 -214
  530. crackerjack-0.18.2.dist-info/METADATA +0 -420
  531. crackerjack-0.18.2.dist-info/RECORD +0 -59
  532. crackerjack-0.18.2.dist-info/entry_points.txt +0 -4
  533. {crackerjack-0.18.2.dist-info → crackerjack-0.45.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,570 @@
1
+ from pathlib import Path
2
+ from typing import Any
3
+
4
+ from .base import (
5
+ AgentContext,
6
+ FixResult,
7
+ Issue,
8
+ IssueType,
9
+ SubAgent,
10
+ agent_registry,
11
+ )
12
+ from .helpers.test_creation.test_ast_analyzer import TestASTAnalyzer
13
+ from .helpers.test_creation.test_coverage_analyzer import TestCoverageAnalyzer
14
+ from .helpers.test_creation.test_template_generator import TestTemplateGenerator
15
+
16
+
17
+ class TestCreationAgent(SubAgent):
18
+ def __init__(self, context: AgentContext) -> None:
19
+ super().__init__(context)
20
+ self._ast_analyzer = TestASTAnalyzer(context)
21
+ self._template_generator = TestTemplateGenerator(context)
22
+ self._coverage_analyzer = TestCoverageAnalyzer(context)
23
+
24
+ def get_supported_types(self) -> set[IssueType]:
25
+ return {
26
+ IssueType.TEST_FAILURE,
27
+ IssueType.DEPENDENCY,
28
+ IssueType.TEST_ORGANIZATION,
29
+ IssueType.COVERAGE_IMPROVEMENT,
30
+ }
31
+
32
+ async def can_handle(self, issue: Issue) -> float:
33
+ if issue.type not in self.get_supported_types():
34
+ return 0.0
35
+
36
+ message_lower = issue.message.lower()
37
+
38
+ if issue.type == IssueType.COVERAGE_IMPROVEMENT:
39
+ if any(
40
+ term in message_lower
41
+ for term in (
42
+ "coverage below",
43
+ "missing tests",
44
+ "untested functions",
45
+ "no tests found",
46
+ "coverage requirement",
47
+ )
48
+ ):
49
+ return 0.95
50
+ return 0.9
51
+
52
+ if issue.type == IssueType.TEST_ORGANIZATION:
53
+ return self._check_test_organization_confidence(message_lower)
54
+
55
+ perfect_score = self._check_perfect_test_creation_matches(message_lower)
56
+ if perfect_score > 0:
57
+ return perfect_score
58
+
59
+ good_score = self._check_good_test_creation_matches(message_lower)
60
+ if good_score > 0:
61
+ return good_score
62
+
63
+ file_path_score = self._check_file_path_test_indicators(issue.file_path)
64
+ if file_path_score > 0:
65
+ return file_path_score
66
+
67
+ if self._indicates_untested_functions(message_lower):
68
+ return 0.85
69
+
70
+ return 0.0
71
+
72
+ def _check_test_organization_confidence(self, message_lower: str) -> float:
73
+ organization_keywords = [
74
+ "redundant tests",
75
+ "duplicate tests",
76
+ "overlapping tests",
77
+ "consolidate tests",
78
+ "test suite optimization",
79
+ "obsolete tests",
80
+ "broken tests",
81
+ "coverage booster",
82
+ "victory test",
83
+ "test cleanup",
84
+ ]
85
+ return (
86
+ 0.9
87
+ if any(keyword in message_lower for keyword in organization_keywords)
88
+ else 0.7
89
+ )
90
+
91
+ def _check_perfect_test_creation_matches(self, message_lower: str) -> float:
92
+ perfect_keywords = [
93
+ "coverage below",
94
+ "missing tests",
95
+ "untested",
96
+ "no tests found",
97
+ "test coverage",
98
+ "coverage requirement",
99
+ "coverage gap",
100
+ ]
101
+ return (
102
+ 1.0
103
+ if any(keyword in message_lower for keyword in perfect_keywords)
104
+ else 0.0
105
+ )
106
+
107
+ def _check_good_test_creation_matches(self, message_lower: str) -> float:
108
+ good_keywords = [
109
+ "coverage",
110
+ "test",
111
+ "missing",
112
+ "untested code",
113
+ "no test",
114
+ "empty test",
115
+ "test missing",
116
+ ]
117
+ return (
118
+ 0.8 if any(keyword in message_lower for keyword in good_keywords) else 0.0
119
+ )
120
+
121
+ def _check_file_path_test_indicators(self, file_path: str | None) -> float:
122
+ if not file_path:
123
+ return 0.0
124
+
125
+ if not self._has_corresponding_test(file_path):
126
+ if any(
127
+ core_path in file_path
128
+ for core_path in ("/managers/", "/services/", "/core/", "/agents/")
129
+ ):
130
+ return 0.8
131
+ return 0.7
132
+ return 0.0
133
+
134
+ def _indicates_untested_functions(self, message_lower: str) -> bool:
135
+ return any(
136
+ indicator in message_lower
137
+ for indicator in (
138
+ "function not tested",
139
+ "untested method",
140
+ "no test for function",
141
+ "function coverage",
142
+ "method coverage",
143
+ "untested code path",
144
+ )
145
+ )
146
+
147
+ async def analyze_and_fix(self, issue: Issue) -> FixResult:
148
+ self._log_analysis(issue)
149
+
150
+ return await self._apply_fixes_and_create_result(issue)
151
+
152
+ def _log_analysis(self, issue: Issue) -> None:
153
+ self.log(f"Analyzing test creation need: {issue.message}")
154
+
155
+ async def _apply_fixes_and_create_result(self, issue: Issue) -> FixResult:
156
+ try:
157
+ fixes_applied, files_modified = await self._apply_test_creation_fixes(issue)
158
+ return self._create_test_creation_result(fixes_applied, files_modified)
159
+
160
+ except Exception as e:
161
+ self.log(f"Error creating tests: {e}", "ERROR")
162
+ return self._create_error_result(e)
163
+
164
+ async def _apply_test_creation_fixes(
165
+ self,
166
+ issue: Issue,
167
+ ) -> tuple[list[str], list[str]]:
168
+ return await self._apply_all_test_creation_fixes(issue)
169
+
170
+ async def _apply_all_test_creation_fixes(
171
+ self,
172
+ issue: Issue,
173
+ ) -> tuple[list[str], list[str]]:
174
+ fixes_applied: list[str] = []
175
+ files_modified: list[str] = []
176
+
177
+ fixes_applied, files_modified = await self._apply_all_fix_types(
178
+ issue, fixes_applied, files_modified
179
+ )
180
+
181
+ return fixes_applied, files_modified
182
+
183
+ async def _apply_all_fix_types(
184
+ self,
185
+ issue: Issue,
186
+ fixes_applied: list[str],
187
+ files_modified: list[str],
188
+ ) -> tuple[list[str], list[str]]:
189
+ return await self._apply_sequential_fixes(issue, fixes_applied, files_modified)
190
+
191
+ async def _apply_sequential_fixes(
192
+ self,
193
+ issue: Issue,
194
+ fixes_applied: list[str],
195
+ files_modified: list[str],
196
+ ) -> tuple[list[str], list[str]]:
197
+ return await self._apply_all_fix_types_sequentially(
198
+ issue, fixes_applied, files_modified
199
+ )
200
+
201
+ async def _apply_all_fix_types_sequentially(
202
+ self,
203
+ issue: Issue,
204
+ fixes_applied: list[str],
205
+ files_modified: list[str],
206
+ ) -> tuple[list[str], list[str]]:
207
+ return await self._apply_all_fix_types_in_sequence(
208
+ issue, fixes_applied, files_modified
209
+ )
210
+
211
+ async def _apply_all_fix_types_in_sequence(
212
+ self,
213
+ issue: Issue,
214
+ fixes_applied: list[str],
215
+ files_modified: list[str],
216
+ ) -> tuple[list[str], list[str]]:
217
+ return await self._apply_fix_types_in_defined_order(
218
+ issue, fixes_applied, files_modified
219
+ )
220
+
221
+ async def _apply_fix_types_in_defined_order(
222
+ self,
223
+ issue: Issue,
224
+ fixes_applied: list[str],
225
+ files_modified: list[str],
226
+ ) -> tuple[list[str], list[str]]:
227
+ (
228
+ fixes_applied,
229
+ files_modified,
230
+ ) = await self._apply_coverage_based_fixes_sequentially(
231
+ fixes_applied, files_modified
232
+ )
233
+
234
+ (
235
+ fixes_applied,
236
+ files_modified,
237
+ ) = await self._apply_file_specific_fixes_sequentially(
238
+ issue, fixes_applied, files_modified
239
+ )
240
+
241
+ (
242
+ fixes_applied,
243
+ files_modified,
244
+ ) = await self._apply_function_specific_fixes_sequentially(
245
+ fixes_applied, files_modified
246
+ )
247
+
248
+ return fixes_applied, files_modified
249
+
250
+ async def _apply_coverage_based_fixes_sequentially(
251
+ self,
252
+ fixes_applied: list[str],
253
+ files_modified: list[str],
254
+ ) -> tuple[list[str], list[str]]:
255
+ coverage_fixes, coverage_files = await self._apply_coverage_based_fixes()
256
+ fixes_applied.extend(coverage_fixes)
257
+ files_modified.extend(coverage_files)
258
+ return fixes_applied, files_modified
259
+
260
+ async def _apply_file_specific_fixes_sequentially(
261
+ self,
262
+ issue: Issue,
263
+ fixes_applied: list[str],
264
+ files_modified: list[str],
265
+ ) -> tuple[list[str], list[str]]:
266
+ file_fixes, file_modified = await self._apply_file_specific_fixes(
267
+ issue.file_path,
268
+ )
269
+ fixes_applied.extend(file_fixes)
270
+ files_modified.extend(file_modified)
271
+ return fixes_applied, files_modified
272
+
273
+ async def _apply_function_specific_fixes_sequentially(
274
+ self,
275
+ fixes_applied: list[str],
276
+ files_modified: list[str],
277
+ ) -> tuple[list[str], list[str]]:
278
+ function_fixes, function_files = await self._apply_function_specific_fixes()
279
+ fixes_applied.extend(function_fixes)
280
+ files_modified.extend(function_files)
281
+ return fixes_applied, files_modified
282
+
283
+ async def _apply_coverage_fixes(
284
+ self,
285
+ fixes_applied: list[str],
286
+ files_modified: list[str],
287
+ ) -> tuple[list[str], list[str]]:
288
+ coverage_fixes, coverage_files = await self._apply_coverage_based_fixes()
289
+ fixes_applied.extend(coverage_fixes)
290
+ files_modified.extend(coverage_files)
291
+ return fixes_applied, files_modified
292
+
293
+ async def _apply_file_fixes(
294
+ self,
295
+ issue: Issue,
296
+ fixes_applied: list[str],
297
+ files_modified: list[str],
298
+ ) -> tuple[list[str], list[str]]:
299
+ file_fixes, file_modified = await self._apply_file_specific_fixes(
300
+ issue.file_path,
301
+ )
302
+ fixes_applied.extend(file_fixes)
303
+ files_modified.extend(file_modified)
304
+ return fixes_applied, files_modified
305
+
306
+ async def _apply_function_fixes(
307
+ self,
308
+ fixes_applied: list[str],
309
+ files_modified: list[str],
310
+ ) -> tuple[list[str], list[str]]:
311
+ function_fixes, function_files = await self._apply_function_specific_fixes()
312
+ fixes_applied.extend(function_fixes)
313
+ files_modified.extend(function_files)
314
+ return fixes_applied, files_modified
315
+
316
+ async def _apply_coverage_based_fixes(self) -> tuple[list[str], list[str]]:
317
+ fixes_applied: list[str] = []
318
+ files_modified: list[str] = []
319
+
320
+ coverage_analysis = await self._analyze_coverage()
321
+
322
+ if coverage_analysis["below_threshold"]:
323
+ fixes_applied, files_modified = await self._handle_low_coverage(
324
+ coverage_analysis, fixes_applied, files_modified
325
+ )
326
+
327
+ return fixes_applied, files_modified
328
+
329
+ async def _handle_low_coverage(
330
+ self,
331
+ coverage_analysis: dict[str, Any],
332
+ fixes_applied: list[str],
333
+ files_modified: list[str],
334
+ ) -> tuple[list[str], list[str]]:
335
+ self.log(
336
+ f"Coverage below threshold: {coverage_analysis['current_coverage']: .1%}",
337
+ )
338
+
339
+ return await self._process_uncovered_modules_for_low_coverage(
340
+ coverage_analysis["uncovered_modules"], fixes_applied, files_modified
341
+ )
342
+
343
+ async def _process_uncovered_modules_for_low_coverage(
344
+ self,
345
+ uncovered_modules: list[str],
346
+ fixes_applied: list[str],
347
+ files_modified: list[str],
348
+ ) -> tuple[list[str], list[str]]:
349
+ for module_path in uncovered_modules:
350
+ test_fixes = await self._create_tests_for_module(module_path)
351
+ fixes_applied.extend(test_fixes["fixes"])
352
+ files_modified.extend(test_fixes["files"])
353
+
354
+ return fixes_applied, files_modified
355
+
356
+ async def _process_uncovered_modules(
357
+ self,
358
+ uncovered_modules: list[str],
359
+ fixes_applied: list[str],
360
+ files_modified: list[str],
361
+ ) -> tuple[list[str], list[str]]:
362
+ return await self._process_each_uncovered_module(
363
+ uncovered_modules, fixes_applied, files_modified
364
+ )
365
+
366
+ async def _process_each_uncovered_module(
367
+ self,
368
+ uncovered_modules: list[str],
369
+ fixes_applied: list[str],
370
+ files_modified: list[str],
371
+ ) -> tuple[list[str], list[str]]:
372
+ return await self._process_all_uncovered_modules(
373
+ uncovered_modules, fixes_applied, files_modified
374
+ )
375
+
376
+ async def _process_all_uncovered_modules(
377
+ self,
378
+ uncovered_modules: list[str],
379
+ fixes_applied: list[str],
380
+ files_modified: list[str],
381
+ ) -> tuple[list[str], list[str]]:
382
+ for module_path in uncovered_modules:
383
+ fixes_applied, files_modified = await self._process_single_uncovered_module(
384
+ module_path, fixes_applied, files_modified
385
+ )
386
+
387
+ return fixes_applied, files_modified
388
+
389
+ async def _process_single_uncovered_module(
390
+ self,
391
+ module_path: str,
392
+ fixes_applied: list[str],
393
+ files_modified: list[str],
394
+ ) -> tuple[list[str], list[str]]:
395
+ test_fixes = await self._create_tests_for_module(module_path)
396
+ fixes_applied.extend(test_fixes["fixes"])
397
+ files_modified.extend(test_fixes["files"])
398
+ return fixes_applied, files_modified
399
+
400
+ async def _apply_file_specific_fixes(
401
+ self,
402
+ file_path: str | None,
403
+ ) -> tuple[list[str], list[str]]:
404
+ if not file_path:
405
+ return [], []
406
+
407
+ file_fixes = await self._create_tests_for_file(file_path)
408
+ return file_fixes["fixes"], file_fixes["files"]
409
+
410
+ async def _apply_function_specific_fixes(self) -> tuple[list[str], list[str]]:
411
+ fixes_applied: list[str] = []
412
+ files_modified: list[str] = []
413
+
414
+ untested_functions = await self._find_untested_functions()
415
+ fixes_applied, files_modified = await self._process_untested_functions(
416
+ untested_functions, fixes_applied, files_modified
417
+ )
418
+
419
+ return fixes_applied, files_modified
420
+
421
+ async def _process_untested_functions(
422
+ self,
423
+ untested_functions: list[dict[str, Any]],
424
+ fixes_applied: list[str],
425
+ files_modified: list[str],
426
+ ) -> tuple[list[str], list[str]]:
427
+ for func_info in untested_functions[:5]:
428
+ func_fixes = await self._create_test_for_function(func_info)
429
+ fixes_applied.extend(func_fixes["fixes"])
430
+ files_modified.extend(func_fixes["files"])
431
+
432
+ return fixes_applied, files_modified
433
+
434
+ def _create_test_creation_result(
435
+ self,
436
+ fixes_applied: list[str],
437
+ files_modified: list[str],
438
+ ) -> FixResult:
439
+ success = len(fixes_applied) > 0
440
+
441
+ confidence = self._calculate_confidence(success, fixes_applied, files_modified)
442
+
443
+ return FixResult(
444
+ success=success,
445
+ confidence=confidence,
446
+ fixes_applied=fixes_applied,
447
+ remaining_issues=[],
448
+ recommendations=self._generate_recommendations(success),
449
+ files_modified=files_modified,
450
+ )
451
+
452
+ def _calculate_confidence(
453
+ self, success: bool, fixes_applied: list[str], files_modified: list[str]
454
+ ) -> float:
455
+ if not success:
456
+ return 0.0
457
+
458
+ confidence = 0.5
459
+
460
+ test_file_fixes = [f for f in fixes_applied if "test file" in f.lower()]
461
+ function_fixes = [f for f in fixes_applied if "function" in f.lower()]
462
+ coverage_fixes = [f for f in fixes_applied if "coverage" in f.lower()]
463
+
464
+ if test_file_fixes:
465
+ confidence += 0.25
466
+ if function_fixes:
467
+ confidence += 0.15
468
+ if coverage_fixes:
469
+ confidence += 0.1
470
+
471
+ if len(files_modified) > 1:
472
+ confidence += 0.1
473
+
474
+ return min(confidence, 0.95)
475
+
476
+ def _generate_recommendations(self, success: bool) -> list[str]:
477
+ if success:
478
+ return [
479
+ "Generated comprehensive test suite",
480
+ "Consider running pytest to validate new tests",
481
+ "Review generated tests for edge cases",
482
+ ]
483
+ return [
484
+ "No test creation opportunities identified",
485
+ "Consider manual test creation for complex scenarios",
486
+ ]
487
+
488
+ def _get_enhanced_test_creation_recommendations(self) -> list[str]:
489
+ return [
490
+ "Run 'python -m crackerjack -t' to execute comprehensive coverage analysis",
491
+ (
492
+ "Focus on testing high-priority functions in managers/ services/ "
493
+ "and core/ modules"
494
+ ),
495
+ (
496
+ "Implement parametrized tests (@pytest.mark.parametrize) "
497
+ "for functions with multiple arguments"
498
+ ),
499
+ "Add edge case testing for boundary conditions and error scenarios",
500
+ "Use fixtures for complex object instantiation and dependency injection",
501
+ "Consider integration tests for modules with multiple classes/functions",
502
+ "Add async tests for coroutine functions using @pytest.mark.asyncio",
503
+ "Mock external dependencies to ensure isolated unit testing",
504
+ "Target ≥10% coverage improvement through systematic test creation",
505
+ "Validate generated tests are syntactically correct before committing",
506
+ ]
507
+
508
+ def _create_error_result(self, error: Exception) -> FixResult:
509
+ return FixResult(
510
+ success=False,
511
+ confidence=0.0,
512
+ remaining_issues=[f"Failed to create tests: {error}"],
513
+ recommendations=[
514
+ "Manual test creation may be required",
515
+ "Check existing test structure and patterns",
516
+ ],
517
+ )
518
+
519
+ async def _analyze_coverage(self) -> dict[str, Any]:
520
+ return await self._coverage_analyzer.analyze_coverage()
521
+
522
+ async def _create_tests_for_module(self, module_path: str) -> dict[str, list[str]]:
523
+ return await self._coverage_analyzer.create_tests_for_module(module_path)
524
+
525
+ async def _create_tests_for_file(self, file_path: str) -> dict[str, list[str]]:
526
+ return await self._coverage_analyzer.create_tests_for_file(file_path)
527
+
528
+ async def _find_untested_functions(self) -> list[dict[str, Any]]:
529
+ return await self._coverage_analyzer.find_untested_functions()
530
+
531
+ async def _create_test_for_function(
532
+ self,
533
+ func_info: dict[str, Any],
534
+ ) -> dict[str, list[str]]:
535
+ return await self._coverage_analyzer.create_test_for_function(func_info)
536
+
537
+ async def _extract_functions_from_file(
538
+ self,
539
+ file_path: Path,
540
+ ) -> list[dict[str, Any]]:
541
+ return await self._ast_analyzer.extract_functions_from_file(file_path)
542
+
543
+ async def _extract_classes_from_file(self, file_path: Path) -> list[dict[str, Any]]:
544
+ return await self._ast_analyzer.extract_classes_from_file(file_path)
545
+
546
+ async def _function_has_test(
547
+ self,
548
+ func_info: dict[str, Any],
549
+ file_path: Path,
550
+ ) -> bool:
551
+ return await self._ast_analyzer.function_has_test(func_info, file_path)
552
+
553
+ async def _generate_test_file_path(self, source_file: Path) -> Path:
554
+ return await self._ast_analyzer.generate_test_file_path(source_file)
555
+
556
+ def _has_corresponding_test(self, file_path: str) -> bool:
557
+ return self._ast_analyzer.has_corresponding_test(file_path)
558
+
559
+ async def _generate_test_content(
560
+ self,
561
+ module_file: Path,
562
+ functions: list[dict[str, Any]],
563
+ classes: list[dict[str, Any]],
564
+ ) -> str:
565
+ return await self._template_generator.generate_test_content(
566
+ module_file, functions, classes
567
+ )
568
+
569
+
570
+ agent_registry.register(TestCreationAgent)