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,699 @@
1
+ import asyncio
2
+ import time
3
+ import typing as t
4
+ import uuid
5
+
6
+ from crackerjack.mcp.context import get_context
7
+
8
+ from .progress_tools import _update_progress
9
+
10
+
11
+ async def execute_crackerjack_workflow(
12
+ args: str, kwargs: dict[str, t.Any]
13
+ ) -> dict[str, t.Any]:
14
+ job_id = str(uuid.uuid4())[:8]
15
+
16
+ # Get context first
17
+ context = get_context()
18
+
19
+ # Initialize progress immediately
20
+ _update_progress(
21
+ job_id,
22
+ {"status": "started", "args": args, "timestamp": time.time()},
23
+ context,
24
+ 1,
25
+ 5,
26
+ 0,
27
+ "initialization",
28
+ 0,
29
+ "Crackerjack execution started",
30
+ )
31
+
32
+ # Start execution in background - no timeout!
33
+ asyncio.create_task(_execute_crackerjack_background(job_id, args, kwargs, context))
34
+
35
+ # Return job_id immediately for progress monitoring
36
+ return {
37
+ "job_id": job_id,
38
+ "status": "running",
39
+ "message": "Execution started. Use get_job_progress(job_id) to monitor progress.",
40
+ "timestamp": time.time(),
41
+ }
42
+
43
+
44
+ async def _execute_crackerjack_background(
45
+ job_id: str,
46
+ args: str,
47
+ kwargs: dict[str, t.Any],
48
+ context: t.Any,
49
+ ) -> None:
50
+ """Execute crackerjack workflow in background with progress updates."""
51
+ try:
52
+ result = await _execute_crackerjack_sync(job_id, args, kwargs, context)
53
+
54
+ # Update final progress with result
55
+ _update_progress(
56
+ job_id,
57
+ {
58
+ "status": result.get("status", "completed"),
59
+ "result": result,
60
+ "timestamp": time.time(),
61
+ "final": True,
62
+ },
63
+ context,
64
+ 1,
65
+ 5,
66
+ 100,
67
+ "completed",
68
+ 100,
69
+ f"Execution {result.get('status', 'completed')}",
70
+ )
71
+ except Exception as e:
72
+ import traceback
73
+
74
+ # Update progress with error
75
+ _update_progress(
76
+ job_id,
77
+ {
78
+ "status": "failed",
79
+ "error": str(e),
80
+ "traceback": traceback.format_exc(),
81
+ "timestamp": time.time(),
82
+ "final": True,
83
+ },
84
+ context,
85
+ 1,
86
+ 5,
87
+ -1,
88
+ "failed",
89
+ -1,
90
+ f"Execution failed: {e}",
91
+ )
92
+
93
+
94
+ async def _execute_crackerjack_sync(
95
+ job_id: str,
96
+ args: str,
97
+ kwargs: dict[str, t.Any],
98
+ context: t.Any,
99
+ ) -> dict[str, t.Any]:
100
+ setup_result = await _initialize_execution(job_id, args, kwargs, context)
101
+ if setup_result.get("status") == "failed":
102
+ return setup_result
103
+
104
+ orchestrator_result = await _setup_orchestrator(
105
+ job_id, args, kwargs, setup_result["working_dir"], context
106
+ )
107
+ if orchestrator_result.get("status") == "failed":
108
+ return orchestrator_result
109
+
110
+ orchestrator = orchestrator_result["orchestrator"]
111
+
112
+ return await _run_workflow_iterations(job_id, orchestrator, kwargs, context)
113
+
114
+
115
+ async def _initialize_execution(
116
+ job_id: str,
117
+ args: str,
118
+ kwargs: dict[str, t.Any],
119
+ context: t.Any,
120
+ ) -> dict[str, t.Any]:
121
+ _update_progress(
122
+ job_id,
123
+ {
124
+ "type": "initialization",
125
+ "status": "starting",
126
+ "message": "Initializing crackerjack execution...",
127
+ },
128
+ context,
129
+ )
130
+
131
+ await _ensure_websocket_server_running(job_id, context)
132
+
133
+ working_dir = kwargs.get("working_directory", ".")
134
+ from pathlib import Path
135
+
136
+ working_path = Path(working_dir)
137
+ if not working_path.exists():
138
+ return {
139
+ "status": "failed",
140
+ "error": f"Working directory does not exist: {working_dir}",
141
+ "job_id": job_id,
142
+ }
143
+
144
+ _update_progress(
145
+ job_id,
146
+ {
147
+ "type": "initialization",
148
+ "status": "ready",
149
+ "working_directory": str(working_path.absolute()),
150
+ },
151
+ context,
152
+ )
153
+
154
+ return {
155
+ "status": "initialized",
156
+ "working_dir": working_path.absolute(),
157
+ "job_id": job_id,
158
+ }
159
+
160
+
161
+ async def _setup_orchestrator(
162
+ job_id: str,
163
+ args: str,
164
+ kwargs: dict[str, t.Any],
165
+ working_dir: t.Any,
166
+ context: t.Any,
167
+ ) -> dict[str, t.Any]:
168
+ _update_progress(
169
+ job_id,
170
+ {
171
+ "type": "setup",
172
+ "status": "creating_orchestrator",
173
+ "message": "Setting up workflow orchestrator...",
174
+ },
175
+ context,
176
+ )
177
+
178
+ use_advanced = kwargs.get("advanced_orchestration", False)
179
+
180
+ try:
181
+ if use_advanced:
182
+ orchestrator = await _create_advanced_orchestrator(
183
+ working_dir, kwargs, context
184
+ )
185
+ else:
186
+ orchestrator = _create_standard_orchestrator(working_dir, kwargs)
187
+
188
+ return {
189
+ "status": "ready",
190
+ "orchestrator": orchestrator,
191
+ "job_id": job_id,
192
+ }
193
+
194
+ except Exception as e:
195
+ return {
196
+ "status": "failed",
197
+ "error": f"Failed to create orchestrator: {e}",
198
+ "job_id": job_id,
199
+ }
200
+
201
+
202
+ async def _create_advanced_orchestrator(
203
+ working_dir: t.Any, kwargs: dict[str, t.Any], context: t.Any
204
+ ) -> t.Any:
205
+ from pathlib import Path
206
+
207
+ from crackerjack.core.async_workflow_orchestrator import AsyncWorkflowOrchestrator
208
+
209
+ # AsyncWorkflowOrchestrator now uses ACB DI internally
210
+ orchestrator = AsyncWorkflowOrchestrator(
211
+ pkg_path=Path(working_dir),
212
+ verbose=kwargs.get("verbose", False),
213
+ debug=kwargs.get("debug", False),
214
+ )
215
+
216
+ return orchestrator
217
+
218
+
219
+ def _create_standard_orchestrator(
220
+ working_dir: t.Any, kwargs: dict[str, t.Any]
221
+ ) -> t.Any:
222
+ from pathlib import Path
223
+
224
+ from crackerjack.core.workflow_orchestrator import WorkflowOrchestrator
225
+
226
+ return WorkflowOrchestrator(pkg_path=Path(working_dir))
227
+
228
+
229
+ async def _register_core_services(container: t.Any, working_dir: t.Any) -> None:
230
+ from acb.console import Console
231
+
232
+ from crackerjack.managers.hook_manager import AsyncHookManager
233
+ from crackerjack.managers.publish_manager import PublishManagerImpl
234
+ from crackerjack.managers.test_manager import TestManagementImpl
235
+ from crackerjack.models.protocols import (
236
+ FileSystemInterface,
237
+ HookManager,
238
+ PublishManager,
239
+ TestManagerProtocol,
240
+ )
241
+ from crackerjack.services.enhanced_filesystem import EnhancedFileSystemService
242
+
243
+ console = depends.get_sync(Console)
244
+
245
+ container.register_singleton(
246
+ HookManager,
247
+ factory=lambda: AsyncHookManager(console, working_dir),
248
+ )
249
+
250
+ container.register_singleton(
251
+ TestManagerProtocol,
252
+ factory=lambda: TestManagementImpl(console, working_dir),
253
+ )
254
+
255
+ # Use factory without parameters to trigger @depends.inject decorator
256
+ # The decorator will inject all dependencies from the DI container
257
+ container.register_singleton(
258
+ PublishManager,
259
+ factory=PublishManagerImpl,
260
+ )
261
+
262
+ container.register_singleton(
263
+ FileSystemInterface,
264
+ factory=EnhancedFileSystemService,
265
+ )
266
+
267
+
268
+ async def _run_workflow_iterations(
269
+ job_id: str,
270
+ orchestrator: t.Any,
271
+ kwargs: dict[str, t.Any],
272
+ context: t.Any,
273
+ ) -> dict[str, t.Any]:
274
+ options = _create_workflow_options(kwargs)
275
+ max_iterations = kwargs.get("max_iterations", 5)
276
+
277
+ keep_alive_task = asyncio.create_task(_keep_alive_heartbeat(job_id, context))
278
+
279
+ try:
280
+ result = await _execute_iterations_loop(
281
+ job_id, orchestrator, options, kwargs, max_iterations, context
282
+ )
283
+ return result
284
+ finally:
285
+ await _cleanup_keep_alive_task(keep_alive_task)
286
+
287
+
288
+ async def _execute_iterations_loop(
289
+ job_id: str,
290
+ orchestrator: t.Any,
291
+ options: t.Any,
292
+ kwargs: dict[str, t.Any],
293
+ max_iterations: int,
294
+ context: t.Any,
295
+ ) -> dict[str, t.Any]:
296
+ for iteration in range(max_iterations):
297
+ _update_iteration_progress(job_id, iteration, max_iterations, context)
298
+
299
+ try:
300
+ success = await _execute_single_iteration(
301
+ job_id, orchestrator, options, iteration, context
302
+ )
303
+
304
+ if success:
305
+ return await _handle_iteration_success(
306
+ job_id, iteration, orchestrator, kwargs, context
307
+ )
308
+
309
+ if iteration < max_iterations - 1:
310
+ await _handle_iteration_retry(job_id, iteration, context)
311
+
312
+ except Exception as e:
313
+ return await _handle_iteration_error(job_id, iteration, e, context)
314
+
315
+ return _create_failure_result(job_id, max_iterations, context)
316
+
317
+
318
+ def _update_iteration_progress(
319
+ job_id: str, iteration: int, max_iterations: int, context: t.Any
320
+ ) -> None:
321
+ _update_progress(
322
+ job_id,
323
+ {
324
+ "type": "iteration",
325
+ "iteration": iteration + 1,
326
+ "max_iterations": max_iterations,
327
+ "status": "running",
328
+ },
329
+ context,
330
+ )
331
+
332
+
333
+ async def _handle_iteration_success(
334
+ job_id: str,
335
+ iteration: int,
336
+ orchestrator: t.Any,
337
+ kwargs: dict[str, t.Any],
338
+ context: t.Any,
339
+ ) -> dict[str, t.Any]:
340
+ coverage_result = None
341
+ if kwargs.get("boost_coverage", False):
342
+ coverage_result = await _attempt_coverage_improvement(
343
+ job_id, orchestrator, context
344
+ )
345
+ return _create_success_result(job_id, iteration + 1, context, coverage_result)
346
+
347
+
348
+ async def _cleanup_keep_alive_task(keep_alive_task: asyncio.Task[t.Any]) -> None:
349
+ if not keep_alive_task.cancelled():
350
+ keep_alive_task.cancel()
351
+ try:
352
+ await keep_alive_task
353
+ except asyncio.CancelledError:
354
+ pass
355
+
356
+
357
+ async def _keep_alive_heartbeat(job_id: str, context: t.Any) -> None:
358
+ try:
359
+ while True:
360
+ await asyncio.sleep(60)
361
+ _update_progress(
362
+ job_id,
363
+ {
364
+ "type": "keep_alive",
365
+ "status": "heartbeat",
366
+ "timestamp": time.time(),
367
+ "message": "Keep-alive heartbeat to prevent connection timeout",
368
+ },
369
+ context,
370
+ )
371
+ except asyncio.CancelledError:
372
+ _update_progress(
373
+ job_id,
374
+ {
375
+ "type": "keep_alive",
376
+ "status": "cancelled",
377
+ "timestamp": time.time(),
378
+ },
379
+ context,
380
+ )
381
+
382
+
383
+ def _create_workflow_options(kwargs: dict[str, t.Any]) -> t.Any:
384
+ from types import SimpleNamespace
385
+
386
+ options = SimpleNamespace()
387
+
388
+ options.commit = kwargs.get("commit", False)
389
+ options.interactive = kwargs.get("interactive", False)
390
+ options.no_config_updates = kwargs.get("no_config_updates", False)
391
+ options.verbose = kwargs.get("verbose", True)
392
+ options.clean = kwargs.get("clean", False)
393
+ options.test = kwargs.get("test_mode", True)
394
+ options.benchmark = kwargs.get("benchmark", False)
395
+ options.skip_hooks = kwargs.get("skip_hooks", False)
396
+ options.ai_agent = kwargs.get("ai_agent", True)
397
+ options.async_mode = kwargs.get("async_mode", True)
398
+
399
+ options.test_workers = kwargs.get("test_workers", 0)
400
+ options.test_timeout = kwargs.get("test_timeout", 0)
401
+
402
+ options.publish = kwargs.get("publish")
403
+ options.bump = kwargs.get("bump")
404
+ options.all = kwargs.get("all")
405
+ options.create_pr = kwargs.get("create_pr", False)
406
+ options.no_git_tags = kwargs.get("no_git_tags", False)
407
+ options.skip_version_check = kwargs.get("skip_version_check", False)
408
+ options.cleanup_pypi = kwargs.get("cleanup_pypi", False)
409
+ options.keep_releases = kwargs.get("keep_releases", 10)
410
+
411
+ options.start_mcp_server = kwargs.get("start_mcp_server", False)
412
+
413
+ options.update_precommit = kwargs.get("update_precommit", False)
414
+ options.experimental_hooks = kwargs.get("experimental_hooks", False)
415
+ options.enable_pyrefly = kwargs.get("enable_pyrefly", False)
416
+ options.enable_ty = kwargs.get("enable_ty", False)
417
+
418
+ options.cleanup = kwargs.get("cleanup")
419
+
420
+ options.coverage = kwargs.get("coverage", False)
421
+ options.track_progress = kwargs.get("track_progress", False)
422
+
423
+ options.fast = kwargs.get("fast", False)
424
+ options.comp = kwargs.get("comp", False)
425
+
426
+ return options
427
+
428
+
429
+ async def _execute_single_iteration(
430
+ job_id: str,
431
+ orchestrator: t.Any,
432
+ options: t.Any,
433
+ iteration: int,
434
+ context: t.Any,
435
+ ) -> bool:
436
+ try:
437
+ method_name = _detect_orchestrator_method(orchestrator)
438
+ result = _invoke_orchestrator_method(orchestrator, method_name, options)
439
+
440
+ # Sync methods return directly, async methods need await
441
+ if method_name == "run":
442
+ return result
443
+
444
+ # Async methods - validate and await
445
+ _validate_awaitable_result(result, method_name, orchestrator)
446
+ return await result
447
+ except Exception as e:
448
+ raise RuntimeError(
449
+ f"Error in _execute_single_iteration (iteration {iteration}): {e}"
450
+ ) from e
451
+
452
+
453
+ def _detect_orchestrator_method(orchestrator: t.Any) -> str:
454
+ """Detect which workflow method the orchestrator supports."""
455
+ method_priority = [
456
+ "run_complete_workflow_async",
457
+ "run_complete_workflow",
458
+ "execute_workflow",
459
+ "run",
460
+ ]
461
+
462
+ for method_name in method_priority:
463
+ if hasattr(orchestrator, method_name):
464
+ return method_name
465
+
466
+ available_methods = [m for m in dir(orchestrator) if not m.startswith("_")]
467
+ raise ValueError(
468
+ f"Orchestrator {type(orchestrator).__name__} has no recognized workflow execution method. "
469
+ f"Available methods: {available_methods}"
470
+ )
471
+
472
+
473
+ def _invoke_orchestrator_method(
474
+ orchestrator: t.Any, method_name: str, options: t.Any
475
+ ) -> t.Any:
476
+ """Invoke the detected orchestrator method with options."""
477
+ method = getattr(orchestrator, method_name)
478
+ result = method(options)
479
+
480
+ if result is None:
481
+ raise ValueError(
482
+ f"Method {method_name} returned None instead of expected result. "
483
+ f"Orchestrator type: {type(orchestrator).__name__}"
484
+ )
485
+
486
+ return result
487
+
488
+
489
+ def _validate_awaitable_result(
490
+ result: t.Any, method_name: str, orchestrator: t.Any
491
+ ) -> None:
492
+ """Validate that async method result is awaitable."""
493
+ if not hasattr(result, "__await__"):
494
+ raise ValueError(
495
+ f"Method {method_name} returned non-awaitable object: {type(result).__name__}. "
496
+ f"Orchestrator: {type(orchestrator).__name__}"
497
+ )
498
+
499
+
500
+ def _create_success_result(
501
+ job_id: str,
502
+ iterations: int,
503
+ context: t.Any,
504
+ coverage_result: dict[str, t.Any] | None = None,
505
+ ) -> dict[str, t.Any]:
506
+ result = {
507
+ "job_id": job_id,
508
+ "status": "completed",
509
+ "iterations": iterations,
510
+ "result": "All quality checks passed successfully",
511
+ "timestamp": time.time(),
512
+ "success": True,
513
+ }
514
+
515
+ if coverage_result:
516
+ result["coverage_improvement"] = coverage_result
517
+
518
+ return result
519
+
520
+
521
+ async def _handle_iteration_retry(job_id: str, iteration: int, context: t.Any) -> None:
522
+ _update_progress(
523
+ job_id,
524
+ {
525
+ "type": "iteration",
526
+ "iteration": iteration + 1,
527
+ "status": "retrying",
528
+ "message": f"Issues found in iteration {iteration + 1}, retrying...",
529
+ },
530
+ context,
531
+ )
532
+
533
+ await asyncio.sleep(1)
534
+
535
+
536
+ async def _handle_iteration_error(
537
+ job_id: str, iteration: int, error: Exception, context: t.Any
538
+ ) -> dict[str, t.Any]:
539
+ _update_progress(
540
+ job_id,
541
+ {
542
+ "type": "error",
543
+ "iteration": iteration + 1,
544
+ "error": str(error),
545
+ "status": "failed",
546
+ },
547
+ context,
548
+ )
549
+
550
+ return {
551
+ "job_id": job_id,
552
+ "status": "failed",
553
+ "error": f"Iteration {iteration + 1} failed: {error}",
554
+ "timestamp": time.time(),
555
+ "success": False,
556
+ }
557
+
558
+
559
+ async def _attempt_coverage_improvement(
560
+ job_id: str, orchestrator: t.Any, context: t.Any
561
+ ) -> dict[str, t.Any]:
562
+ try:
563
+ _update_progress(
564
+ job_id,
565
+ {
566
+ "type": "coverage_improvement",
567
+ "status": "starting",
568
+ "message": "Analyzing coverage for improvement opportunities...",
569
+ },
570
+ context,
571
+ )
572
+
573
+ project_path = getattr(orchestrator, "pkg_path", None)
574
+ if not project_path:
575
+ return {"status": "skipped", "reason": "No project path available"}
576
+
577
+ from crackerjack.orchestration.coverage_improvement import (
578
+ create_coverage_improvement_orchestrator,
579
+ )
580
+
581
+ coverage_orchestrator = await create_coverage_improvement_orchestrator(
582
+ project_path,
583
+ console=getattr(orchestrator, "console", None),
584
+ )
585
+
586
+ should_improve = await coverage_orchestrator.should_improve_coverage()
587
+ if not should_improve:
588
+ _update_progress(
589
+ job_id,
590
+ {
591
+ "type": "coverage_improvement",
592
+ "status": "skipped",
593
+ "message": "Coverage improvement not needed (already at 100 %)",
594
+ },
595
+ context,
596
+ )
597
+ return {"status": "skipped", "reason": "Coverage at 100 %"}
598
+
599
+ from crackerjack.agents.base import AgentContext
600
+
601
+ agent_context = AgentContext(project_path=project_path, console=None)
602
+
603
+ _update_progress(
604
+ job_id,
605
+ {
606
+ "type": "coverage_improvement",
607
+ "status": "executing",
608
+ "message": "Generating tests to improve coverage...",
609
+ },
610
+ context,
611
+ )
612
+
613
+ improvement_result = await coverage_orchestrator.execute_coverage_improvement(
614
+ agent_context
615
+ )
616
+
617
+ if improvement_result["status"] == "completed":
618
+ _update_progress(
619
+ job_id,
620
+ {
621
+ "type": "coverage_improvement",
622
+ "status": "completed",
623
+ "message": f"Coverage improvement: {len(improvement_result.get('fixes_applied', []))} tests created",
624
+ "fixes_applied": improvement_result.get("fixes_applied", []),
625
+ "files_modified": improvement_result.get("files_modified", []),
626
+ },
627
+ context,
628
+ )
629
+ else:
630
+ _update_progress(
631
+ job_id,
632
+ {
633
+ "type": "coverage_improvement",
634
+ "status": "completed_with_issues",
635
+ "message": f"Coverage improvement attempted: {improvement_result.get('status', 'unknown')}",
636
+ },
637
+ context,
638
+ )
639
+
640
+ return improvement_result
641
+
642
+ except Exception as e:
643
+ _update_progress(
644
+ job_id,
645
+ {
646
+ "type": "coverage_improvement",
647
+ "status": "failed",
648
+ "error": str(e),
649
+ "message": f"Coverage improvement failed: {e}",
650
+ },
651
+ context,
652
+ )
653
+
654
+ return {
655
+ "status": "failed",
656
+ "error": str(e),
657
+ "fixes_applied": [],
658
+ "files_modified": [],
659
+ }
660
+
661
+
662
+ def _create_failure_result(
663
+ job_id: str, max_iterations: int, context: t.Any
664
+ ) -> dict[str, t.Any]:
665
+ return {
666
+ "job_id": job_id,
667
+ "status": "failed",
668
+ "error": f"Maximum iterations ({max_iterations}) reached without success",
669
+ "timestamp": time.time(),
670
+ "success": False,
671
+ }
672
+
673
+
674
+ async def _ensure_websocket_server_running(job_id: str, context: t.Any) -> None:
675
+ try:
676
+ from crackerjack.mcp.progress_components import ServiceManager
677
+
678
+ service_manager = ServiceManager()
679
+ await service_manager.ensure_services_running()
680
+
681
+ _update_progress(
682
+ job_id,
683
+ {
684
+ "type": "service_check",
685
+ "status": "websocket_ready",
686
+ "message": "WebSocket server ensured running for progress tracking",
687
+ },
688
+ context,
689
+ )
690
+ except Exception as e:
691
+ _update_progress(
692
+ job_id,
693
+ {
694
+ "type": "service_check",
695
+ "status": "websocket_warning",
696
+ "message": f"WebSocket server auto-start failed: {e}. Progress tracking may be limited.",
697
+ },
698
+ context,
699
+ )