crackerjack 0.37.9__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 (425) hide show
  1. crackerjack/README.md +19 -0
  2. crackerjack/__init__.py +30 -1
  3. crackerjack/__main__.py +342 -1263
  4. crackerjack/adapters/README.md +18 -0
  5. crackerjack/adapters/__init__.py +27 -5
  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/{rust_tool_manager.py → lsp/_manager.py} +3 -3
  27. crackerjack/adapters/{skylos_adapter.py → lsp/skylos.py} +59 -7
  28. crackerjack/adapters/{zuban_adapter.py → lsp/zuban.py} +3 -6
  29. crackerjack/adapters/refactor/README.md +59 -0
  30. crackerjack/adapters/refactor/__init__.py +12 -0
  31. crackerjack/adapters/refactor/creosote.py +318 -0
  32. crackerjack/adapters/refactor/refurb.py +406 -0
  33. crackerjack/adapters/refactor/skylos.py +494 -0
  34. crackerjack/adapters/sast/README.md +132 -0
  35. crackerjack/adapters/sast/__init__.py +32 -0
  36. crackerjack/adapters/sast/_base.py +201 -0
  37. crackerjack/adapters/sast/bandit.py +423 -0
  38. crackerjack/adapters/sast/pyscn.py +405 -0
  39. crackerjack/adapters/sast/semgrep.py +241 -0
  40. crackerjack/adapters/security/README.md +111 -0
  41. crackerjack/adapters/security/__init__.py +17 -0
  42. crackerjack/adapters/security/gitleaks.py +339 -0
  43. crackerjack/adapters/type/README.md +52 -0
  44. crackerjack/adapters/type/__init__.py +12 -0
  45. crackerjack/adapters/type/pyrefly.py +402 -0
  46. crackerjack/adapters/type/ty.py +402 -0
  47. crackerjack/adapters/type/zuban.py +522 -0
  48. crackerjack/adapters/utility/README.md +51 -0
  49. crackerjack/adapters/utility/__init__.py +10 -0
  50. crackerjack/adapters/utility/checks.py +884 -0
  51. crackerjack/agents/README.md +264 -0
  52. crackerjack/agents/__init__.py +40 -12
  53. crackerjack/agents/base.py +1 -0
  54. crackerjack/agents/claude_code_bridge.py +641 -0
  55. crackerjack/agents/coordinator.py +49 -53
  56. crackerjack/agents/dry_agent.py +187 -3
  57. crackerjack/agents/enhanced_coordinator.py +279 -0
  58. crackerjack/agents/enhanced_proactive_agent.py +185 -0
  59. crackerjack/agents/error_middleware.py +53 -0
  60. crackerjack/agents/formatting_agent.py +6 -8
  61. crackerjack/agents/helpers/__init__.py +9 -0
  62. crackerjack/agents/helpers/performance/__init__.py +22 -0
  63. crackerjack/agents/helpers/performance/performance_ast_analyzer.py +357 -0
  64. crackerjack/agents/helpers/performance/performance_pattern_detector.py +909 -0
  65. crackerjack/agents/helpers/performance/performance_recommender.py +572 -0
  66. crackerjack/agents/helpers/refactoring/__init__.py +22 -0
  67. crackerjack/agents/helpers/refactoring/code_transformer.py +536 -0
  68. crackerjack/agents/helpers/refactoring/complexity_analyzer.py +344 -0
  69. crackerjack/agents/helpers/refactoring/dead_code_detector.py +437 -0
  70. crackerjack/agents/helpers/test_creation/__init__.py +19 -0
  71. crackerjack/agents/helpers/test_creation/test_ast_analyzer.py +216 -0
  72. crackerjack/agents/helpers/test_creation/test_coverage_analyzer.py +643 -0
  73. crackerjack/agents/helpers/test_creation/test_template_generator.py +1031 -0
  74. crackerjack/agents/performance_agent.py +121 -1152
  75. crackerjack/agents/refactoring_agent.py +156 -655
  76. crackerjack/agents/semantic_agent.py +479 -0
  77. crackerjack/agents/semantic_helpers.py +356 -0
  78. crackerjack/agents/test_creation_agent.py +19 -1605
  79. crackerjack/api.py +5 -7
  80. crackerjack/cli/README.md +394 -0
  81. crackerjack/cli/__init__.py +1 -1
  82. crackerjack/cli/cache_handlers.py +23 -18
  83. crackerjack/cli/cache_handlers_enhanced.py +1 -4
  84. crackerjack/cli/facade.py +70 -8
  85. crackerjack/cli/formatting.py +13 -0
  86. crackerjack/cli/handlers/__init__.py +85 -0
  87. crackerjack/cli/handlers/advanced.py +103 -0
  88. crackerjack/cli/handlers/ai_features.py +62 -0
  89. crackerjack/cli/handlers/analytics.py +479 -0
  90. crackerjack/cli/handlers/changelog.py +271 -0
  91. crackerjack/cli/handlers/config_handlers.py +16 -0
  92. crackerjack/cli/handlers/coverage.py +84 -0
  93. crackerjack/cli/handlers/documentation.py +280 -0
  94. crackerjack/cli/handlers/main_handlers.py +497 -0
  95. crackerjack/cli/handlers/monitoring.py +371 -0
  96. crackerjack/cli/handlers.py +249 -49
  97. crackerjack/cli/interactive.py +8 -5
  98. crackerjack/cli/options.py +203 -110
  99. crackerjack/cli/semantic_handlers.py +292 -0
  100. crackerjack/cli/version.py +19 -0
  101. crackerjack/code_cleaner.py +60 -24
  102. crackerjack/config/README.md +472 -0
  103. crackerjack/config/__init__.py +256 -0
  104. crackerjack/config/global_lock_config.py +191 -54
  105. crackerjack/config/hooks.py +188 -16
  106. crackerjack/config/loader.py +239 -0
  107. crackerjack/config/settings.py +141 -0
  108. crackerjack/config/tool_commands.py +331 -0
  109. crackerjack/core/README.md +393 -0
  110. crackerjack/core/async_workflow_orchestrator.py +79 -53
  111. crackerjack/core/autofix_coordinator.py +22 -9
  112. crackerjack/core/container.py +10 -9
  113. crackerjack/core/enhanced_container.py +9 -9
  114. crackerjack/core/performance.py +1 -1
  115. crackerjack/core/performance_monitor.py +5 -3
  116. crackerjack/core/phase_coordinator.py +1018 -634
  117. crackerjack/core/proactive_workflow.py +3 -3
  118. crackerjack/core/retry.py +275 -0
  119. crackerjack/core/service_watchdog.py +167 -23
  120. crackerjack/core/session_coordinator.py +187 -382
  121. crackerjack/core/timeout_manager.py +161 -44
  122. crackerjack/core/workflow/__init__.py +21 -0
  123. crackerjack/core/workflow/workflow_ai_coordinator.py +863 -0
  124. crackerjack/core/workflow/workflow_event_orchestrator.py +1107 -0
  125. crackerjack/core/workflow/workflow_issue_parser.py +714 -0
  126. crackerjack/core/workflow/workflow_phase_executor.py +1158 -0
  127. crackerjack/core/workflow/workflow_security_gates.py +400 -0
  128. crackerjack/core/workflow_orchestrator.py +1247 -953
  129. crackerjack/data/README.md +11 -0
  130. crackerjack/data/__init__.py +8 -0
  131. crackerjack/data/models.py +79 -0
  132. crackerjack/data/repository.py +210 -0
  133. crackerjack/decorators/README.md +180 -0
  134. crackerjack/decorators/__init__.py +35 -0
  135. crackerjack/decorators/error_handling.py +649 -0
  136. crackerjack/decorators/error_handling_decorators.py +334 -0
  137. crackerjack/decorators/helpers.py +58 -0
  138. crackerjack/decorators/patterns.py +281 -0
  139. crackerjack/decorators/utils.py +58 -0
  140. crackerjack/docs/README.md +11 -0
  141. crackerjack/docs/generated/api/CLI_REFERENCE.md +1 -1
  142. crackerjack/documentation/README.md +11 -0
  143. crackerjack/documentation/ai_templates.py +1 -1
  144. crackerjack/documentation/dual_output_generator.py +11 -9
  145. crackerjack/documentation/reference_generator.py +104 -59
  146. crackerjack/dynamic_config.py +52 -61
  147. crackerjack/errors.py +1 -1
  148. crackerjack/events/README.md +11 -0
  149. crackerjack/events/__init__.py +16 -0
  150. crackerjack/events/telemetry.py +175 -0
  151. crackerjack/events/workflow_bus.py +346 -0
  152. crackerjack/exceptions/README.md +301 -0
  153. crackerjack/exceptions/__init__.py +5 -0
  154. crackerjack/exceptions/config.py +4 -0
  155. crackerjack/exceptions/tool_execution_error.py +245 -0
  156. crackerjack/executors/README.md +591 -0
  157. crackerjack/executors/__init__.py +2 -0
  158. crackerjack/executors/async_hook_executor.py +539 -77
  159. crackerjack/executors/cached_hook_executor.py +3 -3
  160. crackerjack/executors/hook_executor.py +967 -102
  161. crackerjack/executors/hook_lock_manager.py +31 -22
  162. crackerjack/executors/individual_hook_executor.py +66 -32
  163. crackerjack/executors/lsp_aware_hook_executor.py +136 -57
  164. crackerjack/executors/progress_hook_executor.py +282 -0
  165. crackerjack/executors/tool_proxy.py +23 -7
  166. crackerjack/hooks/README.md +485 -0
  167. crackerjack/hooks/lsp_hook.py +8 -9
  168. crackerjack/intelligence/README.md +557 -0
  169. crackerjack/interactive.py +37 -10
  170. crackerjack/managers/README.md +369 -0
  171. crackerjack/managers/async_hook_manager.py +41 -57
  172. crackerjack/managers/hook_manager.py +449 -79
  173. crackerjack/managers/publish_manager.py +81 -36
  174. crackerjack/managers/test_command_builder.py +290 -12
  175. crackerjack/managers/test_executor.py +93 -8
  176. crackerjack/managers/test_manager.py +1082 -75
  177. crackerjack/managers/test_progress.py +118 -26
  178. crackerjack/mcp/README.md +374 -0
  179. crackerjack/mcp/cache.py +25 -2
  180. crackerjack/mcp/client_runner.py +35 -18
  181. crackerjack/mcp/context.py +9 -9
  182. crackerjack/mcp/dashboard.py +24 -8
  183. crackerjack/mcp/enhanced_progress_monitor.py +34 -23
  184. crackerjack/mcp/file_monitor.py +27 -6
  185. crackerjack/mcp/progress_components.py +45 -34
  186. crackerjack/mcp/progress_monitor.py +6 -9
  187. crackerjack/mcp/rate_limiter.py +11 -7
  188. crackerjack/mcp/server.py +2 -0
  189. crackerjack/mcp/server_core.py +187 -55
  190. crackerjack/mcp/service_watchdog.py +12 -9
  191. crackerjack/mcp/task_manager.py +2 -2
  192. crackerjack/mcp/tools/README.md +27 -0
  193. crackerjack/mcp/tools/__init__.py +2 -0
  194. crackerjack/mcp/tools/core_tools.py +75 -52
  195. crackerjack/mcp/tools/execution_tools.py +87 -31
  196. crackerjack/mcp/tools/intelligence_tools.py +2 -2
  197. crackerjack/mcp/tools/proactive_tools.py +1 -1
  198. crackerjack/mcp/tools/semantic_tools.py +584 -0
  199. crackerjack/mcp/tools/utility_tools.py +180 -132
  200. crackerjack/mcp/tools/workflow_executor.py +87 -46
  201. crackerjack/mcp/websocket/README.md +31 -0
  202. crackerjack/mcp/websocket/app.py +11 -1
  203. crackerjack/mcp/websocket/event_bridge.py +188 -0
  204. crackerjack/mcp/websocket/jobs.py +27 -4
  205. crackerjack/mcp/websocket/monitoring/__init__.py +25 -0
  206. crackerjack/mcp/websocket/monitoring/api/__init__.py +19 -0
  207. crackerjack/mcp/websocket/monitoring/api/dependencies.py +141 -0
  208. crackerjack/mcp/websocket/monitoring/api/heatmap.py +154 -0
  209. crackerjack/mcp/websocket/monitoring/api/intelligence.py +199 -0
  210. crackerjack/mcp/websocket/monitoring/api/metrics.py +203 -0
  211. crackerjack/mcp/websocket/monitoring/api/telemetry.py +101 -0
  212. crackerjack/mcp/websocket/monitoring/dashboard.py +18 -0
  213. crackerjack/mcp/websocket/monitoring/factory.py +109 -0
  214. crackerjack/mcp/websocket/monitoring/filters.py +10 -0
  215. crackerjack/mcp/websocket/monitoring/metrics.py +64 -0
  216. crackerjack/mcp/websocket/monitoring/models.py +90 -0
  217. crackerjack/mcp/websocket/monitoring/utils.py +171 -0
  218. crackerjack/mcp/websocket/monitoring/websocket_manager.py +78 -0
  219. crackerjack/mcp/websocket/monitoring/websockets/__init__.py +17 -0
  220. crackerjack/mcp/websocket/monitoring/websockets/dependencies.py +126 -0
  221. crackerjack/mcp/websocket/monitoring/websockets/heatmap.py +176 -0
  222. crackerjack/mcp/websocket/monitoring/websockets/intelligence.py +291 -0
  223. crackerjack/mcp/websocket/monitoring/websockets/metrics.py +291 -0
  224. crackerjack/mcp/websocket/monitoring_endpoints.py +16 -2930
  225. crackerjack/mcp/websocket/server.py +1 -3
  226. crackerjack/mcp/websocket/websocket_handler.py +107 -6
  227. crackerjack/models/README.md +308 -0
  228. crackerjack/models/__init__.py +10 -1
  229. crackerjack/models/config.py +639 -22
  230. crackerjack/models/config_adapter.py +6 -6
  231. crackerjack/models/protocols.py +1167 -23
  232. crackerjack/models/pydantic_models.py +320 -0
  233. crackerjack/models/qa_config.py +145 -0
  234. crackerjack/models/qa_results.py +134 -0
  235. crackerjack/models/results.py +35 -0
  236. crackerjack/models/semantic_models.py +258 -0
  237. crackerjack/models/task.py +19 -3
  238. crackerjack/models/test_models.py +60 -0
  239. crackerjack/monitoring/README.md +11 -0
  240. crackerjack/monitoring/ai_agent_watchdog.py +5 -4
  241. crackerjack/monitoring/metrics_collector.py +4 -3
  242. crackerjack/monitoring/regression_prevention.py +4 -3
  243. crackerjack/monitoring/websocket_server.py +4 -241
  244. crackerjack/orchestration/README.md +340 -0
  245. crackerjack/orchestration/__init__.py +43 -0
  246. crackerjack/orchestration/advanced_orchestrator.py +20 -67
  247. crackerjack/orchestration/cache/README.md +312 -0
  248. crackerjack/orchestration/cache/__init__.py +37 -0
  249. crackerjack/orchestration/cache/memory_cache.py +338 -0
  250. crackerjack/orchestration/cache/tool_proxy_cache.py +340 -0
  251. crackerjack/orchestration/config.py +297 -0
  252. crackerjack/orchestration/coverage_improvement.py +13 -6
  253. crackerjack/orchestration/execution_strategies.py +6 -6
  254. crackerjack/orchestration/hook_orchestrator.py +1398 -0
  255. crackerjack/orchestration/strategies/README.md +401 -0
  256. crackerjack/orchestration/strategies/__init__.py +39 -0
  257. crackerjack/orchestration/strategies/adaptive_strategy.py +630 -0
  258. crackerjack/orchestration/strategies/parallel_strategy.py +237 -0
  259. crackerjack/orchestration/strategies/sequential_strategy.py +299 -0
  260. crackerjack/orchestration/test_progress_streamer.py +1 -1
  261. crackerjack/plugins/README.md +11 -0
  262. crackerjack/plugins/hooks.py +3 -2
  263. crackerjack/plugins/loader.py +3 -3
  264. crackerjack/plugins/managers.py +1 -1
  265. crackerjack/py313.py +191 -0
  266. crackerjack/security/README.md +11 -0
  267. crackerjack/services/README.md +374 -0
  268. crackerjack/services/__init__.py +8 -21
  269. crackerjack/services/ai/README.md +295 -0
  270. crackerjack/services/ai/__init__.py +7 -0
  271. crackerjack/services/ai/advanced_optimizer.py +878 -0
  272. crackerjack/services/{contextual_ai_assistant.py → ai/contextual_ai_assistant.py} +5 -3
  273. crackerjack/services/ai/embeddings.py +444 -0
  274. crackerjack/services/ai/intelligent_commit.py +328 -0
  275. crackerjack/services/ai/predictive_analytics.py +510 -0
  276. crackerjack/services/api_extractor.py +5 -3
  277. crackerjack/services/bounded_status_operations.py +45 -5
  278. crackerjack/services/cache.py +249 -318
  279. crackerjack/services/changelog_automation.py +7 -3
  280. crackerjack/services/command_execution_service.py +305 -0
  281. crackerjack/services/config_integrity.py +83 -39
  282. crackerjack/services/config_merge.py +9 -6
  283. crackerjack/services/config_service.py +198 -0
  284. crackerjack/services/config_template.py +13 -26
  285. crackerjack/services/coverage_badge_service.py +6 -4
  286. crackerjack/services/coverage_ratchet.py +53 -27
  287. crackerjack/services/debug.py +18 -7
  288. crackerjack/services/dependency_analyzer.py +4 -4
  289. crackerjack/services/dependency_monitor.py +13 -13
  290. crackerjack/services/documentation_generator.py +4 -2
  291. crackerjack/services/documentation_service.py +62 -33
  292. crackerjack/services/enhanced_filesystem.py +81 -27
  293. crackerjack/services/enterprise_optimizer.py +1 -1
  294. crackerjack/services/error_pattern_analyzer.py +10 -10
  295. crackerjack/services/file_filter.py +221 -0
  296. crackerjack/services/file_hasher.py +5 -7
  297. crackerjack/services/file_io_service.py +361 -0
  298. crackerjack/services/file_modifier.py +615 -0
  299. crackerjack/services/filesystem.py +80 -109
  300. crackerjack/services/git.py +99 -5
  301. crackerjack/services/health_metrics.py +4 -6
  302. crackerjack/services/heatmap_generator.py +12 -3
  303. crackerjack/services/incremental_executor.py +380 -0
  304. crackerjack/services/initialization.py +101 -49
  305. crackerjack/services/log_manager.py +2 -2
  306. crackerjack/services/logging.py +120 -68
  307. crackerjack/services/lsp_client.py +12 -12
  308. crackerjack/services/memory_optimizer.py +27 -22
  309. crackerjack/services/monitoring/README.md +30 -0
  310. crackerjack/services/monitoring/__init__.py +9 -0
  311. crackerjack/services/monitoring/dependency_monitor.py +678 -0
  312. crackerjack/services/monitoring/error_pattern_analyzer.py +676 -0
  313. crackerjack/services/monitoring/health_metrics.py +716 -0
  314. crackerjack/services/monitoring/metrics.py +587 -0
  315. crackerjack/services/{performance_benchmarks.py → monitoring/performance_benchmarks.py} +100 -14
  316. crackerjack/services/{performance_cache.py → monitoring/performance_cache.py} +21 -15
  317. crackerjack/services/{performance_monitor.py → monitoring/performance_monitor.py} +10 -6
  318. crackerjack/services/parallel_executor.py +166 -55
  319. crackerjack/services/patterns/__init__.py +142 -0
  320. crackerjack/services/patterns/agents.py +107 -0
  321. crackerjack/services/patterns/code/__init__.py +15 -0
  322. crackerjack/services/patterns/code/detection.py +118 -0
  323. crackerjack/services/patterns/code/imports.py +107 -0
  324. crackerjack/services/patterns/code/paths.py +159 -0
  325. crackerjack/services/patterns/code/performance.py +119 -0
  326. crackerjack/services/patterns/code/replacement.py +36 -0
  327. crackerjack/services/patterns/core.py +212 -0
  328. crackerjack/services/patterns/documentation/__init__.py +14 -0
  329. crackerjack/services/patterns/documentation/badges_markdown.py +96 -0
  330. crackerjack/services/patterns/documentation/comments_blocks.py +83 -0
  331. crackerjack/services/patterns/documentation/docstrings.py +89 -0
  332. crackerjack/services/patterns/formatting.py +226 -0
  333. crackerjack/services/patterns/operations.py +339 -0
  334. crackerjack/services/patterns/security/__init__.py +23 -0
  335. crackerjack/services/patterns/security/code_injection.py +122 -0
  336. crackerjack/services/patterns/security/credentials.py +190 -0
  337. crackerjack/services/patterns/security/path_traversal.py +221 -0
  338. crackerjack/services/patterns/security/unsafe_operations.py +216 -0
  339. crackerjack/services/patterns/templates.py +62 -0
  340. crackerjack/services/patterns/testing/__init__.py +18 -0
  341. crackerjack/services/patterns/testing/error_patterns.py +107 -0
  342. crackerjack/services/patterns/testing/pytest_output.py +126 -0
  343. crackerjack/services/patterns/tool_output/__init__.py +16 -0
  344. crackerjack/services/patterns/tool_output/bandit.py +72 -0
  345. crackerjack/services/patterns/tool_output/other.py +97 -0
  346. crackerjack/services/patterns/tool_output/pyright.py +67 -0
  347. crackerjack/services/patterns/tool_output/ruff.py +44 -0
  348. crackerjack/services/patterns/url_sanitization.py +114 -0
  349. crackerjack/services/patterns/utilities.py +42 -0
  350. crackerjack/services/patterns/utils.py +339 -0
  351. crackerjack/services/patterns/validation.py +46 -0
  352. crackerjack/services/patterns/versioning.py +62 -0
  353. crackerjack/services/predictive_analytics.py +21 -8
  354. crackerjack/services/profiler.py +280 -0
  355. crackerjack/services/quality/README.md +415 -0
  356. crackerjack/services/quality/__init__.py +11 -0
  357. crackerjack/services/quality/anomaly_detector.py +392 -0
  358. crackerjack/services/quality/pattern_cache.py +333 -0
  359. crackerjack/services/quality/pattern_detector.py +479 -0
  360. crackerjack/services/quality/qa_orchestrator.py +491 -0
  361. crackerjack/services/{quality_baseline.py → quality/quality_baseline.py} +163 -2
  362. crackerjack/services/{quality_baseline_enhanced.py → quality/quality_baseline_enhanced.py} +4 -1
  363. crackerjack/services/{quality_intelligence.py → quality/quality_intelligence.py} +180 -16
  364. crackerjack/services/regex_patterns.py +58 -2987
  365. crackerjack/services/regex_utils.py +55 -29
  366. crackerjack/services/secure_status_formatter.py +42 -15
  367. crackerjack/services/secure_subprocess.py +35 -2
  368. crackerjack/services/security.py +16 -8
  369. crackerjack/services/server_manager.py +40 -51
  370. crackerjack/services/smart_scheduling.py +46 -6
  371. crackerjack/services/status_authentication.py +3 -3
  372. crackerjack/services/thread_safe_status_collector.py +1 -0
  373. crackerjack/services/tool_filter.py +368 -0
  374. crackerjack/services/tool_version_service.py +9 -5
  375. crackerjack/services/unified_config.py +43 -351
  376. crackerjack/services/vector_store.py +689 -0
  377. crackerjack/services/version_analyzer.py +6 -4
  378. crackerjack/services/version_checker.py +14 -8
  379. crackerjack/services/zuban_lsp_service.py +5 -4
  380. crackerjack/slash_commands/README.md +11 -0
  381. crackerjack/slash_commands/init.md +2 -12
  382. crackerjack/slash_commands/run.md +84 -50
  383. crackerjack/tools/README.md +11 -0
  384. crackerjack/tools/__init__.py +30 -0
  385. crackerjack/tools/_git_utils.py +105 -0
  386. crackerjack/tools/check_added_large_files.py +139 -0
  387. crackerjack/tools/check_ast.py +105 -0
  388. crackerjack/tools/check_json.py +103 -0
  389. crackerjack/tools/check_jsonschema.py +297 -0
  390. crackerjack/tools/check_toml.py +103 -0
  391. crackerjack/tools/check_yaml.py +110 -0
  392. crackerjack/tools/codespell_wrapper.py +72 -0
  393. crackerjack/tools/end_of_file_fixer.py +202 -0
  394. crackerjack/tools/format_json.py +128 -0
  395. crackerjack/tools/mdformat_wrapper.py +114 -0
  396. crackerjack/tools/trailing_whitespace.py +198 -0
  397. crackerjack/tools/validate_regex_patterns.py +7 -3
  398. crackerjack/ui/README.md +11 -0
  399. crackerjack/ui/dashboard_renderer.py +28 -0
  400. crackerjack/ui/templates/README.md +11 -0
  401. crackerjack/utils/console_utils.py +13 -0
  402. crackerjack/utils/dependency_guard.py +230 -0
  403. crackerjack/utils/retry_utils.py +275 -0
  404. crackerjack/workflows/README.md +590 -0
  405. crackerjack/workflows/__init__.py +46 -0
  406. crackerjack/workflows/actions.py +811 -0
  407. crackerjack/workflows/auto_fix.py +444 -0
  408. crackerjack/workflows/container_builder.py +499 -0
  409. crackerjack/workflows/definitions.py +443 -0
  410. crackerjack/workflows/engine.py +177 -0
  411. crackerjack/workflows/event_bridge.py +242 -0
  412. {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/METADATA +678 -98
  413. crackerjack-0.45.2.dist-info/RECORD +478 -0
  414. {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/WHEEL +1 -1
  415. crackerjack/managers/test_manager_backup.py +0 -1075
  416. crackerjack/mcp/tools/execution_tools_backup.py +0 -1011
  417. crackerjack/mixins/__init__.py +0 -3
  418. crackerjack/mixins/error_handling.py +0 -145
  419. crackerjack/services/config.py +0 -358
  420. crackerjack/ui/server_panels.py +0 -125
  421. crackerjack-0.37.9.dist-info/RECORD +0 -231
  422. /crackerjack/adapters/{rust_tool_adapter.py → lsp/_base.py} +0 -0
  423. /crackerjack/adapters/{lsp_client.py → lsp/_client.py} +0 -0
  424. {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/entry_points.txt +0 -0
  425. {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,714 @@
1
+ """Issue parsing and classification for workflow failures.
2
+
3
+ Parses test and hook failures into structured Issue objects for AI agent processing.
4
+ Extracted from WorkflowOrchestrator to improve modularity and testability.
5
+
6
+ This module handles:
7
+ - Collection of test failure issues
8
+ - Collection of hook failure issues
9
+ - Classification of issues by type and priority
10
+ - Detection of specific error patterns (complexity, type, security, etc.)
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import typing as t
16
+
17
+ from acb.console import Console
18
+ from acb.depends import Inject, depends
19
+
20
+ from crackerjack.agents.base import Issue, IssueType, Priority
21
+ from crackerjack.models.protocols import (
22
+ DebugServiceProtocol,
23
+ LoggerProtocol,
24
+ )
25
+
26
+
27
+ class WorkflowIssueParser:
28
+ """Parses and classifies workflow failures into structured issues.
29
+
30
+ This parser extracts issues from test failures and hook execution results,
31
+ classifying them by type (complexity, security, type errors, etc.) and
32
+ priority level for AI agent processing.
33
+
34
+ Uses dependency injection for all required services (Console, Logger, Debug).
35
+ """
36
+
37
+ @depends.inject
38
+ def __init__(
39
+ self,
40
+ console: Inject[Console],
41
+ logger: Inject[LoggerProtocol],
42
+ debugger: Inject[DebugServiceProtocol],
43
+ ) -> None:
44
+ """Initialize the issue parser with injected dependencies.
45
+
46
+ Args:
47
+ console: Console for output
48
+ logger: Logger for diagnostic messages
49
+ debugger: Debug service for detailed diagnostics
50
+ """
51
+ self.console = console
52
+ self.logger = logger
53
+ self.debugger = debugger
54
+
55
+ async def _collect_issues_from_failures(
56
+ self,
57
+ phases: t.Any,
58
+ session: t.Any,
59
+ debug_enabled: bool = False,
60
+ ) -> list[Issue]:
61
+ """Collect all issues from test and hook failures.
62
+
63
+ Args:
64
+ phases: PhaseCoordinator instance with test_manager and hook_manager
65
+ session: SessionCoordinator instance with session_tracker
66
+ debug_enabled: Whether debug mode is enabled
67
+
68
+ Returns:
69
+ List of structured Issue objects for AI agent processing
70
+ """
71
+ issues: list[Issue] = []
72
+
73
+ test_issues, test_count = self._collect_test_failure_issues(phases)
74
+ hook_issues, hook_count = self._collect_hook_failure_issues(phases, session)
75
+
76
+ issues.extend(test_issues)
77
+ issues.extend(hook_issues)
78
+
79
+ self._log_failure_counts_if_debugging(test_count, hook_count, debug_enabled)
80
+
81
+ return issues
82
+
83
+ def _collect_test_failure_issues(self, phases: t.Any) -> tuple[list[Issue], int]:
84
+ """Collect issues from test failures.
85
+
86
+ Args:
87
+ phases: PhaseCoordinator instance with test_manager
88
+
89
+ Returns:
90
+ Tuple of (list of test failure issues, count of test failures)
91
+ """
92
+ issues: list[Issue] = []
93
+ test_count = 0
94
+
95
+ if hasattr(phases, "test_manager") and hasattr(
96
+ phases.test_manager,
97
+ "get_test_failures",
98
+ ):
99
+ test_failures = phases.test_manager.get_test_failures()
100
+ test_count = len(test_failures)
101
+ for i, failure in enumerate(
102
+ test_failures[:20],
103
+ ):
104
+ issue = Issue(
105
+ id=f"test_failure_{i}",
106
+ type=IssueType.TEST_FAILURE,
107
+ severity=Priority.HIGH,
108
+ message=failure.strip(),
109
+ stage="tests",
110
+ )
111
+ issues.append(issue)
112
+
113
+ return issues, test_count
114
+
115
+ def _collect_hook_failure_issues(
116
+ self, phases: t.Any, session: t.Any
117
+ ) -> tuple[list[Issue], int]:
118
+ """Collect issues from hook execution failures.
119
+
120
+ Args:
121
+ phases: PhaseCoordinator instance with hook_manager
122
+ session: SessionCoordinator instance with session_tracker
123
+
124
+ Returns:
125
+ Tuple of (list of hook failure issues, count of hook failures)
126
+ """
127
+ issues: list[Issue] = []
128
+ hook_count = 0
129
+
130
+ try:
131
+ hook_results = phases.hook_manager.run_comprehensive_hooks()
132
+ issues, hook_count = self._process_hook_results(hook_results)
133
+ except Exception:
134
+ issues, hook_count = self._fallback_to_session_tracker(session)
135
+
136
+ return issues, hook_count
137
+
138
+ def _process_hook_results(self, hook_results: t.Any) -> tuple[list[Issue], int]:
139
+ """Process hook execution results into issues.
140
+
141
+ Args:
142
+ hook_results: Results from hook manager execution
143
+
144
+ Returns:
145
+ Tuple of (list of issues, count of failed hooks)
146
+ """
147
+ issues: list[Issue] = []
148
+ hook_count = 0
149
+
150
+ for result in hook_results:
151
+ if not self._is_hook_result_failed(result):
152
+ continue
153
+
154
+ hook_count += 1
155
+ result_issues = self._extract_issues_from_hook_result(result)
156
+ issues.extend(result_issues)
157
+
158
+ return issues, hook_count
159
+
160
+ def _is_hook_result_failed(self, result: t.Any) -> bool:
161
+ """Check if a hook result indicates failure.
162
+
163
+ Args:
164
+ result: Hook execution result object
165
+
166
+ Returns:
167
+ True if the hook failed, error occurred, or timed out
168
+ """
169
+ return result.status in ("failed", "error", "timeout")
170
+
171
+ def _extract_issues_from_hook_result(self, result: t.Any) -> list[Issue]:
172
+ """Extract structured issues from a failed hook result.
173
+
174
+ Args:
175
+ result: Failed hook execution result
176
+
177
+ Returns:
178
+ List of Issue objects parsed from the hook failure
179
+ """
180
+ if result.issues_found:
181
+ return self._create_specific_issues_from_hook_result(result)
182
+ return [self._create_generic_issue_from_hook_result(result)]
183
+
184
+ def _create_specific_issues_from_hook_result(self, result: t.Any) -> list[Issue]:
185
+ """Create specific issues from hook result with detailed issue information.
186
+
187
+ Args:
188
+ result: Hook result with issues_found list
189
+
190
+ Returns:
191
+ List of parsed and classified issues
192
+ """
193
+ issues: list[Issue] = []
194
+ hook_context = f"{result.name}: "
195
+
196
+ for issue_text in result.issues_found:
197
+ parsed_issues = self._parse_issues_for_agents([hook_context + issue_text])
198
+ issues.extend(parsed_issues)
199
+
200
+ return issues
201
+
202
+ def _create_generic_issue_from_hook_result(self, result: t.Any) -> Issue:
203
+ """Create a generic issue from a hook result without specific details.
204
+
205
+ Args:
206
+ result: Failed hook execution result
207
+
208
+ Returns:
209
+ Generic Issue object for the hook failure
210
+ """
211
+ issue_type = self._determine_hook_issue_type(result.name)
212
+ return Issue(
213
+ id=f"hook_failure_{result.name}",
214
+ type=issue_type,
215
+ severity=Priority.MEDIUM,
216
+ message=f"Hook {result.name} failed with no specific details",
217
+ stage="comprehensive",
218
+ )
219
+
220
+ def _determine_hook_issue_type(self, hook_name: str) -> IssueType:
221
+ """Determine issue type from hook name.
222
+
223
+ Args:
224
+ hook_name: Name of the failed hook
225
+
226
+ Returns:
227
+ IssueType classification based on hook name
228
+ """
229
+ formatting_hooks = {
230
+ "trailing-whitespace",
231
+ "end-of-file-fixer",
232
+ "ruff-format",
233
+ "ruff-check",
234
+ }
235
+
236
+ if hook_name == "validate-regex-patterns":
237
+ return IssueType.REGEX_VALIDATION
238
+
239
+ return (
240
+ IssueType.FORMATTING
241
+ if hook_name in formatting_hooks
242
+ else IssueType.TYPE_ERROR
243
+ )
244
+
245
+ def _fallback_to_session_tracker(self, session: t.Any) -> tuple[list[Issue], int]:
246
+ """Fallback to session tracker when hook manager fails.
247
+
248
+ Args:
249
+ session: SessionCoordinator instance with session_tracker
250
+
251
+ Returns:
252
+ Tuple of (list of issues, count of failed hooks)
253
+ """
254
+ issues: list[Issue] = []
255
+ hook_count = 0
256
+
257
+ if not session.session_tracker:
258
+ return issues, hook_count
259
+
260
+ for task_id, task_data in session.session_tracker.tasks.items():
261
+ if self._is_failed_hook_task(task_data, task_id):
262
+ hook_count += 1
263
+ hook_issues = self._process_hook_failure(task_id, task_data)
264
+ issues.extend(hook_issues)
265
+
266
+ return issues, hook_count
267
+
268
+ def _is_failed_hook_task(self, task_data: t.Any, task_id: str) -> bool:
269
+ """Check if a task is a failed hook task.
270
+
271
+ Args:
272
+ task_data: Task data from session tracker
273
+ task_id: Task identifier
274
+
275
+ Returns:
276
+ True if task is a failed hook task
277
+ """
278
+ return task_data.status == "failed" and task_id in (
279
+ "fast_hooks",
280
+ "comprehensive_hooks",
281
+ )
282
+
283
+ def _process_hook_failure(self, task_id: str, task_data: t.Any) -> list[Issue]:
284
+ """Process a hook failure from session tracker.
285
+
286
+ Args:
287
+ task_id: Task identifier
288
+ task_data: Failed task data
289
+
290
+ Returns:
291
+ List of issues parsed from the hook failure
292
+ """
293
+ error_msg = getattr(task_data, "error_message", "Unknown error")
294
+ specific_issues = self._parse_hook_error_details(task_id, error_msg)
295
+
296
+ if specific_issues:
297
+ return specific_issues
298
+
299
+ return [self._create_generic_hook_issue(task_id, error_msg)]
300
+
301
+ def _create_generic_hook_issue(self, task_id: str, error_msg: str) -> Issue:
302
+ """Create a generic issue from a hook task failure.
303
+
304
+ Args:
305
+ task_id: Task identifier
306
+ error_msg: Error message from the task
307
+
308
+ Returns:
309
+ Generic Issue object for the hook failure
310
+ """
311
+ issue_type = IssueType.FORMATTING if "fast" in task_id else IssueType.TYPE_ERROR
312
+ return Issue(
313
+ id=f"hook_failure_{task_id}",
314
+ type=issue_type,
315
+ severity=Priority.MEDIUM,
316
+ message=error_msg,
317
+ stage=task_id.replace("_hooks", ""),
318
+ )
319
+
320
+ def _parse_hook_error_details(self, task_id: str, error_msg: str) -> list[Issue]:
321
+ """Parse specific error details from hook error messages.
322
+
323
+ Args:
324
+ task_id: Task identifier
325
+ error_msg: Error message to parse
326
+
327
+ Returns:
328
+ List of specific issues, or empty list if no patterns match
329
+ """
330
+ issues: list[Issue] = []
331
+
332
+ if task_id == "comprehensive_hooks":
333
+ issues.extend(self._parse_comprehensive_hook_errors(error_msg))
334
+ elif task_id == "fast_hooks":
335
+ issues.append(self._create_fast_hook_issue())
336
+
337
+ return issues
338
+
339
+ def _parse_comprehensive_hook_errors(self, error_msg: str) -> list[Issue]:
340
+ """Parse comprehensive hook errors using pattern checkers.
341
+
342
+ Args:
343
+ error_msg: Error message from comprehensive hooks
344
+
345
+ Returns:
346
+ List of specific issues found in the error message
347
+ """
348
+ error_lower = error_msg.lower()
349
+ error_checkers = self._get_comprehensive_error_checkers()
350
+
351
+ issues = []
352
+ for check_func in error_checkers:
353
+ issue = check_func(error_lower)
354
+ if issue:
355
+ issues.append(issue)
356
+
357
+ return issues
358
+
359
+ def _get_comprehensive_error_checkers(
360
+ self,
361
+ ) -> list[t.Callable[[str], Issue | None]]:
362
+ """Get list of error checking functions for comprehensive hooks.
363
+
364
+ Returns:
365
+ List of checker functions that return Issue if pattern matches
366
+ """
367
+ return [
368
+ self._check_complexity_error,
369
+ self._check_type_error,
370
+ self._check_security_error,
371
+ self._check_performance_error,
372
+ self._check_dead_code_error,
373
+ self._check_regex_validation_error,
374
+ ]
375
+
376
+ def _check_complexity_error(self, error_lower: str) -> Issue | None:
377
+ """Check for complexity violation errors.
378
+
379
+ Args:
380
+ error_lower: Lowercase error message
381
+
382
+ Returns:
383
+ Issue if complexity error detected, None otherwise
384
+ """
385
+ if "complexipy" in error_lower or "c901" in error_lower:
386
+ return Issue(
387
+ id="complexity_violation",
388
+ type=IssueType.COMPLEXITY,
389
+ severity=Priority.HIGH,
390
+ message="Code complexity violation detected",
391
+ stage="comprehensive",
392
+ )
393
+ return None
394
+
395
+ def _check_type_error(self, error_lower: str) -> Issue | None:
396
+ """Check for type checking errors.
397
+
398
+ Args:
399
+ error_lower: Lowercase error message
400
+
401
+ Returns:
402
+ Issue if type error detected, None otherwise
403
+ """
404
+ if "pyright" in error_lower:
405
+ return Issue(
406
+ id="pyright_type_error",
407
+ type=IssueType.TYPE_ERROR,
408
+ severity=Priority.HIGH,
409
+ message="Type checking errors detected by pyright",
410
+ stage="comprehensive",
411
+ )
412
+ return None
413
+
414
+ def _check_security_error(self, error_lower: str) -> Issue | None:
415
+ """Check for security vulnerability errors.
416
+
417
+ Args:
418
+ error_lower: Lowercase error message
419
+
420
+ Returns:
421
+ Issue if security error detected, None otherwise
422
+ """
423
+ if "bandit" in error_lower:
424
+ return Issue(
425
+ id="bandit_security_issue",
426
+ type=IssueType.SECURITY,
427
+ severity=Priority.HIGH,
428
+ message="Security vulnerabilities detected by bandit",
429
+ stage="comprehensive",
430
+ )
431
+ return None
432
+
433
+ def _check_performance_error(self, error_lower: str) -> Issue | None:
434
+ """Check for performance/quality errors.
435
+
436
+ Args:
437
+ error_lower: Lowercase error message
438
+
439
+ Returns:
440
+ Issue if performance error detected, None otherwise
441
+ """
442
+ if "refurb" in error_lower:
443
+ return Issue(
444
+ id="refurb_quality_issue",
445
+ type=IssueType.PERFORMANCE,
446
+ severity=Priority.MEDIUM,
447
+ message="Code quality issues detected by refurb",
448
+ stage="comprehensive",
449
+ )
450
+ return None
451
+
452
+ def _check_dead_code_error(self, error_lower: str) -> Issue | None:
453
+ """Check for dead code errors.
454
+
455
+ Args:
456
+ error_lower: Lowercase error message
457
+
458
+ Returns:
459
+ Issue if dead code detected, None otherwise
460
+ """
461
+ if "vulture" in error_lower:
462
+ return Issue(
463
+ id="vulture_dead_code",
464
+ type=IssueType.DEAD_CODE,
465
+ severity=Priority.MEDIUM,
466
+ message="Dead code detected by vulture",
467
+ stage="comprehensive",
468
+ )
469
+ return None
470
+
471
+ def _check_regex_validation_error(self, error_lower: str) -> Issue | None:
472
+ """Check for regex validation errors.
473
+
474
+ Args:
475
+ error_lower: Lowercase error message
476
+
477
+ Returns:
478
+ Issue if regex validation error detected, None otherwise
479
+ """
480
+ regex_keywords = ("raw regex", "regex pattern", r"\g<", "replacement")
481
+ if "validate-regex-patterns" in error_lower or any(
482
+ keyword in error_lower for keyword in regex_keywords
483
+ ):
484
+ return Issue(
485
+ id="regex_validation_failure",
486
+ type=IssueType.REGEX_VALIDATION,
487
+ severity=Priority.HIGH,
488
+ message="Unsafe regex patterns detected by validate-regex-patterns",
489
+ stage="fast",
490
+ )
491
+ return None
492
+
493
+ def _create_fast_hook_issue(self) -> Issue:
494
+ """Create an issue for fast hook formatting failures.
495
+
496
+ Returns:
497
+ Issue object for fast hook formatting failure
498
+ """
499
+ return Issue(
500
+ id="fast_hooks_formatting",
501
+ type=IssueType.FORMATTING,
502
+ severity=Priority.LOW,
503
+ message="Code formatting issues detected",
504
+ stage="fast",
505
+ )
506
+
507
+ def _parse_issues_for_agents(self, issue_strings: list[str]) -> list[Issue]:
508
+ """Parse issue strings into classified Issue objects.
509
+
510
+ Args:
511
+ issue_strings: List of issue description strings
512
+
513
+ Returns:
514
+ List of classified Issue objects
515
+ """
516
+ issues: list[Issue] = []
517
+
518
+ for i, issue_str in enumerate(issue_strings):
519
+ issue_type, priority = self._classify_issue(issue_str)
520
+
521
+ issue = Issue(
522
+ id=f"parsed_issue_{i}",
523
+ type=issue_type,
524
+ severity=priority,
525
+ message=issue_str.strip(),
526
+ stage="comprehensive",
527
+ )
528
+ issues.append(issue)
529
+
530
+ return issues
531
+
532
+ def _classify_issue(self, issue_str: str) -> tuple[IssueType, Priority]:
533
+ """Classify an issue string by type and priority.
534
+
535
+ Args:
536
+ issue_str: Issue description string
537
+
538
+ Returns:
539
+ Tuple of (IssueType, Priority) based on content analysis
540
+ """
541
+ issue_lower = issue_str.lower()
542
+
543
+ # Check high priority issues first
544
+ high_priority_result = self._check_high_priority_issues(issue_lower)
545
+ if high_priority_result:
546
+ return high_priority_result
547
+
548
+ # Check medium priority issues
549
+ medium_priority_result = self._check_medium_priority_issues(issue_lower)
550
+ if medium_priority_result:
551
+ return medium_priority_result
552
+
553
+ # Default to formatting issue
554
+ return IssueType.FORMATTING, Priority.MEDIUM
555
+
556
+ def _check_high_priority_issues(
557
+ self, issue_lower: str
558
+ ) -> tuple[IssueType, Priority] | None:
559
+ """Check for high priority issue types.
560
+
561
+ Args:
562
+ issue_lower: Lowercase issue string
563
+
564
+ Returns:
565
+ Tuple of issue type and priority if found, None otherwise
566
+ """
567
+ high_priority_checks = [
568
+ (self._is_type_error, IssueType.TYPE_ERROR),
569
+ (self._is_security_issue, IssueType.SECURITY),
570
+ (self._is_complexity_issue, IssueType.COMPLEXITY),
571
+ (self._is_regex_validation_issue, IssueType.REGEX_VALIDATION),
572
+ ]
573
+
574
+ for check_func, issue_type in high_priority_checks:
575
+ if check_func(issue_lower):
576
+ return issue_type, Priority.HIGH
577
+
578
+ return None
579
+
580
+ def _check_medium_priority_issues(
581
+ self, issue_lower: str
582
+ ) -> tuple[IssueType, Priority] | None:
583
+ """Check for medium priority issue types.
584
+
585
+ Args:
586
+ issue_lower: Lowercase issue string
587
+
588
+ Returns:
589
+ Tuple of issue type and priority if found, None otherwise
590
+ """
591
+ medium_priority_checks = [
592
+ (self._is_dead_code_issue, IssueType.DEAD_CODE),
593
+ (self._is_performance_issue, IssueType.PERFORMANCE),
594
+ (self._is_import_error, IssueType.IMPORT_ERROR),
595
+ ]
596
+
597
+ for check_func, issue_type in medium_priority_checks:
598
+ if check_func(issue_lower):
599
+ return issue_type, Priority.MEDIUM
600
+
601
+ return None
602
+
603
+ def _is_type_error(self, issue_lower: str) -> bool:
604
+ """Check if issue is a type error.
605
+
606
+ Args:
607
+ issue_lower: Lowercase issue string
608
+
609
+ Returns:
610
+ True if type error pattern detected
611
+ """
612
+ return any(
613
+ keyword in issue_lower for keyword in ("type", "annotation", "pyright")
614
+ )
615
+
616
+ def _is_security_issue(self, issue_lower: str) -> bool:
617
+ """Check if issue is a security concern.
618
+
619
+ Args:
620
+ issue_lower: Lowercase issue string
621
+
622
+ Returns:
623
+ True if security pattern detected
624
+ """
625
+ return any(
626
+ keyword in issue_lower for keyword in ("security", "bandit", "hardcoded")
627
+ )
628
+
629
+ def _is_complexity_issue(self, issue_lower: str) -> bool:
630
+ """Check if issue is a complexity violation.
631
+
632
+ Args:
633
+ issue_lower: Lowercase issue string
634
+
635
+ Returns:
636
+ True if complexity pattern detected
637
+ """
638
+ return any(
639
+ keyword in issue_lower
640
+ for keyword in ("complexity", "complexipy", "c901", "too complex")
641
+ )
642
+
643
+ def _is_regex_validation_issue(self, issue_lower: str) -> bool:
644
+ """Check if issue is a regex validation problem.
645
+
646
+ Args:
647
+ issue_lower: Lowercase issue string
648
+
649
+ Returns:
650
+ True if regex validation pattern detected
651
+ """
652
+ return any(
653
+ keyword in issue_lower
654
+ for keyword in (
655
+ "regex",
656
+ "pattern",
657
+ "validate-regex-patterns",
658
+ r"\g<",
659
+ "replacement",
660
+ )
661
+ )
662
+
663
+ def _is_dead_code_issue(self, issue_lower: str) -> bool:
664
+ """Check if issue is dead/unused code.
665
+
666
+ Args:
667
+ issue_lower: Lowercase issue string
668
+
669
+ Returns:
670
+ True if dead code pattern detected
671
+ """
672
+ return any(keyword in issue_lower for keyword in ("unused", "dead", "vulture"))
673
+
674
+ def _is_performance_issue(self, issue_lower: str) -> bool:
675
+ """Check if issue is a performance concern.
676
+
677
+ Args:
678
+ issue_lower: Lowercase issue string
679
+
680
+ Returns:
681
+ True if performance pattern detected
682
+ """
683
+ return any(
684
+ keyword in issue_lower for keyword in ("performance", "refurb", "furb")
685
+ )
686
+
687
+ def _is_import_error(self, issue_lower: str) -> bool:
688
+ """Check if issue is an import error.
689
+
690
+ Args:
691
+ issue_lower: Lowercase issue string
692
+
693
+ Returns:
694
+ True if import error pattern detected
695
+ """
696
+ return any(keyword in issue_lower for keyword in ("import", "creosote"))
697
+
698
+ def _log_failure_counts_if_debugging(
699
+ self, test_count: int, hook_count: int, debug_enabled: bool
700
+ ) -> None:
701
+ """Log failure counts when debugging is enabled.
702
+
703
+ Args:
704
+ test_count: Number of test failures
705
+ hook_count: Number of hook failures
706
+ debug_enabled: Whether debug mode is enabled
707
+ """
708
+ if debug_enabled:
709
+ self.debugger.log_test_failures(test_count)
710
+ self.debugger.log_hook_failures(hook_count)
711
+
712
+
713
+ # Register with ACB dependency injection
714
+ depends.set(WorkflowIssueParser, WorkflowIssueParser)