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,641 @@
1
+ """
2
+ Bridge between crackerjack's built-in agents and Claude Code's external agents.
3
+
4
+ This module provides integration between the internal agent system and Claude Code's
5
+ specialized agents located in ~/.claude/agents. It enables crackerjack's built-in
6
+ agents to consult with expert external agents for complex scenarios.
7
+ """
8
+
9
+ import logging
10
+ import typing as t
11
+ from contextlib import suppress
12
+ from pathlib import Path
13
+
14
+ from crackerjack.services.file_modifier import SafeFileModifier
15
+
16
+ from .base import AgentContext, FixResult, Issue, IssueType
17
+
18
+ # Conditional import - ClaudeCodeFixer may not be available
19
+ _claude_ai_available = False
20
+ ClaudeCodeFixer: type[t.Any] | None = None
21
+
22
+ with suppress(ImportError):
23
+ from crackerjack.adapters.ai.claude import ClaudeCodeFixer # type: ignore[no-redef]
24
+
25
+ _claude_ai_available = True
26
+
27
+ # Mapping of internal issue types to Claude Code external agents
28
+ CLAUDE_CODE_AGENT_MAPPING = {
29
+ IssueType.COMPLEXITY: ["refactoring-specialist", "crackerjack-architect"],
30
+ IssueType.DRY_VIOLATION: ["refactoring-specialist", "crackerjack-architect"],
31
+ IssueType.PERFORMANCE: ["performance-specialist", "python-pro"],
32
+ IssueType.SECURITY: ["security-auditor", "python-pro"],
33
+ IssueType.TYPE_ERROR: ["python-pro", "crackerjack-architect"],
34
+ IssueType.TEST_FAILURE: ["crackerjack-test-specialist", "python-pro"],
35
+ IssueType.TEST_ORGANIZATION: ["crackerjack-test-specialist", "testing-specialist"],
36
+ IssueType.IMPORT_ERROR: ["python-pro", "refactoring-specialist"],
37
+ IssueType.DOCUMENTATION: ["documentation-specialist", "crackerjack-architect"],
38
+ IssueType.FORMATTING: ["python-pro"],
39
+ }
40
+
41
+ # Minimum confidence threshold for consulting external agents
42
+ EXTERNAL_CONSULTATION_THRESHOLD = 0.8
43
+
44
+
45
+ class ClaudeCodeBridge:
46
+ """Bridge for consulting Claude Code external agents with real AI integration."""
47
+
48
+ def __init__(self, context: AgentContext) -> None:
49
+ self.context = context
50
+ self.logger = logging.getLogger(__name__)
51
+ self._agent_path = Path.home() / ".claude" / "agents"
52
+ self._consultation_cache: dict[str, dict[str, t.Any]] = {}
53
+
54
+ # Real AI integration components (if available)
55
+ self.ai_fixer: t.Any | None = None # ClaudeCodeFixer instance or None
56
+ self.file_modifier = SafeFileModifier()
57
+ self._ai_available = _claude_ai_available
58
+
59
+ if not self._ai_available:
60
+ self.logger.warning(
61
+ "Claude AI adapter not available - AI-powered fixes disabled"
62
+ )
63
+
64
+ def should_consult_external_agent(
65
+ self, issue: Issue, internal_confidence: float
66
+ ) -> bool:
67
+ """Determine if we should consult an external Claude Code agent."""
68
+ # Only consult for complex issues that meet threshold
69
+ if internal_confidence >= EXTERNAL_CONSULTATION_THRESHOLD:
70
+ return False
71
+
72
+ # Check if we have relevant external agents for this issue type
73
+ return issue.type in CLAUDE_CODE_AGENT_MAPPING
74
+
75
+ def _get_agent_mapping(self) -> dict[t.Any, list[str]]:
76
+ """Get the agent mapping for external access."""
77
+ return CLAUDE_CODE_AGENT_MAPPING
78
+
79
+ def _get_consultation_threshold(self) -> float:
80
+ """Get the consultation threshold for external access."""
81
+ return EXTERNAL_CONSULTATION_THRESHOLD
82
+
83
+ def get_recommended_external_agents(self, issue: Issue) -> list[str]:
84
+ """Get list of recommended external agents for an issue."""
85
+ return CLAUDE_CODE_AGENT_MAPPING.get(issue.type, [])
86
+
87
+ def verify_agent_availability(self, agent_name: str) -> bool:
88
+ """Check if a Claude Code agent file exists."""
89
+ agent_file = self._agent_path / f"{agent_name}.md"
90
+ return agent_file.exists()
91
+
92
+ async def consult_external_agent(
93
+ self, issue: Issue, agent_name: str, context: dict[str, t.Any] | None = None
94
+ ) -> dict[str, t.Any]:
95
+ """
96
+ Consult with a Claude Code external agent for expert guidance.
97
+
98
+ This method would ideally use the Task tool to invoke external agents,
99
+ but since we're within crackerjack's internal system, we'll simulate
100
+ the consultation process and provide structured recommendations.
101
+ """
102
+ cache_key = (
103
+ f"{agent_name}:{issue.type.value}:{issue.file_path}:{issue.line_number}"
104
+ )
105
+
106
+ if cache_key in self._consultation_cache:
107
+ self.logger.debug(f"Using cached consultation for {agent_name}")
108
+ return self._consultation_cache[cache_key]
109
+
110
+ if not self.verify_agent_availability(agent_name):
111
+ self.logger.warning(f"Agent {agent_name} not available in ~/.claude/agents")
112
+ return {"status": "unavailable", "recommendations": []}
113
+
114
+ # Generate consultation based on agent expertise and issue type
115
+ consultation = await self._generate_agent_consultation(
116
+ issue, agent_name, context
117
+ )
118
+
119
+ # Cache successful consultations
120
+ if consultation.get("status") == "success":
121
+ self._consultation_cache[cache_key] = consultation
122
+
123
+ return consultation
124
+
125
+ async def _generate_agent_consultation(
126
+ self, issue: Issue, agent_name: str, context: dict[str, t.Any] | None = None
127
+ ) -> dict[str, t.Any]:
128
+ """Generate structured consultation response from agent expertise."""
129
+ consultation: dict[str, t.Any] = {
130
+ "status": "success",
131
+ "agent": agent_name,
132
+ "issue_type": issue.type.value,
133
+ "recommendations": [],
134
+ "patterns": [],
135
+ "validation_steps": [],
136
+ "confidence": 0.9,
137
+ }
138
+
139
+ # Agent-specific consultation logic
140
+ if agent_name == "crackerjack-architect":
141
+ consultation.update(
142
+ await self._consult_crackerjack_architect(issue, context)
143
+ )
144
+ elif agent_name == "python-pro":
145
+ consultation.update(await self._consult_python_pro(issue, context))
146
+ elif agent_name == "security-auditor":
147
+ consultation.update(await self._consult_security_auditor(issue, context))
148
+ elif agent_name == "refactoring-specialist":
149
+ consultation.update(
150
+ await self._consult_refactoring_specialist(issue, context)
151
+ )
152
+ elif agent_name == "crackerjack-test-specialist":
153
+ consultation.update(await self._consult_test_specialist(issue, context))
154
+ else:
155
+ consultation.update(
156
+ await self._consult_generic_agent(issue, agent_name, context)
157
+ )
158
+
159
+ return consultation
160
+
161
+ async def _consult_crackerjack_architect(
162
+ self, issue: Issue, context: dict[str, t.Any] | None = None
163
+ ) -> dict[str, t.Any]:
164
+ """Consult with crackerjack-architect for architectural guidance."""
165
+ return {
166
+ "recommendations": [
167
+ "Apply clean code principles (DRY, YAGNI, KISS)",
168
+ "Follow crackerjack's modular architecture patterns",
169
+ "Use protocol-based dependency injection",
170
+ "Break complex functions into focused helper methods",
171
+ "Maintain single responsibility principle",
172
+ ],
173
+ "patterns": [
174
+ "extract_method",
175
+ "dependency_injection",
176
+ "protocol_interfaces",
177
+ "helper_methods",
178
+ "single_responsibility",
179
+ ],
180
+ "validation_steps": [
181
+ "run_complexity_check",
182
+ "verify_type_annotations",
183
+ "check_architectural_consistency",
184
+ "validate_against_crackerjack_patterns",
185
+ ],
186
+ }
187
+
188
+ async def _consult_python_pro(
189
+ self, issue: Issue, context: dict[str, t.Any] | None = None
190
+ ) -> dict[str, t.Any]:
191
+ """Consult with python-pro for Python-specific best practices."""
192
+ return {
193
+ "recommendations": [
194
+ "Use modern Python 3.13+ type hints with | unions",
195
+ "Apply proper error handling patterns",
196
+ "Follow PEP 8 style guidelines",
197
+ "Use pathlib over os.path",
198
+ "Implement proper context managers",
199
+ ],
200
+ "patterns": [
201
+ "type_annotations",
202
+ "context_managers",
203
+ "exception_handling",
204
+ "python_idioms",
205
+ "modern_syntax",
206
+ ],
207
+ "validation_steps": [
208
+ "run_type_checking",
209
+ "verify_python_compatibility",
210
+ "check_style_compliance",
211
+ "validate_error_handling",
212
+ ],
213
+ }
214
+
215
+ async def _consult_security_auditor(
216
+ self, issue: Issue, context: dict[str, t.Any] | None = None
217
+ ) -> dict[str, t.Any]:
218
+ """Consult with security-auditor for security best practices."""
219
+ return {
220
+ "recommendations": [
221
+ "Never use hardcoded paths or credentials",
222
+ "Use secure temp file creation",
223
+ "Avoid shell=True in subprocess calls",
224
+ "Implement proper input validation",
225
+ "Use environment variables for sensitive data",
226
+ ],
227
+ "patterns": [
228
+ "secure_temp_files",
229
+ "input_validation",
230
+ "safe_subprocess",
231
+ "environment_variables",
232
+ "sanitization",
233
+ ],
234
+ "validation_steps": [
235
+ "run_security_scan",
236
+ "check_for_hardcoded_secrets",
237
+ "validate_subprocess_calls",
238
+ "verify_temp_file_handling",
239
+ ],
240
+ }
241
+
242
+ async def _consult_refactoring_specialist(
243
+ self, issue: Issue, context: dict[str, t.Any] | None = None
244
+ ) -> dict[str, t.Any]:
245
+ """Consult with refactoring-specialist for code improvement."""
246
+ return {
247
+ "recommendations": [
248
+ "Break down complex functions (complexity ≤ 15)",
249
+ "Extract common patterns into utilities",
250
+ "Remove dead code and unused imports",
251
+ "Apply DRY principle to eliminate duplication",
252
+ "Use composition over inheritance",
253
+ ],
254
+ "patterns": [
255
+ "extract_method",
256
+ "eliminate_duplication",
257
+ "dead_code_removal",
258
+ "complexity_reduction",
259
+ "composition_pattern",
260
+ ],
261
+ "validation_steps": [
262
+ "measure_complexity_reduction",
263
+ "verify_test_coverage_maintained",
264
+ "check_for_dead_code",
265
+ "validate_duplication_removal",
266
+ ],
267
+ }
268
+
269
+ async def _consult_test_specialist(
270
+ self, issue: Issue, context: dict[str, t.Any] | None = None
271
+ ) -> dict[str, t.Any]:
272
+ """Consult with crackerjack-test-specialist for testing guidance."""
273
+ return {
274
+ "recommendations": [
275
+ "Avoid complex async tests that can hang",
276
+ "Use synchronous config tests for reliability",
277
+ "Mock external dependencies properly",
278
+ "Follow crackerjack's testing patterns",
279
+ "Maintain test coverage ratchet",
280
+ ],
281
+ "patterns": [
282
+ "synchronous_tests",
283
+ "proper_mocking",
284
+ "test_organization",
285
+ "coverage_improvement",
286
+ "fixture_patterns",
287
+ ],
288
+ "validation_steps": [
289
+ "run_test_suite",
290
+ "verify_coverage_increase",
291
+ "check_test_reliability",
292
+ "validate_mock_usage",
293
+ ],
294
+ }
295
+
296
+ async def _consult_generic_agent(
297
+ self, issue: Issue, agent_name: str, context: dict[str, t.Any] | None = None
298
+ ) -> dict[str, t.Any]:
299
+ """Generic consultation for unspecified agents."""
300
+ return {
301
+ "recommendations": [
302
+ f"Consult {agent_name} documentation for specific guidance",
303
+ "Apply domain-specific best practices",
304
+ "Follow established patterns and conventions",
305
+ ],
306
+ "patterns": ["domain_specific_patterns"],
307
+ "validation_steps": ["validate_domain_requirements"],
308
+ }
309
+
310
+ async def _ensure_ai_fixer(self) -> t.Any:
311
+ """Lazy initialization of AI fixer adapter.
312
+
313
+ Returns:
314
+ Initialized ClaudeCodeFixer instance
315
+
316
+ Raises:
317
+ RuntimeError: If Claude AI is not available or initialization fails
318
+ """
319
+ if not self._ai_available:
320
+ raise RuntimeError(
321
+ "Claude AI adapter not available - install ACB with 'uv add acb[ai]'"
322
+ )
323
+
324
+ if self.ai_fixer is None:
325
+ if ClaudeCodeFixer is None:
326
+ raise RuntimeError("ClaudeCodeFixer import failed")
327
+
328
+ self.ai_fixer = ClaudeCodeFixer()
329
+ await self.ai_fixer.init()
330
+ self.logger.debug("Claude AI fixer initialized")
331
+
332
+ return self.ai_fixer
333
+
334
+ def _extract_ai_response_fields(
335
+ self, ai_result: dict[str, t.Any]
336
+ ) -> tuple[str, str, float, list[str], list[str]]:
337
+ """Extract fields from AI result."""
338
+ fixed_code = str(ai_result.get("fixed_code", ""))
339
+ explanation = str(ai_result.get("explanation", "No explanation"))
340
+ confidence = float(ai_result.get("confidence", 0.0))
341
+ changes_made = ai_result.get("changes_made", [])
342
+ potential_side_effects = ai_result.get("potential_side_effects", [])
343
+
344
+ return fixed_code, explanation, confidence, changes_made, potential_side_effects
345
+
346
+ async def _apply_fix_to_file(
347
+ self, file_path: str, fixed_code: str, dry_run: bool
348
+ ) -> dict[str, t.Any]:
349
+ """Apply the fix to the file using SafeFileModifier."""
350
+ modify_result = await self.file_modifier.apply_fix(
351
+ file_path=file_path,
352
+ fixed_content=fixed_code,
353
+ dry_run=dry_run,
354
+ create_backup=True,
355
+ )
356
+ return modify_result
357
+
358
+ def _handle_successful_ai_fix(
359
+ self,
360
+ issue: Issue,
361
+ file_path: str,
362
+ confidence: float,
363
+ changes_made: list[str],
364
+ potential_side_effects: list[str],
365
+ fix_type: str,
366
+ ) -> FixResult:
367
+ """Handle the case when the AI successfully fixes the issue."""
368
+ self.logger.info(
369
+ f"Successfully applied AI fix to {file_path} (confidence: {confidence:.2f})"
370
+ )
371
+
372
+ return FixResult(
373
+ success=True,
374
+ confidence=confidence,
375
+ fixes_applied=[f"Fixed {fix_type} in {file_path}"],
376
+ remaining_issues=[],
377
+ recommendations=[
378
+ issue.message,
379
+ *[f"Change: {change}" for change in changes_made],
380
+ *[
381
+ f"Potential side effect: {effect}"
382
+ for effect in potential_side_effects
383
+ ],
384
+ ],
385
+ files_modified=[file_path],
386
+ )
387
+
388
+ def _handle_dry_run_response(
389
+ self, confidence: float, changes_made: list[str], issue: Issue
390
+ ) -> FixResult:
391
+ """Handle the case for dry-run mode."""
392
+ return FixResult(
393
+ success=True,
394
+ confidence=confidence,
395
+ fixes_applied=[],
396
+ remaining_issues=[issue.id],
397
+ recommendations=[
398
+ f"AI suggests (dry-run): {issue.message}",
399
+ *[f"Change: {change}" for change in changes_made],
400
+ ],
401
+ files_modified=[],
402
+ )
403
+
404
+ def _handle_error_response(self, error_msg: str, issue: Issue) -> FixResult:
405
+ """Handle the case when there's an error in AI fix."""
406
+ self.logger.error(f"AI fix failed: {error_msg}")
407
+
408
+ return FixResult(
409
+ success=False,
410
+ confidence=0.0,
411
+ fixes_applied=[],
412
+ remaining_issues=[issue.id],
413
+ recommendations=[f"AI fix failed: {error_msg}"],
414
+ files_modified=[],
415
+ )
416
+
417
+ def _handle_low_confidence_response(
418
+ self, confidence: float, explanation: str, issue: Issue
419
+ ) -> FixResult:
420
+ """Handle the case when confidence is too low."""
421
+ min_confidence = 0.7 # Match AI fixer's default
422
+ self.logger.warning(
423
+ f"AI confidence {confidence:.2f} below threshold {min_confidence}"
424
+ )
425
+
426
+ return FixResult(
427
+ success=False,
428
+ confidence=confidence,
429
+ fixes_applied=[],
430
+ remaining_issues=[issue.id],
431
+ recommendations=[
432
+ f"AI fix confidence {confidence:.2f} too low (threshold: {min_confidence})",
433
+ explanation,
434
+ ],
435
+ files_modified=[],
436
+ )
437
+
438
+ async def _validate_ai_result(
439
+ self, ai_result: dict[str, t.Any], issue: Issue
440
+ ) -> tuple[str, str, float, list[str], list[str]] | None:
441
+ """Validate AI result and extract fields.
442
+
443
+ Returns:
444
+ Tuple of (fixed_code, explanation, confidence, changes_made, side_effects)
445
+ or None if validation failed (already returned FixResult)
446
+ """
447
+ # Check if AI fix was successful
448
+ if not ai_result.get("success"):
449
+ ai_result.get("error", "Unknown AI error")
450
+ return None
451
+
452
+ # Extract AI response fields
453
+ (
454
+ fixed_code,
455
+ explanation,
456
+ confidence,
457
+ changes_made,
458
+ potential_side_effects,
459
+ ) = self._extract_ai_response_fields(ai_result)
460
+
461
+ # Validate confidence threshold
462
+ min_confidence = 0.7 # Match AI fixer's default
463
+ if confidence < min_confidence:
464
+ return None
465
+
466
+ return (
467
+ fixed_code,
468
+ explanation,
469
+ confidence,
470
+ changes_made,
471
+ potential_side_effects,
472
+ )
473
+
474
+ async def _apply_ai_fix(
475
+ self,
476
+ file_path: str,
477
+ fixed_code: str,
478
+ confidence: float,
479
+ changes_made: list[str],
480
+ potential_side_effects: list[str],
481
+ fix_type: str,
482
+ issue: Issue,
483
+ dry_run: bool,
484
+ ) -> FixResult:
485
+ """Apply AI fix to file using SafeFileModifier."""
486
+ modify_result = await self._apply_fix_to_file(file_path, fixed_code, dry_run)
487
+
488
+ if not modify_result.get("success"):
489
+ error_msg = modify_result.get("error", "Unknown modification error")
490
+ self.logger.error(f"File modification failed: {error_msg}")
491
+
492
+ return FixResult(
493
+ success=False,
494
+ confidence=confidence,
495
+ fixes_applied=[],
496
+ remaining_issues=[issue.id],
497
+ recommendations=[
498
+ f"File modification failed: {error_msg}",
499
+ "",
500
+ ],
501
+ files_modified=[],
502
+ )
503
+
504
+ # Success - fix applied
505
+ return self._handle_successful_ai_fix(
506
+ issue,
507
+ file_path,
508
+ confidence,
509
+ changes_made,
510
+ potential_side_effects,
511
+ fix_type,
512
+ )
513
+
514
+ async def consult_on_issue(
515
+ self,
516
+ issue: Issue,
517
+ dry_run: bool = False,
518
+ ) -> FixResult:
519
+ """Consult with Claude AI to fix an issue using real AI integration.
520
+
521
+ This method replaces the simulation-based approach with real AI-powered
522
+ code fixing. It:
523
+ 1. Calls the ClaudeCodeFixer adapter to generate a fix
524
+ 2. Validates the AI response (confidence, success)
525
+ 3. Uses SafeFileModifier to safely apply changes
526
+ 4. Handles errors gracefully
527
+ 5. Returns a proper FixResult
528
+
529
+ Args:
530
+ issue: Issue to fix
531
+ dry_run: If True, only generate fix without applying
532
+
533
+ Returns:
534
+ FixResult with fix details and success status
535
+ """
536
+ try:
537
+ # Initialize AI fixer if needed
538
+ fixer = await self._ensure_ai_fixer()
539
+
540
+ # Extract issue details for AI context
541
+ file_path = str(issue.file_path) if issue.file_path else "unknown"
542
+ issue_description = issue.message # Issue uses 'message' not 'description'
543
+ code_snippet = "\n".join(issue.details) if issue.details else ""
544
+ fix_type = issue.type.value
545
+
546
+ self.logger.info(
547
+ f"Consulting Claude AI for {fix_type} issue in {file_path}"
548
+ )
549
+
550
+ # Call AI fixer to generate code fix
551
+ ai_result = await fixer.fix_code_issue(
552
+ file_path=file_path,
553
+ issue_description=issue_description,
554
+ code_context=code_snippet,
555
+ fix_type=fix_type,
556
+ )
557
+
558
+ # Validate AI result
559
+ validation_result = await self._validate_ai_result(ai_result, issue)
560
+ if validation_result is None:
561
+ # Validation failed - extract error from ai_result
562
+ if not ai_result.get("success"):
563
+ error_msg = ai_result.get("error", "Unknown AI error")
564
+ return self._handle_error_response(error_msg, issue)
565
+ else:
566
+ # Low confidence
567
+ _, explanation, confidence, *_ = self._extract_ai_response_fields(
568
+ ai_result
569
+ )
570
+ return self._handle_low_confidence_response(
571
+ confidence, explanation, issue
572
+ )
573
+
574
+ (
575
+ fixed_code,
576
+ explanation,
577
+ confidence,
578
+ changes_made,
579
+ potential_side_effects,
580
+ ) = validation_result
581
+
582
+ # Apply fix using SafeFileModifier
583
+ if not dry_run and fixed_code:
584
+ return await self._apply_ai_fix(
585
+ file_path,
586
+ fixed_code,
587
+ confidence,
588
+ changes_made,
589
+ potential_side_effects,
590
+ fix_type,
591
+ issue,
592
+ dry_run,
593
+ )
594
+ else:
595
+ # Dry-run mode or no code - just report recommendation
596
+ return self._handle_dry_run_response(confidence, changes_made, issue)
597
+
598
+ except Exception as e:
599
+ self.logger.exception(f"Unexpected error in consult_on_issue: {e}")
600
+
601
+ return FixResult(
602
+ success=False,
603
+ confidence=0.0,
604
+ fixes_applied=[],
605
+ remaining_issues=[issue.id],
606
+ recommendations=[f"Unexpected error: {e}"],
607
+ files_modified=[],
608
+ )
609
+
610
+ def create_enhanced_fix_result(
611
+ self, base_result: FixResult, consultations: list[dict[str, t.Any]]
612
+ ) -> FixResult:
613
+ """Enhance a FixResult with external agent consultations."""
614
+ enhanced_result = FixResult(
615
+ success=base_result.success,
616
+ confidence=base_result.confidence,
617
+ fixes_applied=base_result.fixes_applied.copy(),
618
+ remaining_issues=base_result.remaining_issues.copy(),
619
+ recommendations=base_result.recommendations.copy(),
620
+ files_modified=base_result.files_modified.copy(),
621
+ )
622
+
623
+ # Aggregate recommendations from all consultations
624
+ for consultation in consultations:
625
+ if consultation.get("status") == "success":
626
+ agent_name = consultation.get("agent", "unknown")
627
+ enhanced_result.recommendations.extend(
628
+ [
629
+ f"[{agent_name}] {rec}"
630
+ for rec in consultation.get("recommendations", [])
631
+ ]
632
+ )
633
+
634
+ # Boost confidence if external agents provided guidance
635
+ external_confidence = consultation.get("confidence", 0.0)
636
+ enhanced_result.confidence = max(
637
+ enhanced_result.confidence,
638
+ (enhanced_result.confidence + external_confidence) / 2,
639
+ )
640
+
641
+ return enhanced_result