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,585 @@
1
+ import typing as t
2
+ from contextlib import suppress
3
+ from pathlib import Path
4
+
5
+ from acb.console import Console
6
+ from acb.depends import depends
7
+
8
+ from crackerjack.config import CrackerjackSettings
9
+ from crackerjack.config.hooks import HookConfigLoader
10
+ from crackerjack.executors.hook_executor import HookExecutor
11
+ from crackerjack.executors.lsp_aware_hook_executor import LSPAwareHookExecutor
12
+ from crackerjack.executors.progress_hook_executor import ProgressHookExecutor
13
+ from crackerjack.models.task import HookResult
14
+
15
+ if t.TYPE_CHECKING:
16
+ from crackerjack.orchestration.hook_orchestrator import HookOrchestratorAdapter
17
+
18
+
19
+ class HookManagerImpl:
20
+ executor: HookExecutor | LSPAwareHookExecutor | ProgressHookExecutor
21
+
22
+ def _setup_git_service(self, use_incremental: bool, pkg_path: Path):
23
+ """Setup GitService for incremental execution."""
24
+ from crackerjack.services.git import GitService
25
+
26
+ git_service = None
27
+ if use_incremental:
28
+ git_service = GitService(self.console, pkg_path)
29
+ return git_service
30
+
31
+ def _setup_executor(
32
+ self,
33
+ pkg_path: Path,
34
+ verbose: bool,
35
+ quiet: bool,
36
+ debug: bool,
37
+ enable_lsp_optimization: bool,
38
+ enable_tool_proxy: bool,
39
+ use_incremental: bool,
40
+ git_service: t.Any,
41
+ ):
42
+ """Setup the appropriate executor based on configuration."""
43
+ if enable_lsp_optimization:
44
+ self.executor = LSPAwareHookExecutor(
45
+ self.console,
46
+ pkg_path,
47
+ verbose,
48
+ quiet,
49
+ debug,
50
+ use_tool_proxy=enable_tool_proxy,
51
+ use_incremental=use_incremental,
52
+ git_service=git_service,
53
+ )
54
+ else:
55
+ # Use HookExecutor - match what tests expect
56
+ # Pass only the expected positional arguments for test compatibility
57
+ self.executor = HookExecutor( # type: ignore[assignment]
58
+ self.console,
59
+ pkg_path,
60
+ verbose,
61
+ quiet,
62
+ )
63
+
64
+ def _load_from_project_config(
65
+ self,
66
+ config_path: Path,
67
+ enable_orchestration: bool | None,
68
+ orchestration_mode: str | None,
69
+ ) -> None:
70
+ """Load orchestration config from project .crackerjack.yaml file."""
71
+ from crackerjack.orchestration.config import OrchestrationConfig
72
+
73
+ loaded_config = OrchestrationConfig.load(config_path)
74
+ self._orchestration_config: t.Any = loaded_config # Can be either OrchestrationConfig or HookOrchestratorSettings
75
+ # Extract orchestration settings with param override
76
+ self.orchestration_enabled = (
77
+ enable_orchestration
78
+ if enable_orchestration is not None
79
+ else loaded_config.enable_orchestration
80
+ )
81
+ self.orchestration_mode = (
82
+ orchestration_mode
83
+ if orchestration_mode is not None
84
+ else loaded_config.orchestration_mode
85
+ )
86
+
87
+ def _create_default_orchestration_config(
88
+ self,
89
+ enable_orchestration: bool | None,
90
+ orchestration_mode: str | None,
91
+ enable_caching: bool,
92
+ cache_backend: str,
93
+ ) -> None:
94
+ """Create default orchestration config from constructor params."""
95
+ from crackerjack.orchestration.hook_orchestrator import (
96
+ HookOrchestratorSettings,
97
+ )
98
+
99
+ self._orchestration_config = HookOrchestratorSettings(
100
+ enable_caching=enable_caching,
101
+ cache_backend=cache_backend,
102
+ )
103
+ # Default to enabled unless explicitly disabled
104
+ # Fallback chain: explicit param -> DI settings -> True (application default)
105
+ self.orchestration_enabled = (
106
+ bool(enable_orchestration)
107
+ if enable_orchestration is not None
108
+ else getattr(self._settings, "enable_orchestration", True)
109
+ )
110
+ self.orchestration_mode = (
111
+ orchestration_mode
112
+ if orchestration_mode is not None
113
+ else (self._settings.orchestration_mode or "acb")
114
+ )
115
+
116
+ def _load_orchestration_config(
117
+ self,
118
+ pkg_path: Path,
119
+ orchestration_config: t.Any,
120
+ enable_orchestration: bool | None,
121
+ orchestration_mode: str | None,
122
+ enable_caching: bool,
123
+ cache_backend: str,
124
+ ):
125
+ """Load orchestration configuration with priority."""
126
+ # Get settings from ACB dependency injection
127
+ self._settings = depends.get_sync(CrackerjackSettings)
128
+
129
+ # Load orchestration config with priority:
130
+ # 1. Explicit orchestration_config param (highest - for testing)
131
+ # 2. Project .crackerjack.yaml file (middle - for project-specific settings)
132
+ # 3. Create from constructor params + DI settings (lowest - for defaults)
133
+ if orchestration_config:
134
+ # Explicit config object provided - use its values directly
135
+ # Legacy parameters (enable_orchestration, orchestration_mode) are ignored
136
+ # when an explicit config object is provided
137
+ self._orchestration_config = orchestration_config
138
+ self.orchestration_enabled = getattr(
139
+ orchestration_config, "enable_orchestration", False
140
+ )
141
+ self.orchestration_mode = getattr(
142
+ orchestration_config, "orchestration_mode", "acb"
143
+ )
144
+ else:
145
+ config_path = pkg_path / ".crackerjack.yaml"
146
+ if config_path.exists():
147
+ self._load_from_project_config(
148
+ config_path, enable_orchestration, orchestration_mode
149
+ )
150
+ else:
151
+ self._create_default_orchestration_config(
152
+ enable_orchestration,
153
+ orchestration_mode,
154
+ enable_caching,
155
+ cache_backend,
156
+ )
157
+
158
+ def __init__(
159
+ self,
160
+ pkg_path: Path,
161
+ verbose: bool = False,
162
+ quiet: bool = False,
163
+ debug: bool = False,
164
+ enable_lsp_optimization: bool = False,
165
+ enable_tool_proxy: bool = True,
166
+ use_incremental: bool = False,
167
+ # Legacy parameters kept for backward compatibility (deprecated)
168
+ orchestration_config: t.Any = None,
169
+ enable_orchestration: bool | None = None,
170
+ orchestration_mode: str | None = None,
171
+ enable_caching: bool = True,
172
+ cache_backend: str = "memory",
173
+ console: t.Any = None, # Accept console parameter for DI
174
+ ) -> None:
175
+ self.pkg_path = pkg_path
176
+ self.debug = debug
177
+
178
+ # Use provided console or get from DI
179
+ self.console = console or depends.get_sync(Console)
180
+
181
+ # Get GitService for incremental execution
182
+ git_service = self._setup_git_service(use_incremental, pkg_path)
183
+
184
+ # Use LSP-aware executor if optimization is enabled
185
+ self._setup_executor(
186
+ pkg_path,
187
+ verbose,
188
+ quiet,
189
+ debug,
190
+ enable_lsp_optimization,
191
+ enable_tool_proxy,
192
+ use_incremental,
193
+ git_service,
194
+ )
195
+
196
+ self.config_loader = HookConfigLoader()
197
+ self._config_path: Path | None = None
198
+ self.lsp_optimization_enabled = enable_lsp_optimization
199
+ self.tool_proxy_enabled = enable_tool_proxy
200
+
201
+ self._load_orchestration_config(
202
+ pkg_path,
203
+ orchestration_config,
204
+ enable_orchestration,
205
+ orchestration_mode,
206
+ enable_caching,
207
+ cache_backend,
208
+ )
209
+
210
+ self._orchestrator: HookOrchestratorAdapter | None = None
211
+
212
+ def set_config_path(self, config_path: Path) -> None:
213
+ self._config_path = config_path
214
+
215
+ async def _init_orchestrator(self) -> None:
216
+ """Initialize orchestrator if not already initialized."""
217
+ if self._orchestrator is not None:
218
+ return # Already initialized
219
+
220
+ from crackerjack.orchestration.hook_orchestrator import (
221
+ HookOrchestratorAdapter,
222
+ HookOrchestratorSettings,
223
+ )
224
+
225
+ # Create orchestrator settings from orchestration config
226
+ # Handle both OrchestrationConfig (uses orchestration_mode) and
227
+ # HookOrchestratorSettings (uses execution_mode)
228
+ execution_mode = getattr(
229
+ self._orchestration_config,
230
+ "execution_mode",
231
+ getattr(self._orchestration_config, "orchestration_mode", "acb"),
232
+ )
233
+
234
+ orchestrator_settings = HookOrchestratorSettings(
235
+ execution_mode=execution_mode,
236
+ enable_caching=self._orchestration_config.enable_caching,
237
+ cache_backend=self._orchestration_config.cache_backend,
238
+ max_parallel_hooks=self._orchestration_config.max_parallel_hooks,
239
+ enable_adaptive_execution=getattr(
240
+ self._orchestration_config, "enable_adaptive_execution", True
241
+ ),
242
+ )
243
+
244
+ self._orchestrator = HookOrchestratorAdapter(
245
+ settings=orchestrator_settings,
246
+ hook_executor=self.executor, # Provide executor for legacy mode fallback
247
+ )
248
+
249
+ await self._orchestrator.init()
250
+
251
+ async def _run_fast_hooks_orchestrated(self) -> list[HookResult]:
252
+ """Run fast hooks using orchestrator (async path)."""
253
+ await self._init_orchestrator()
254
+ assert self._orchestrator is not None
255
+
256
+ strategy = self.config_loader.load_strategy("fast")
257
+
258
+ if self._config_path:
259
+ for hook in strategy.hooks:
260
+ hook.config_path = self._config_path
261
+
262
+ # Check for progress callback from PhaseCoordinator
263
+ getattr(self, "_progress_callback", None)
264
+
265
+ return await self._orchestrator.execute_strategy(
266
+ strategy,
267
+ progress_callback=getattr(self, "_progress_callback", None),
268
+ progress_start_callback=getattr(self, "_progress_start_callback", None),
269
+ )
270
+
271
+ async def _run_comprehensive_hooks_orchestrated(self) -> list[HookResult]:
272
+ """Run comprehensive hooks using orchestrator (async path)."""
273
+ await self._init_orchestrator()
274
+ assert self._orchestrator is not None
275
+
276
+ strategy = self.config_loader.load_strategy("comprehensive")
277
+
278
+ if self._config_path:
279
+ for hook in strategy.hooks:
280
+ hook.config_path = self._config_path
281
+
282
+ # Check for progress callback from PhaseCoordinator
283
+ getattr(self, "_progress_callback", None)
284
+
285
+ return await self._orchestrator.execute_strategy(
286
+ strategy,
287
+ progress_callback=getattr(self, "_progress_callback", None),
288
+ progress_start_callback=getattr(self, "_progress_start_callback", None),
289
+ )
290
+
291
+ def run_fast_hooks(self) -> list[HookResult]:
292
+ # Use orchestrator if enabled (Phase 3+)
293
+ if self.orchestration_enabled:
294
+ import asyncio
295
+
296
+ # Check if we're already in an event loop (e.g., during testing)
297
+ try:
298
+ asyncio.get_running_loop()
299
+ # We're in an event loop, run in thread
300
+ import concurrent.futures
301
+
302
+ # Let executor show progress - orchestrator doesn't display progress
303
+ with concurrent.futures.ThreadPoolExecutor() as executor:
304
+ future = executor.submit(
305
+ asyncio.run, self._run_fast_hooks_orchestrated()
306
+ )
307
+ return future.result()
308
+ except RuntimeError:
309
+ # No event loop running, safe to use asyncio.run()
310
+ return asyncio.run(self._run_fast_hooks_orchestrated())
311
+
312
+ # Legacy executor path (Phase 1-2)
313
+ strategy = self.config_loader.load_strategy("fast")
314
+
315
+ if self._config_path:
316
+ for hook in strategy.hooks:
317
+ hook.config_path = self._config_path
318
+ # Wire progress callbacks for legacy executor path so ticks update
319
+ with suppress(Exception):
320
+ self.executor.set_progress_callbacks(
321
+ started_cb=getattr(self, "_progress_start_callback", None),
322
+ completed_cb=getattr(self, "_progress_callback", None),
323
+ total=len(strategy.hooks),
324
+ )
325
+ execution_result = self.executor.execute_strategy(strategy)
326
+ return execution_result.results
327
+
328
+ def run_comprehensive_hooks(self) -> list[HookResult]:
329
+ # Use orchestrator if enabled (Phase 3+)
330
+ if self.orchestration_enabled:
331
+ import asyncio
332
+
333
+ # Check if we're already in an event loop (e.g., during testing)
334
+ try:
335
+ asyncio.get_running_loop()
336
+ # We're in an event loop, run in thread
337
+ import concurrent.futures
338
+
339
+ # Let executor show progress - orchestrator doesn't display progress
340
+ with concurrent.futures.ThreadPoolExecutor() as executor:
341
+ future = executor.submit(
342
+ asyncio.run, self._run_comprehensive_hooks_orchestrated()
343
+ )
344
+ return future.result()
345
+ except RuntimeError:
346
+ # No event loop running, safe to use asyncio.run()
347
+ return asyncio.run(self._run_comprehensive_hooks_orchestrated())
348
+
349
+ # Legacy executor path (Phase 1-2)
350
+ strategy = self.config_loader.load_strategy("comprehensive")
351
+
352
+ if self._config_path:
353
+ for hook in strategy.hooks:
354
+ hook.config_path = self._config_path
355
+ # Wire progress callbacks for legacy executor path so ticks update
356
+ with suppress(Exception):
357
+ self.executor.set_progress_callbacks(
358
+ started_cb=getattr(self, "_progress_start_callback", None),
359
+ completed_cb=getattr(self, "_progress_callback", None),
360
+ total=len(strategy.hooks),
361
+ )
362
+ execution_result = self.executor.execute_strategy(strategy)
363
+ return execution_result.results
364
+
365
+ async def _run_hooks_parallel(self) -> list[HookResult]:
366
+ """Run fast and comprehensive strategies in parallel (async helper)."""
367
+ import asyncio
368
+
369
+ fast_task = self._run_fast_hooks_orchestrated()
370
+ comp_task = self._run_comprehensive_hooks_orchestrated()
371
+
372
+ fast_results, comp_results = await asyncio.gather(fast_task, comp_task)
373
+ return fast_results + comp_results
374
+
375
+ def run_hooks(self) -> list[HookResult]:
376
+ # Phase 5-7: Enable strategy-level parallelism when orchestration is enabled
377
+ # Use config's enable_strategy_parallelism setting (defaults to True if not set)
378
+ enable_parallelism = getattr(
379
+ self._orchestration_config, "enable_strategy_parallelism", True
380
+ )
381
+ if self.orchestration_enabled and enable_parallelism:
382
+ import asyncio
383
+
384
+ # Check if we're already in an event loop (e.g., during testing)
385
+ try:
386
+ asyncio.get_running_loop()
387
+ # We're in an event loop, use nest_asyncio or run in thread
388
+ import concurrent.futures
389
+
390
+ with concurrent.futures.ThreadPoolExecutor() as executor:
391
+ future = executor.submit(asyncio.run, self._run_hooks_parallel())
392
+ return future.result()
393
+ except RuntimeError:
394
+ # No event loop running, safe to use asyncio.run()
395
+ return asyncio.run(self._run_hooks_parallel())
396
+
397
+ # Legacy path: Sequential execution (backward compatibility)
398
+ fast_results = self.run_fast_hooks()
399
+ comprehensive_results = self.run_comprehensive_hooks()
400
+ return fast_results + comprehensive_results
401
+
402
+ def configure_lsp_optimization(self, enable: bool) -> None:
403
+ """Enable or disable LSP optimization by switching executors."""
404
+ if enable == self.lsp_optimization_enabled:
405
+ return # Already in the correct state
406
+
407
+ # Switch executor based on the enable flag
408
+ if enable:
409
+ self.executor = LSPAwareHookExecutor( # type: ignore[assignment]
410
+ self.console,
411
+ self.pkg_path,
412
+ verbose=getattr(self.executor, "verbose", False),
413
+ quiet=getattr(self.executor, "quiet", True),
414
+ use_tool_proxy=self.tool_proxy_enabled,
415
+ )
416
+ else:
417
+ self.executor = HookExecutor( # type: ignore[assignment]
418
+ self.console,
419
+ self.pkg_path,
420
+ verbose=getattr(self.executor, "verbose", False),
421
+ quiet=getattr(self.executor, "quiet", True),
422
+ )
423
+
424
+ self.lsp_optimization_enabled = enable
425
+
426
+ # Restore config path if it was set[t.Any]
427
+ if self._config_path:
428
+ # Config path is set[t.Any] at the manager level, not executor level
429
+ pass
430
+
431
+ def configure_tool_proxy(self, enable: bool) -> None:
432
+ """Enable or disable tool proxy resilience."""
433
+ if enable == self.tool_proxy_enabled:
434
+ return # Already in the correct state
435
+
436
+ self.tool_proxy_enabled = enable
437
+
438
+ # If using LSP-aware executor, recreate it with new tool proxy setting
439
+ if isinstance(self.executor, LSPAwareHookExecutor):
440
+ self.executor = LSPAwareHookExecutor(
441
+ self.console,
442
+ self.pkg_path,
443
+ verbose=getattr(self.executor, "verbose", False),
444
+ quiet=getattr(self.executor, "quiet", True),
445
+ use_tool_proxy=enable,
446
+ )
447
+
448
+ # Restore config path if it was set[t.Any]
449
+ if self._config_path:
450
+ pass # Config path handled at manager level
451
+
452
+ async def get_orchestration_stats(self) -> dict[str, t.Any] | None:
453
+ """Get orchestration statistics if orchestrator is initialized.
454
+
455
+ Returns:
456
+ Dictionary with orchestration stats, or None if orchestration disabled
457
+ """
458
+ if not self.orchestration_enabled or self._orchestrator is None:
459
+ return None
460
+
461
+ return await self._orchestrator.get_cache_stats()
462
+
463
+ def get_execution_info(self) -> dict[str, t.Any]:
464
+ """Get information about current execution mode and capabilities."""
465
+ info = {
466
+ "lsp_optimization_enabled": self.lsp_optimization_enabled,
467
+ "tool_proxy_enabled": self.tool_proxy_enabled,
468
+ "executor_type": type(self.executor).__name__,
469
+ # Use instance properties which may override settings via constructor params
470
+ "orchestration_enabled": self.orchestration_enabled,
471
+ "orchestration_mode": (
472
+ self.orchestration_mode if self.orchestration_enabled else None
473
+ ),
474
+ "caching_enabled": (
475
+ self._orchestration_config.enable_caching
476
+ if self.orchestration_enabled
477
+ else False
478
+ ),
479
+ "cache_backend": (
480
+ self._orchestration_config.cache_backend
481
+ if self.orchestration_enabled
482
+ else None
483
+ ),
484
+ }
485
+
486
+ # Get LSP-specific info if available
487
+ if hasattr(self.executor, "get_execution_mode_summary"):
488
+ info.update(self.executor.get_execution_mode_summary())
489
+
490
+ return info
491
+
492
+ @staticmethod
493
+ def validate_hooks_config() -> bool:
494
+ """Validate hooks configuration.
495
+
496
+ Phase 8.5: This method is deprecated. Direct tool invocation doesn't require
497
+ pre-commit config validation. Always returns True for backward compatibility.
498
+ """
499
+ return True
500
+
501
+ def get_hook_ids(self) -> list[str]:
502
+ fast_strategy = self.config_loader.load_strategy("fast")
503
+ comprehensive_strategy = self.config_loader.load_strategy("comprehensive")
504
+
505
+ all_hooks = fast_strategy.hooks + comprehensive_strategy.hooks
506
+ return [hook.name for hook in all_hooks]
507
+
508
+ def get_hook_count(self, suite_name: str) -> int:
509
+ """Get the number of hooks in a specific suite.
510
+
511
+ Args:
512
+ suite_name: Name of the suite ('fast' or 'comprehensive')
513
+
514
+ Returns:
515
+ Number of hooks in the suite
516
+ """
517
+ strategy = self.config_loader.load_strategy(suite_name)
518
+ return len(strategy.hooks)
519
+
520
+ def install_hooks(self) -> bool:
521
+ """Install git hooks.
522
+
523
+ Phase 8.5: This method is deprecated. Direct tool invocation doesn't require
524
+ pre-commit hook installation. Returns True with informational message.
525
+ """
526
+ self.console.print(
527
+ "[yellow]ℹ️[/yellow] Hook installation not required with direct invocation"
528
+ )
529
+ return True
530
+
531
+ def update_hooks(self) -> bool:
532
+ """Update hooks to latest versions.
533
+
534
+ Phase 8.5: This method is deprecated. Direct tool invocation uses UV for
535
+ dependency management. Returns True with informational message.
536
+ """
537
+ self.console.print(
538
+ "[yellow]ℹ️[/yellow] Hook updates managed via UV dependency resolution"
539
+ )
540
+ return True
541
+
542
+ @staticmethod
543
+ def get_hook_summary(
544
+ results: list[HookResult], elapsed_time: float | None = None
545
+ ) -> dict[str, t.Any]:
546
+ """Calculate summary statistics for hook execution results.
547
+
548
+ Args:
549
+ results: List of hook execution results
550
+ elapsed_time: Optional wall-clock elapsed time in seconds.
551
+ If provided, used as total_duration (critical for parallel execution).
552
+ If None, falls back to sum of individual durations (sequential mode).
553
+
554
+ Returns:
555
+ Dictionary with execution statistics
556
+ """
557
+ if not results:
558
+ return {
559
+ "total": 0,
560
+ "passed": 0,
561
+ "failed": 0,
562
+ "errors": 0,
563
+ "total_duration": 0,
564
+ "success_rate": 0,
565
+ }
566
+
567
+ passed = sum(1 for r in results if r.status == "passed")
568
+ failed = sum(1 for r in results if r.status == "failed")
569
+ errors = sum(1 for r in results if r.status in ("timeout", "error"))
570
+
571
+ # Use wall-clock time if provided (parallel execution), else sum durations (sequential)
572
+ total_duration = (
573
+ elapsed_time
574
+ if elapsed_time is not None
575
+ else sum(r.duration for r in results)
576
+ )
577
+
578
+ return {
579
+ "total": len(results),
580
+ "passed": passed,
581
+ "failed": failed,
582
+ "errors": errors,
583
+ "total_duration": total_duration,
584
+ "success_rate": (passed / len(results)) * 100 if results else 0,
585
+ }