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,738 @@
1
+ import asyncio
2
+ import time
3
+ import typing as t
4
+ from contextlib import suppress
5
+ from pathlib import Path
6
+
7
+ from acb.depends import Inject, depends
8
+ from acb.logger import Logger
9
+ from rich.console import Console
10
+
11
+ from crackerjack.agents.base import FixResult, Issue, IssueType, Priority
12
+ from crackerjack.models.protocols import OptionsProtocol
13
+
14
+ from .phase_coordinator import PhaseCoordinator
15
+ from .session_coordinator import SessionCoordinator
16
+ from .timeout_manager import TimeoutStrategy, get_timeout_manager
17
+
18
+
19
+ class AsyncWorkflowPipeline:
20
+ @depends.inject
21
+ def __init__(
22
+ self,
23
+ logger: Inject[Logger],
24
+ console: Inject[Console],
25
+ pkg_path: Path,
26
+ session: SessionCoordinator,
27
+ phases: PhaseCoordinator,
28
+ ) -> None:
29
+ self.console = console
30
+ self.pkg_path = pkg_path
31
+ self.session = session
32
+ self.phases = phases
33
+ self.logger = logger
34
+ self.timeout_manager = get_timeout_manager()
35
+ self._active_tasks: list[asyncio.Task[t.Any]] = []
36
+ self.resource_context: t.Any | None = None
37
+
38
+ async def run_complete_workflow_async(self, options: OptionsProtocol) -> bool:
39
+ start_time = time.time()
40
+ self.session.initialize_session_tracking(options)
41
+ self.session.track_task("workflow", "Complete async crackerjack workflow")
42
+
43
+ try:
44
+ async with self.timeout_manager.timeout_context(
45
+ "complete_workflow", strategy=TimeoutStrategy.GRACEFUL_DEGRADATION
46
+ ):
47
+ if hasattr(options, "ai_agent") and options.ai_agent:
48
+ success = await self._execute_ai_agent_workflow_async(options)
49
+ else:
50
+ success = await self._execute_workflow_phases_async(options)
51
+ self.session.finalize_session(start_time, success)
52
+ return success
53
+ except KeyboardInterrupt:
54
+ self.console.print("Interrupted by user")
55
+ self.session.fail_task("workflow", "Interrupted by user")
56
+ return False
57
+ except Exception as e:
58
+ self.console.print(f"Error: {e}")
59
+ self.session.fail_task("workflow", f"Unexpected error: {e}")
60
+ return False
61
+ finally:
62
+ self.session.cleanup_resources()
63
+
64
+ async def _execute_workflow_phases_async(self, options: OptionsProtocol) -> bool:
65
+ success = True
66
+
67
+ self.phases.run_configuration_phase(options) # type: ignore[arg-type]
68
+
69
+ if not await self._execute_cleaning_phase_async(options):
70
+ success = False
71
+
72
+ self.session.fail_task("workflow", "Cleaning phase failed")
73
+ return False
74
+
75
+ if not await self._execute_quality_phase_async(options):
76
+ success = False
77
+
78
+ return False
79
+
80
+ if not self.phases.run_publishing_phase(options): # type: ignore[arg-type]
81
+ success = False
82
+ self.session.fail_task("workflow", "Publishing failed")
83
+ return False
84
+
85
+ if not self.phases.run_commit_phase(options): # type: ignore[arg-type]
86
+ success = False
87
+
88
+ return success
89
+
90
+ async def _cleanup_active_tasks(self) -> None:
91
+ if not self._active_tasks:
92
+ return
93
+
94
+ self.logger.info(f"Cleaning up {len(self._active_tasks)} active tasks")
95
+
96
+ for task in self._active_tasks:
97
+ if not task.done():
98
+ task.cancel()
99
+
100
+ if self._active_tasks:
101
+ try:
102
+ await asyncio.wait_for(
103
+ asyncio.gather(*self._active_tasks, return_exceptions=True),
104
+ timeout=30.0,
105
+ )
106
+ except TimeoutError:
107
+ self.logger.warning("Timeout waiting for task cleanup")
108
+
109
+ self._active_tasks.clear()
110
+
111
+ async def _execute_cleaning_phase_async(self, options: OptionsProtocol) -> bool:
112
+ if not options.clean:
113
+ return True
114
+
115
+ result = await self.timeout_manager.with_timeout(
116
+ "file_operations",
117
+ asyncio.to_thread(self.phases.run_cleaning_phase, options), # type: ignore[arg-type]
118
+ strategy=TimeoutStrategy.RETRY_WITH_BACKOFF,
119
+ )
120
+ return bool(result) # type: ignore[return-value]
121
+
122
+ async def _execute_quality_phase_async(self, options: OptionsProtocol) -> bool:
123
+ if hasattr(options, "fast") and options.fast:
124
+ return await self._run_fast_hooks_async(options)
125
+ if hasattr(options, "comp") and options.comp:
126
+ return await self._run_comprehensive_hooks_async(options)
127
+ print(f"DEBUG: options.test = {options.test}")
128
+ if options.test:
129
+ return await self._execute_test_workflow_async(options)
130
+ return await self._execute_standard_hooks_workflow_async(options)
131
+
132
+ async def _execute_test_workflow_async(self, options: OptionsProtocol) -> bool:
133
+ overall_success = True
134
+
135
+ if not await self._run_fast_hooks_async(options):
136
+ overall_success = False
137
+ self.session.fail_task("workflow", "Fast hooks failed")
138
+ return False
139
+
140
+ try:
141
+ test_task, hooks_task = self._create_parallel_tasks(options)
142
+ done, pending = await self._execute_parallel_tasks(test_task, hooks_task)
143
+
144
+ await self._cleanup_pending_tasks(pending)
145
+
146
+ test_success, hooks_success = await self._process_task_results(
147
+ done, test_task, hooks_task
148
+ )
149
+
150
+ return self._validate_workflow_results(
151
+ test_success, hooks_success, overall_success
152
+ )
153
+
154
+ except Exception as e:
155
+ self.logger.error(f"Test workflow execution error: {e}")
156
+ self.session.fail_task("workflow", f"Test workflow error: {e}")
157
+ return False
158
+
159
+ def _create_parallel_tasks(
160
+ self, options: OptionsProtocol
161
+ ) -> tuple[asyncio.Task[bool], asyncio.Task[bool]]:
162
+ test_task = asyncio.create_task(
163
+ self.timeout_manager.with_timeout(
164
+ "test_execution",
165
+ self._run_testing_phase_async(options),
166
+ strategy=TimeoutStrategy.GRACEFUL_DEGRADATION,
167
+ )
168
+ )
169
+ hooks_task = asyncio.create_task(
170
+ self.timeout_manager.with_timeout(
171
+ "comprehensive_hooks",
172
+ self._run_comprehensive_hooks_async(options),
173
+ strategy=TimeoutStrategy.GRACEFUL_DEGRADATION,
174
+ )
175
+ )
176
+ return test_task, hooks_task
177
+
178
+ async def _execute_parallel_tasks(
179
+ self, test_task: asyncio.Task[bool], hooks_task: asyncio.Task[bool]
180
+ ) -> tuple[set[asyncio.Task[bool]], set[asyncio.Task[bool]]]:
181
+ combined_timeout = (
182
+ self.timeout_manager.get_timeout("test_execution")
183
+ + self.timeout_manager.get_timeout("comprehensive_hooks")
184
+ + 60
185
+ )
186
+
187
+ done, pending = await asyncio.wait(
188
+ [test_task, hooks_task],
189
+ timeout=combined_timeout,
190
+ return_when=asyncio.ALL_COMPLETED,
191
+ )
192
+
193
+ return done, pending
194
+
195
+ @staticmethod
196
+ async def _cleanup_pending_tasks(pending: set[asyncio.Task[t.Any]]) -> None:
197
+ for task in pending:
198
+ task.cancel()
199
+ with suppress(asyncio.CancelledError):
200
+ await task
201
+
202
+ async def _process_task_results(
203
+ self,
204
+ done: set[asyncio.Task[bool]],
205
+ test_task: asyncio.Task[bool],
206
+ hooks_task: asyncio.Task[bool],
207
+ ) -> tuple[bool, bool]:
208
+ test_success = hooks_success = False
209
+
210
+ for task in done:
211
+ try:
212
+ result = await task
213
+ if task == test_task:
214
+ test_success = result
215
+ elif task == hooks_task:
216
+ hooks_success = result
217
+ except Exception as e:
218
+ self.logger.error(f"Task execution error: {e}")
219
+ if task == test_task:
220
+ test_success = False
221
+ elif task == hooks_task:
222
+ hooks_success = False
223
+
224
+ return test_success, hooks_success
225
+
226
+ def _validate_workflow_results(
227
+ self, test_success: bool, hooks_success: bool, overall_success: bool
228
+ ) -> bool:
229
+ if not test_success:
230
+ overall_success = False
231
+ self.session.fail_task("workflow", "Testing failed")
232
+ return False
233
+
234
+ if not hooks_success:
235
+ overall_success = False
236
+ self.session.fail_task("workflow", "Comprehensive hooks failed")
237
+ return False
238
+
239
+ return overall_success
240
+
241
+ async def _execute_standard_hooks_workflow_async(
242
+ self,
243
+ options: OptionsProtocol,
244
+ ) -> bool:
245
+ hooks_success = await self._run_hooks_phase_async(options)
246
+ if not hooks_success:
247
+ self.session.fail_task("workflow", "Hooks failed")
248
+ return False
249
+ return True
250
+
251
+ async def _create_managed_task(
252
+ self,
253
+ coro: t.Coroutine[t.Any, t.Any, t.Any],
254
+ timeout: float = 300.0,
255
+ task_name: str = "workflow_task",
256
+ ) -> asyncio.Task[t.Any]:
257
+ task = asyncio.create_task(coro, name=task_name)
258
+
259
+ if self.resource_context:
260
+ self.resource_context.managed_task(task, timeout)
261
+
262
+ self._active_tasks.append(task)
263
+ return task
264
+
265
+ async def _run_fast_hooks_async(self, options: OptionsProtocol) -> bool:
266
+ result = await self.timeout_manager.with_timeout(
267
+ "fast_hooks",
268
+ asyncio.to_thread(self.phases.run_fast_hooks_only, options), # type: ignore[arg-type]
269
+ strategy=TimeoutStrategy.RETRY_WITH_BACKOFF,
270
+ )
271
+ return bool(result) # type: ignore[return-value]
272
+
273
+ async def _run_comprehensive_hooks_async(self, options: OptionsProtocol) -> bool:
274
+ result = await self.timeout_manager.with_timeout(
275
+ "comprehensive_hooks",
276
+ asyncio.to_thread(self.phases.run_comprehensive_hooks_only, options), # type: ignore[arg-type]
277
+ strategy=TimeoutStrategy.GRACEFUL_DEGRADATION,
278
+ )
279
+ return bool(result) # type: ignore[return-value]
280
+
281
+ async def _run_hooks_phase_async(self, options: OptionsProtocol) -> bool:
282
+ result = await self.timeout_manager.with_timeout(
283
+ "comprehensive_hooks",
284
+ asyncio.to_thread(self.phases.run_hooks_phase, options), # type: ignore[arg-type]
285
+ strategy=TimeoutStrategy.GRACEFUL_DEGRADATION,
286
+ )
287
+ return bool(result) # type: ignore[return-value]
288
+
289
+ async def _run_testing_phase_async(self, options: OptionsProtocol) -> bool:
290
+ result = await self.timeout_manager.with_timeout(
291
+ "test_execution",
292
+ asyncio.to_thread(self.phases.run_testing_phase, options), # type: ignore[arg-type]
293
+ strategy=TimeoutStrategy.GRACEFUL_DEGRADATION,
294
+ )
295
+ return bool(result) # type: ignore[return-value]
296
+
297
+ async def _execute_ai_agent_workflow_async(
298
+ self, options: OptionsProtocol, max_iterations: int = 10
299
+ ) -> bool:
300
+ self.console.print(
301
+ f"🤖 Starting AI Agent workflow (max {max_iterations} iterations)"
302
+ )
303
+
304
+ self.phases.run_configuration_phase(options) # type: ignore[arg-type]
305
+
306
+ if not await self._execute_cleaning_phase_async(options):
307
+ self.session.fail_task("workflow", "Cleaning phase failed")
308
+ return False
309
+
310
+ iteration_success = await self._run_iterative_quality_improvement(
311
+ options, max_iterations
312
+ )
313
+ if not iteration_success:
314
+ return False
315
+
316
+ return await self._run_final_workflow_phases(options)
317
+
318
+ async def _run_iterative_quality_improvement(
319
+ self, options: OptionsProtocol, max_iterations: int
320
+ ) -> bool:
321
+ for iteration in range(1, max_iterations + 1):
322
+ self.console.print(f"\n🔄 Iteration {iteration}/{max_iterations}")
323
+
324
+ try:
325
+ iteration_result = await self.timeout_manager.with_timeout(
326
+ "workflow_iteration",
327
+ self._execute_single_iteration(options, iteration),
328
+ strategy=TimeoutStrategy.GRACEFUL_DEGRADATION,
329
+ )
330
+
331
+ if iteration_result == "success":
332
+ self.console.print("✅ All quality checks passed !")
333
+ return True
334
+ elif iteration_result == "failed":
335
+ return False
336
+
337
+ except Exception as e:
338
+ self.logger.error(f"Iteration {iteration} failed with error: {e}")
339
+ self.console.print(f"⚠️ Iteration {iteration} failed: {e}")
340
+
341
+ if iteration == max_iterations:
342
+ return False
343
+
344
+ self.console.print(
345
+ f"❌ Failed to achieve code quality after {max_iterations} iterations"
346
+ )
347
+ self.session.fail_task("workflow", f"Failed after {max_iterations} iterations")
348
+ return False
349
+
350
+ async def _execute_single_iteration(
351
+ self, options: OptionsProtocol, iteration: int
352
+ ) -> str:
353
+ fast_hooks_success = await self._run_fast_hooks_with_retry_async(options)
354
+
355
+ test_issues = await self._collect_test_issues_async(options)
356
+ hook_issues = await self._collect_comprehensive_hook_issues_async(options)
357
+
358
+ if fast_hooks_success and not test_issues and not hook_issues:
359
+ return "success"
360
+
361
+ if test_issues or hook_issues:
362
+ fix_success = await self._apply_ai_fixes_async(
363
+ options, test_issues, hook_issues, iteration
364
+ )
365
+ if not fix_success:
366
+ self.console.print(f"❌ AI fixing failed in iteration {iteration}")
367
+ self.session.fail_task(
368
+ "workflow", f"AI fixing failed in iteration {iteration}"
369
+ )
370
+ return "failed"
371
+
372
+ return "continue"
373
+
374
+ def _parse_issues_for_agents(
375
+ self, test_issues: list[str], hook_issues: list[str]
376
+ ) -> list[Issue]:
377
+ structured_issues = []
378
+
379
+ for issue in hook_issues:
380
+ parsed_issue = self._parse_single_hook_issue(issue)
381
+ structured_issues.append(parsed_issue)
382
+
383
+ for issue in test_issues:
384
+ parsed_issue = self._parse_single_test_issue(issue)
385
+ structured_issues.append(parsed_issue)
386
+
387
+ return structured_issues
388
+
389
+ def _parse_single_hook_issue(self, issue: str) -> Issue:
390
+ from crackerjack.agents.base import IssueType, Priority
391
+
392
+ if "refurb: " in issue and "[FURB" in issue:
393
+ return self._parse_refurb_issue(issue)
394
+
395
+ hook_type_mapping = {
396
+ "pyright: ": (IssueType.TYPE_ERROR, Priority.HIGH, "pyright"),
397
+ "Type error": (IssueType.TYPE_ERROR, Priority.HIGH, "pyright"),
398
+ "bandit: ": (IssueType.SECURITY, Priority.HIGH, "bandit"),
399
+ "vulture: ": (IssueType.DEAD_CODE, Priority.MEDIUM, "vulture"),
400
+ "complexipy: ": (IssueType.COMPLEXITY, Priority.MEDIUM, "complexipy"),
401
+ }
402
+
403
+ for keyword, (issue_type, priority, stage) in hook_type_mapping.items():
404
+ if keyword in issue:
405
+ return self._create_generic_issue(issue, issue_type, priority, stage)
406
+
407
+ return self._create_generic_issue(
408
+ issue, IssueType.FORMATTING, Priority.MEDIUM, "hook"
409
+ )
410
+
411
+ def _parse_refurb_issue(self, issue: str) -> Issue:
412
+ import re
413
+ import uuid
414
+
415
+ from crackerjack.agents.base import Issue, IssueType, Priority
416
+
417
+ match = re.search(
418
+ r"refurb: \s *(.+?): (\d +): (\d +)\s +\[(\w +)\]: \s *(.+)", issue
419
+ )
420
+ if match:
421
+ file_path, line_num, _, error_code, message = match.groups()
422
+ return Issue(
423
+ id=str(uuid.uuid4()),
424
+ type=IssueType.FORMATTING,
425
+ severity=Priority.MEDIUM,
426
+ message=f"[{error_code}] {message}",
427
+ file_path=file_path,
428
+ line_number=int(line_num),
429
+ details=[issue],
430
+ stage="refurb",
431
+ )
432
+
433
+ return self._create_generic_issue(
434
+ issue, IssueType.FORMATTING, Priority.MEDIUM, "refurb"
435
+ )
436
+
437
+ @staticmethod
438
+ def _parse_single_test_issue(issue: str) -> Issue:
439
+ import uuid
440
+
441
+ from crackerjack.agents.base import Issue, IssueType, Priority
442
+
443
+ if "FAILED" in issue or "ERROR" in issue:
444
+ severity = Priority.HIGH
445
+ else:
446
+ severity = Priority.MEDIUM
447
+
448
+ return Issue(
449
+ id=str(uuid.uuid4()),
450
+ type=IssueType.TEST_FAILURE,
451
+ severity=severity,
452
+ message=issue,
453
+ details=[issue],
454
+ stage="test",
455
+ )
456
+
457
+ @staticmethod
458
+ def _create_generic_issue(
459
+ issue: str, issue_type: IssueType, priority: Priority, stage: str
460
+ ) -> Issue:
461
+ import uuid
462
+
463
+ from crackerjack.agents.base import Issue
464
+
465
+ return Issue(
466
+ id=str(uuid.uuid4()),
467
+ type=issue_type,
468
+ severity=priority,
469
+ message=issue,
470
+ details=[issue],
471
+ stage=stage,
472
+ )
473
+
474
+ async def _run_final_workflow_phases(self, options: OptionsProtocol) -> bool:
475
+ if not self.phases.run_publishing_phase(options): # type: ignore[arg-type]
476
+ self.session.fail_task("workflow", "Publishing failed")
477
+ return False
478
+
479
+ if not self.phases.run_commit_phase(options): # type: ignore[arg-type]
480
+ self.session.fail_task("workflow", "Commit failed")
481
+ return False
482
+
483
+ return True
484
+
485
+ async def _run_fast_hooks_with_retry_async(self, options: OptionsProtocol) -> bool:
486
+ return await asyncio.to_thread(self.phases.run_fast_hooks_only, options) # type: ignore[arg-type]
487
+
488
+ async def _collect_test_issues_async(self, options: OptionsProtocol) -> list[str]:
489
+ if not options.test:
490
+ return []
491
+
492
+ try:
493
+ success = await self.timeout_manager.with_timeout(
494
+ "test_execution",
495
+ self._run_testing_phase_async(options),
496
+ strategy=TimeoutStrategy.GRACEFUL_DEGRADATION,
497
+ )
498
+ if success:
499
+ return []
500
+ else:
501
+ test_failures = self.phases.test_manager.get_test_failures()
502
+ if test_failures:
503
+ return [f"Test failure: {failure}" for failure in test_failures]
504
+ else:
505
+ return ["Test failures detected-see logs for details"]
506
+ except Exception as e:
507
+ return [f"Test execution error: {e}"]
508
+
509
+ async def _collect_comprehensive_hook_issues_async(
510
+ self, options: OptionsProtocol
511
+ ) -> list[str]:
512
+ try:
513
+ hook_results = await self.timeout_manager.with_timeout(
514
+ "comprehensive_hooks",
515
+ asyncio.to_thread(self.phases.hook_manager.run_comprehensive_hooks), # type: ignore[arg-type]
516
+ strategy=TimeoutStrategy.GRACEFUL_DEGRADATION,
517
+ )
518
+
519
+ all_issues = []
520
+ for result in hook_results:
521
+ if (
522
+ result.status in ("failed", "error", "timeout")
523
+ and result.issues_found
524
+ ):
525
+ hook_context = f"{result.name}: "
526
+ for issue in result.issues_found:
527
+ all_issues.append(hook_context + issue)
528
+
529
+ return all_issues
530
+
531
+ except Exception as e:
532
+ return [f"Comprehensive hooks error: {e}"]
533
+
534
+ async def _apply_ai_fixes_async(
535
+ self,
536
+ options: OptionsProtocol,
537
+ test_issues: list[str],
538
+ hook_issues: list[str],
539
+ iteration: int,
540
+ ) -> bool:
541
+ all_issues = test_issues + hook_issues
542
+ if not all_issues:
543
+ return True
544
+
545
+ self.console.print(
546
+ f"🔧 Applying AI fixes for {len(all_issues)} issues in iteration {iteration}"
547
+ )
548
+
549
+ try:
550
+ result = await self.timeout_manager.with_timeout(
551
+ "ai_agent_processing",
552
+ self._execute_ai_fix_workflow(test_issues, hook_issues, iteration),
553
+ strategy=TimeoutStrategy.GRACEFUL_DEGRADATION,
554
+ )
555
+ return bool(result)
556
+ except Exception as e:
557
+ return self._handle_ai_fix_error(e)
558
+
559
+ async def _execute_ai_fix_workflow(
560
+ self, test_issues: list[str], hook_issues: list[str], iteration: int
561
+ ) -> bool:
562
+ structured_issues = self._parse_issues_for_agents(test_issues, hook_issues)
563
+
564
+ if not structured_issues:
565
+ self.console.print("⚠️ No actionable issues found for AI agents")
566
+ return True
567
+
568
+ coordinator = self._create_agent_coordinator()
569
+
570
+ fix_result = await self.timeout_manager.with_timeout(
571
+ "ai_agent_processing",
572
+ coordinator.handle_issues(structured_issues),
573
+ strategy=TimeoutStrategy.GRACEFUL_DEGRADATION,
574
+ )
575
+
576
+ self._report_fix_results(fix_result, iteration)
577
+ return bool(fix_result.success if fix_result else False)
578
+
579
+ def _create_agent_coordinator(self) -> t.Any:
580
+ from crackerjack.agents.base import AgentContext
581
+ from crackerjack.agents.enhanced_coordinator import create_enhanced_coordinator
582
+
583
+ context = AgentContext(project_path=self.pkg_path)
584
+ # Use enhanced coordinator with Claude Code agent integration
585
+ return create_enhanced_coordinator(context=context, enable_external_agents=True)
586
+
587
+ def _report_fix_results(self, fix_result: FixResult, iteration: int) -> None:
588
+ if fix_result.success:
589
+ self._report_successful_fixes(fix_result, iteration)
590
+ else:
591
+ self._report_failed_fixes(fix_result, iteration)
592
+
593
+ def _report_successful_fixes(self, fix_result: FixResult, iteration: int) -> None:
594
+ self.console.print(f"✅ AI fixes applied successfully in iteration {iteration}")
595
+ if fix_result.fixes_applied:
596
+ self.console.print(f" Applied {len(fix_result.fixes_applied)} fixes")
597
+
598
+ def _report_failed_fixes(self, fix_result: FixResult, iteration: int) -> None:
599
+ self.console.print(f"⚠️ Some AI fixes failed in iteration {iteration}")
600
+ if fix_result.remaining_issues:
601
+ for error in fix_result.remaining_issues[:3]:
602
+ self.console.print(f" Error: {error}")
603
+
604
+ def _handle_ai_fix_error(self, error: Exception) -> bool:
605
+ self.logger.error(f"AI fixing failed: {error}")
606
+ self.console.print(f"❌ AI agent system error: {error}")
607
+ return False
608
+
609
+
610
+ class AsyncWorkflowOrchestrator:
611
+ @depends.inject
612
+ def __init__(
613
+ self,
614
+ logger: Inject[Logger],
615
+ console: Inject[Console],
616
+ pkg_path: Path | None = None,
617
+ dry_run: bool = False,
618
+ web_job_id: str | None = None,
619
+ verbose: bool = False,
620
+ debug: bool = False,
621
+ changed_only: bool = False,
622
+ ) -> None:
623
+ # Initialize console and pkg_path first
624
+ self.console = console
625
+ self.pkg_path = pkg_path or Path.cwd()
626
+ self.dry_run = dry_run
627
+ self.web_job_id = web_job_id
628
+ self.verbose = verbose
629
+ self.debug = debug
630
+ self.changed_only = changed_only
631
+
632
+ # Configure ACB dependency injection using native patterns
633
+ from acb.depends import depends
634
+
635
+ # Register core dependencies directly with ACB
636
+ depends.set(Path, self.pkg_path)
637
+
638
+ # Import protocols for retrieving dependencies via ACB
639
+ from crackerjack.models.protocols import (
640
+ ConfigMergeServiceProtocol,
641
+ FileSystemInterface,
642
+ GitInterface,
643
+ HookManager,
644
+ PublishManager,
645
+ TestManagerProtocol,
646
+ )
647
+
648
+ # Setup services with ACB DI (reuse from WorkflowOrchestrator)
649
+ from .workflow_orchestrator import WorkflowOrchestrator
650
+
651
+ # Use a temporary orchestrator instance just for service setup
652
+ temp_orch = WorkflowOrchestrator.__new__(WorkflowOrchestrator)
653
+ temp_orch.console = self.console
654
+ temp_orch.pkg_path = self.pkg_path
655
+ temp_orch.verbose = self.verbose
656
+ temp_orch._setup_acb_services()
657
+
658
+ self._initialize_logging()
659
+
660
+ self.logger = logger
661
+
662
+ # Create coordinators - dependencies retrieved via ACB's depends.get_sync()
663
+ self.session = SessionCoordinator(self.console, self.pkg_path, self.web_job_id)
664
+ self.phases = PhaseCoordinator(
665
+ console=self.console,
666
+ pkg_path=self.pkg_path,
667
+ session=self.session,
668
+ filesystem=depends.get_sync(FileSystemInterface),
669
+ git_service=depends.get_sync(GitInterface),
670
+ hook_manager=depends.get_sync(HookManager),
671
+ test_manager=depends.get_sync(TestManagerProtocol),
672
+ publish_manager=depends.get_sync(PublishManager),
673
+ config_merge_service=depends.get_sync(ConfigMergeServiceProtocol),
674
+ )
675
+
676
+ self.async_pipeline = AsyncWorkflowPipeline(
677
+ pkg_path=self.pkg_path,
678
+ session=self.session,
679
+ phases=self.phases,
680
+ )
681
+
682
+ def _initialize_logging(self) -> None:
683
+ from crackerjack.services.log_manager import get_log_manager
684
+
685
+ log_manager = get_log_manager()
686
+ session_id = getattr(self, "web_job_id", None) or str(int(time.time()))[:8]
687
+ debug_log_file = log_manager.create_debug_log_file(session_id)
688
+
689
+ log_level = "DEBUG" if self.debug else "INFO"
690
+ self.logger.set_level(log_level)
691
+ self.logger.add_file_handler(debug_log_file)
692
+
693
+ async def run_complete_workflow_async(self, options: OptionsProtocol) -> bool:
694
+ return await self.async_pipeline.run_complete_workflow_async(options)
695
+
696
+ def run_complete_workflow(self, options: OptionsProtocol) -> bool:
697
+ return asyncio.run(self.run_complete_workflow_async(options))
698
+
699
+ def run_cleaning_phase(self, options: OptionsProtocol) -> bool:
700
+ result = self.phases.run_cleaning_phase(options) # type: ignore[arg-type]
701
+ return bool(result)
702
+
703
+ def run_fast_hooks_only(self, options: OptionsProtocol) -> bool:
704
+ result = self.phases.run_fast_hooks_only(options) # type: ignore[arg-type]
705
+ return bool(result)
706
+
707
+ def run_comprehensive_hooks_only(self, options: OptionsProtocol) -> bool:
708
+ result = self.phases.run_comprehensive_hooks_only(options) # type: ignore[arg-type]
709
+ return bool(result)
710
+
711
+ def run_hooks_phase(self, options: OptionsProtocol) -> bool:
712
+ result = self.phases.run_hooks_phase(options) # type: ignore[arg-type]
713
+ return bool(result)
714
+
715
+ def run_testing_phase(self, options: OptionsProtocol) -> bool:
716
+ result = self.phases.run_testing_phase(options) # type: ignore[arg-type]
717
+ return bool(result)
718
+
719
+ def run_publishing_phase(self, options: OptionsProtocol) -> bool:
720
+ result = self.phases.run_publishing_phase(options) # type: ignore[arg-type]
721
+ return bool(result)
722
+
723
+ def run_commit_phase(self, options: OptionsProtocol) -> bool:
724
+ result = self.phases.run_commit_phase(options) # type: ignore[arg-type]
725
+ return bool(result)
726
+
727
+ def run_configuration_phase(self, options: OptionsProtocol) -> bool:
728
+ result = self.phases.run_configuration_phase(options) # type: ignore[arg-type]
729
+ return bool(result)
730
+
731
+ def _cleanup_resources(self) -> None:
732
+ self.session.cleanup_resources()
733
+
734
+ def _register_cleanup(self, cleanup_handler: t.Callable[[], None]) -> None:
735
+ self.session.register_cleanup(cleanup_handler)
736
+
737
+ def _track_lock_file(self, lock_file_path: Path) -> None:
738
+ self.session.track_lock_file(lock_file_path)