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,180 @@
1
+ import logging
2
+ import typing as t
3
+ from pathlib import Path
4
+
5
+ from acb.console import Console
6
+ from acb.depends import Inject, depends
7
+
8
+ from crackerjack.agents.base import Issue, IssueType, Priority
9
+ from crackerjack.agents.test_creation_agent import TestCreationAgent
10
+ from crackerjack.services.coverage_ratchet import CoverageRatchetService
11
+
12
+
13
+ class CoverageImprovementOrchestrator:
14
+ @depends.inject # type: ignore[misc]
15
+ def __init__(self, project_path: Path, console: Inject[Console]) -> None:
16
+ self.project_path = project_path
17
+ self.logger = logging.getLogger(__name__)
18
+ self.console = console
19
+ self.coverage_service = CoverageRatchetService(project_path)
20
+ self.min_coverage_improvement = 2.0
21
+
22
+ async def should_improve_coverage(
23
+ self, current_coverage: float | None = None
24
+ ) -> bool:
25
+ try:
26
+ if current_coverage is None:
27
+ coverage_status = self.coverage_service.get_ratchet_data()
28
+ current_coverage = coverage_status.get("current_coverage", 0.0)
29
+
30
+ if current_coverage is not None and current_coverage < 100.0:
31
+ self.logger.info(
32
+ f"Coverage at {current_coverage: .1f}%-improvement recommended"
33
+ )
34
+ return True
35
+
36
+ self.logger.info("Coverage at 100 %-no improvement needed")
37
+ return False
38
+
39
+ except Exception as e:
40
+ self.logger.warning(f"Could not determine coverage status: {e}")
41
+
42
+ return True
43
+
44
+ async def create_coverage_improvement_issue(
45
+ self, coverage_gap: float | None = None
46
+ ) -> Issue:
47
+ if coverage_gap is None:
48
+ try:
49
+ coverage_status = self.coverage_service.get_ratchet_data()
50
+ current_coverage = coverage_status.get("current_coverage", 0.0)
51
+ coverage_gap = 100.0 - current_coverage
52
+ except Exception:
53
+ coverage_gap = 90.0
54
+
55
+ message = (
56
+ f"Proactive coverage improvement requested. "
57
+ f"Gap to 100 %: {coverage_gap: .1f}%. "
58
+ f"Target improvement: {min(self.min_coverage_improvement, coverage_gap) if coverage_gap is not None else self.min_coverage_improvement: .1f}%"
59
+ )
60
+
61
+ return Issue(
62
+ id="coverage_improvement_proactive",
63
+ type=IssueType.COVERAGE_IMPROVEMENT,
64
+ severity=Priority.MEDIUM,
65
+ message=message,
66
+ file_path=None,
67
+ stage="coverage_improvement",
68
+ )
69
+
70
+ async def execute_coverage_improvement(
71
+ self, agent_context: t.Any
72
+ ) -> dict[str, t.Any]:
73
+ try:
74
+ self.logger.info("Starting proactive coverage improvement")
75
+
76
+ if not await self.should_improve_coverage():
77
+ return self._create_skipped_result("Coverage improvement not needed")
78
+
79
+ issue = await self.create_coverage_improvement_issue()
80
+ test_agent = TestCreationAgent(agent_context)
81
+
82
+ confidence = await test_agent.can_handle(issue)
83
+ if confidence < 0.5:
84
+ return self._create_low_confidence_result(confidence)
85
+
86
+ fix_result = await test_agent.analyze_and_fix(issue)
87
+ result = self._create_completion_result(fix_result)
88
+
89
+ self._log_and_display_results(fix_result)
90
+ return result
91
+
92
+ except Exception as e:
93
+ return self._create_error_result(e)
94
+
95
+ def _create_skipped_result(self, reason: str) -> dict[str, t.Any]:
96
+ return {
97
+ "status": "skipped",
98
+ "reason": reason,
99
+ "coverage_at_100": True,
100
+ }
101
+
102
+ def _create_low_confidence_result(self, confidence: float) -> dict[str, t.Any]:
103
+ self.logger.warning(f"TestCreationAgent confidence too low: {confidence}")
104
+ return {
105
+ "status": "skipped",
106
+ "reason": "Agent confidence too low",
107
+ "confidence": confidence,
108
+ }
109
+
110
+ def _create_completion_result(self, fix_result: t.Any) -> dict[str, t.Any]:
111
+ return {
112
+ "status": "completed" if fix_result.success else "failed",
113
+ "confidence": fix_result.confidence,
114
+ "fixes_applied": fix_result.fixes_applied,
115
+ "files_modified": fix_result.files_modified,
116
+ "recommendations": fix_result.recommendations,
117
+ }
118
+
119
+ def _log_and_display_results(self, fix_result: t.Any) -> None:
120
+ if fix_result.success:
121
+ self.logger.info(
122
+ f"Coverage improvement successful: {len(fix_result.fixes_applied)} fixes applied"
123
+ )
124
+ if self.console:
125
+ self.console.print(
126
+ f"[green]📈[/ green] Coverage improved: {len(fix_result.fixes_applied)} "
127
+ f"tests created in {len(fix_result.files_modified)} files"
128
+ )
129
+ else:
130
+ # Log at debug level rather than warning since this is normal behavior
131
+ self.logger.debug(
132
+ "Test creation for coverage improvement was not successful"
133
+ )
134
+ if self.console:
135
+ self.console.print(
136
+ "[dim]📈 Coverage improvement: no new tests created[/dim]"
137
+ )
138
+
139
+ def _create_error_result(self, error: Exception) -> dict[str, t.Any]:
140
+ self.logger.error(f"Coverage improvement failed with error: {error}")
141
+ return {
142
+ "status": "error",
143
+ "error": str(error),
144
+ "fixes_applied": [],
145
+ "files_modified": [],
146
+ }
147
+
148
+ async def get_coverage_improvement_recommendations(self) -> list[str]:
149
+ recommendations = [
150
+ "Focus on core business logic functions first",
151
+ "Add tests for error handling and edge cases",
152
+ "Consider property-based testing for complex algorithms",
153
+ "Test integration points and configuration handling",
154
+ "Add parametrized tests for different input scenarios",
155
+ ]
156
+
157
+ from contextlib import suppress
158
+
159
+ with suppress(Exception):
160
+ coverage_status = self.coverage_service.get_ratchet_data()
161
+ current_coverage = coverage_status.get("current_coverage", 0.0)
162
+
163
+ if current_coverage < 25.0:
164
+ recommendations.insert(
165
+ 0, "Start with basic import and instantiation tests"
166
+ )
167
+ elif current_coverage < 50.0:
168
+ recommendations.insert(0, "Focus on testing public method interfaces")
169
+ elif current_coverage < 75.0:
170
+ recommendations.insert(0, "Add tests for internal helper methods")
171
+ else:
172
+ recommendations.insert(0, "Target remaining edge cases and error paths")
173
+
174
+ return recommendations
175
+
176
+
177
+ async def create_coverage_improvement_orchestrator(
178
+ project_path: Path,
179
+ ) -> CoverageImprovementOrchestrator:
180
+ return CoverageImprovementOrchestrator(project_path)
@@ -0,0 +1,361 @@
1
+ import typing as t
2
+ from dataclasses import dataclass
3
+ from enum import Enum
4
+ from pathlib import Path
5
+
6
+ from acb.console import Console
7
+
8
+ from crackerjack.config.hooks import HookStrategy
9
+ from crackerjack.models.protocols import OptionsProtocol
10
+
11
+
12
+ class ExecutionStrategy(str, Enum):
13
+ BATCH = "batch"
14
+ INDIVIDUAL = "individual"
15
+ ADAPTIVE = "adaptive"
16
+ SELECTIVE = "selective"
17
+
18
+
19
+ class ProgressLevel(str, Enum):
20
+ BASIC = "basic"
21
+ DETAILED = "detailed"
22
+ GRANULAR = "granular"
23
+ STREAMING = "streaming"
24
+
25
+
26
+ class StreamingMode(str, Enum):
27
+ WEBSOCKET = "websocket"
28
+ FILE = "file"
29
+ HYBRID = "hybrid"
30
+
31
+
32
+ class AICoordinationMode(str, Enum):
33
+ SINGLE_AGENT = "single-agent"
34
+ MULTI_AGENT = "multi-agent"
35
+ COORDINATOR = "coordinator"
36
+
37
+
38
+ class AIIntelligence(str, Enum):
39
+ BASIC = "basic"
40
+ ADAPTIVE = "adaptive"
41
+ LEARNING = "learning"
42
+
43
+
44
+ @dataclass
45
+ class OrchestrationConfig:
46
+ execution_strategy: ExecutionStrategy = ExecutionStrategy.BATCH
47
+ progress_level: ProgressLevel = ProgressLevel.BASIC
48
+ streaming_mode: StreamingMode = StreamingMode.WEBSOCKET
49
+ ai_coordination_mode: AICoordinationMode = AICoordinationMode.SINGLE_AGENT
50
+ ai_intelligence: AIIntelligence = AIIntelligence.BASIC
51
+
52
+ correlation_tracking: bool = True
53
+ failure_analysis: bool = True
54
+ intelligent_retry: bool = True
55
+
56
+ max_parallel_hooks: int = 3
57
+ max_parallel_tests: int = 4
58
+ timeout_multiplier: float = 1.0
59
+
60
+ debug_level: str = "standard"
61
+ log_individual_outputs: bool = False
62
+ preserve_temp_files: bool = False
63
+
64
+ def to_dict(self) -> dict[str, t.Any]:
65
+ return {
66
+ "execution_strategy": self.execution_strategy.value,
67
+ "progress_level": self.progress_level.value,
68
+ "streaming_mode": self.streaming_mode.value,
69
+ "ai_coordination_mode": self.ai_coordination_mode.value,
70
+ "ai_intelligence": self.ai_intelligence.value,
71
+ "correlation_tracking": self.correlation_tracking,
72
+ "failure_analysis": self.failure_analysis,
73
+ "intelligent_retry": self.intelligent_retry,
74
+ "max_parallel_hooks": self.max_parallel_hooks,
75
+ "max_parallel_tests": self.max_parallel_tests,
76
+ "timeout_multiplier": self.timeout_multiplier,
77
+ "debug_level": self.debug_level,
78
+ "log_individual_outputs": self.log_individual_outputs,
79
+ "preserve_temp_files": self.preserve_temp_files,
80
+ }
81
+
82
+
83
+ class ExecutionContext:
84
+ def __init__(
85
+ self,
86
+ pkg_path: Path,
87
+ options: OptionsProtocol,
88
+ previous_failures: list[str] | None = None,
89
+ changed_files: list[Path] | None = None,
90
+ iteration_count: int = 1,
91
+ ) -> None:
92
+ self.pkg_path = pkg_path
93
+ self.options = options
94
+ self.previous_failures = previous_failures or []
95
+ self.changed_files = changed_files or []
96
+ self.iteration_count = iteration_count
97
+
98
+ self.total_python_files = len(list[t.Any](pkg_path.rglob(" * .py")))
99
+ self.total_test_files = len(list[t.Any](pkg_path.glob("tests / test_ * .py")))
100
+ self.has_complex_setup = self._detect_complex_setup()
101
+ self.estimated_hook_duration = self._estimate_hook_duration()
102
+
103
+ def _detect_complex_setup(self) -> bool:
104
+ complex_indicators = [
105
+ (self.pkg_path / "pyproject.toml").exists(),
106
+ (self.pkg_path / "setup.py").exists(),
107
+ (self.pkg_path / "requirements.txt").exists(),
108
+ len(list[t.Any](self.pkg_path.rglob(" * .py"))) > 50,
109
+ len(list[t.Any](self.pkg_path.glob("tests / test_ * .py"))) > 20,
110
+ ]
111
+ return sum(complex_indicators) >= 3
112
+
113
+ def _estimate_hook_duration(self) -> float:
114
+ base_time = 30.0
115
+ file_factor = self.total_python_files * 0.5
116
+ test_factor = self.total_test_files * 2.0
117
+
118
+ return base_time + file_factor + test_factor
119
+
120
+ @property
121
+ def ai_agent_mode(self) -> bool:
122
+ """Check if AI agent mode is enabled."""
123
+ return getattr(self.options, "ai_agent", False)
124
+
125
+ @property
126
+ def ai_debug_mode(self) -> bool:
127
+ """Check if AI debug mode is enabled."""
128
+ return getattr(self.options, "ai_debug", False)
129
+
130
+ @property
131
+ def interactive(self) -> bool:
132
+ """Check if interactive mode is enabled."""
133
+ return getattr(self.options, "interactive", False)
134
+
135
+ @property
136
+ def working_directory(self) -> Path:
137
+ """Get the working directory path."""
138
+ return self.pkg_path
139
+
140
+
141
+ class StrategySelector:
142
+ def __init__(self, console: Console) -> None:
143
+ self.console = console
144
+
145
+ def select_strategy(
146
+ self,
147
+ config: OrchestrationConfig,
148
+ context: ExecutionContext,
149
+ ) -> ExecutionStrategy:
150
+ if config.execution_strategy != ExecutionStrategy.ADAPTIVE:
151
+ return config.execution_strategy
152
+
153
+ return self._select_adaptive_strategy(context)
154
+
155
+ def _select_adaptive_strategy(self, context: ExecutionContext) -> ExecutionStrategy:
156
+ if context.iteration_count == 1:
157
+ return ExecutionStrategy.BATCH
158
+
159
+ if len(context.previous_failures) > 5:
160
+ self.console.print(
161
+ "[yellow]🧠 Switching to individual execution due to multiple failures[/ yellow]",
162
+ )
163
+ return ExecutionStrategy.INDIVIDUAL
164
+
165
+ if context.changed_files and len(context.changed_files) < 5:
166
+ self.console.print(
167
+ "[cyan]🎯 Using selective execution for targeted file changes[/ cyan]",
168
+ )
169
+ return ExecutionStrategy.SELECTIVE
170
+
171
+ if context.has_complex_setup and context.iteration_count > 2:
172
+ return ExecutionStrategy.INDIVIDUAL
173
+
174
+ return ExecutionStrategy.BATCH
175
+
176
+ def select_hook_subset(
177
+ self,
178
+ strategy: HookStrategy,
179
+ execution_strategy: ExecutionStrategy,
180
+ context: ExecutionContext,
181
+ ) -> HookStrategy:
182
+ if execution_strategy == ExecutionStrategy.SELECTIVE:
183
+ return self._create_selective_strategy(strategy, context)
184
+
185
+ return strategy
186
+
187
+ def _create_selective_strategy(
188
+ self,
189
+ strategy: HookStrategy,
190
+ context: ExecutionContext,
191
+ ) -> HookStrategy:
192
+ priority_hooks = set[t.Any](context.previous_failures)
193
+
194
+ if context.changed_files:
195
+ for file_path in context.changed_files:
196
+ if file_path.suffix == ".py":
197
+ priority_hooks.update(["pyright", "ruff-check", "ruff-format"])
198
+ if "test" in str(file_path):
199
+ priority_hooks.update(["pytest", "coverage"])
200
+ if str(file_path).endswith(("setup.py", "pyproject.toml")):
201
+ priority_hooks.update(["bandit", "creosote", "gitleaks"])
202
+
203
+ selected_hooks = [
204
+ hook for hook in strategy.hooks if hook.name in priority_hooks
205
+ ]
206
+
207
+ if not selected_hooks:
208
+ selected_hooks = strategy.hooks[:3]
209
+
210
+ self.console.print(
211
+ f"[cyan]🎯 Selected {len(selected_hooks)} hooks for targeted execution: "
212
+ f"{', '.join(h.name for h in selected_hooks)}[/ cyan]",
213
+ )
214
+
215
+ return HookStrategy(
216
+ name=f"{strategy.name}_selective",
217
+ hooks=selected_hooks,
218
+ timeout=strategy.timeout,
219
+ retry_policy=strategy.retry_policy,
220
+ parallel=strategy.parallel,
221
+ max_workers=min(strategy.max_workers, len(selected_hooks)),
222
+ )
223
+
224
+
225
+ class OrchestrationPlanner:
226
+ def __init__(self, console: Console) -> None:
227
+ self.console = console
228
+ self.strategy_selector = StrategySelector(console)
229
+
230
+ def create_execution_plan(
231
+ self,
232
+ config: OrchestrationConfig,
233
+ context: ExecutionContext,
234
+ hook_strategies: list[HookStrategy],
235
+ ) -> "ExecutionPlan":
236
+ execution_strategy = self.strategy_selector.select_strategy(config, context)
237
+
238
+ hook_plans = []
239
+ for strategy in hook_strategies:
240
+ selected_strategy = self.strategy_selector.select_hook_subset(
241
+ strategy,
242
+ execution_strategy,
243
+ context,
244
+ )
245
+ hook_plans.append(
246
+ {
247
+ "strategy": selected_strategy,
248
+ "execution_mode": execution_strategy,
249
+ "estimated_duration": self._estimate_strategy_duration(
250
+ selected_strategy,
251
+ ),
252
+ },
253
+ )
254
+
255
+ test_plan = self._create_test_plan(config, context, execution_strategy)
256
+
257
+ ai_plan = self._create_ai_plan(config, context)
258
+
259
+ return ExecutionPlan(
260
+ config=config,
261
+ execution_strategy=execution_strategy,
262
+ hook_plans=hook_plans,
263
+ test_plan=test_plan,
264
+ ai_plan=ai_plan,
265
+ estimated_total_duration=float(
266
+ sum(int(float(str(plan["estimated_duration"]))) for plan in hook_plans)
267
+ )
268
+ + float(test_plan["estimated_duration"]),
269
+ )
270
+
271
+ def _estimate_strategy_duration(self, strategy: HookStrategy) -> float:
272
+ base_time_per_hook = 10.0
273
+ return len(strategy.hooks) * base_time_per_hook
274
+
275
+ def _create_test_plan(
276
+ self,
277
+ config: OrchestrationConfig,
278
+ context: ExecutionContext,
279
+ execution_strategy: ExecutionStrategy,
280
+ ) -> dict[str, t.Any]:
281
+ if execution_strategy == ExecutionStrategy.INDIVIDUAL:
282
+ test_mode = "individual_with_progress"
283
+ elif execution_strategy == ExecutionStrategy.SELECTIVE:
284
+ test_mode = "selective"
285
+ else:
286
+ test_mode = "full_suite"
287
+
288
+ return {
289
+ "mode": test_mode,
290
+ "parallel_workers": min(
291
+ config.max_parallel_tests,
292
+ context.total_test_files,
293
+ ),
294
+ "estimated_duration": context.total_test_files * 2.0,
295
+ "progress_tracking": config.progress_level
296
+ in (ProgressLevel.DETAILED, ProgressLevel.GRANULAR),
297
+ }
298
+
299
+ def _create_ai_plan(
300
+ self,
301
+ config: OrchestrationConfig,
302
+ context: ExecutionContext,
303
+ ) -> dict[str, t.Any]:
304
+ return {
305
+ "mode": config.ai_coordination_mode,
306
+ "intelligence_level": config.ai_intelligence,
307
+ "batch_processing": True,
308
+ "correlation_tracking": config.correlation_tracking,
309
+ "failure_analysis": config.failure_analysis,
310
+ "adaptive_retry": config.intelligent_retry,
311
+ }
312
+
313
+
314
+ @dataclass
315
+ class ExecutionPlan:
316
+ config: OrchestrationConfig
317
+ execution_strategy: ExecutionStrategy
318
+ hook_plans: list[dict[str, t.Any]]
319
+ test_plan: dict[str, t.Any]
320
+ ai_plan: dict[str, t.Any]
321
+ estimated_total_duration: float
322
+
323
+ def print_plan_summary(self, console: Console) -> None:
324
+ console.print("\n" + "=" * 80)
325
+ console.print(
326
+ "[bold bright_blue]🎯 ORCHESTRATED EXECUTION PLAN[/ bold bright_blue]",
327
+ )
328
+ console.print("=" * 80)
329
+
330
+ console.print(f"[bold]Strategy: [/ bold] {self.execution_strategy.value}")
331
+ console.print(
332
+ f"[bold]AI Mode: [/ bold] {self.config.ai_coordination_mode.value}",
333
+ )
334
+ console.print(
335
+ f"[bold]Progress Level: [/ bold] {self.config.progress_level.value}",
336
+ )
337
+ console.print(
338
+ f"[bold]Estimated Duration: [/ bold] {self.estimated_total_duration: .1f}s",
339
+ )
340
+
341
+ console.print("\n[bold cyan]Hook Execution: [/ bold cyan]")
342
+ for i, plan in enumerate(self.hook_plans, 1):
343
+ strategy = plan["strategy"]
344
+ console.print(
345
+ f" {i}. {strategy.name}-{len(strategy.hooks)} hooks "
346
+ f"({plan['estimated_duration']: .1f}s)",
347
+ )
348
+
349
+ console.print("\n[bold green]Test Execution: [/ bold green]")
350
+ console.print(f" Mode: {self.test_plan['mode']}")
351
+ console.print(f" Workers: {self.test_plan['parallel_workers']}")
352
+ console.print(f" Duration: {self.test_plan['estimated_duration']: .1f}s")
353
+
354
+ console.print("\n[bold magenta]AI Coordination: [/ bold magenta]")
355
+ console.print(f" Mode: {self.ai_plan['mode'].value}")
356
+ console.print(f" Intelligence: {self.ai_plan['intelligence_level'].value}")
357
+ console.print(
358
+ f" Batch Processing: {'✅' if self.ai_plan['batch_processing'] else '❌'}",
359
+ )
360
+
361
+ console.print("=" * 80)