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,201 @@
1
+ """SAST (Static Application Security Testing) adapter protocol and base classes.
2
+
3
+ This module defines the protocol interface that all SAST adapters must implement,
4
+ providing a consistent API for static security analysis tools.
5
+
6
+ SAST tools analyze source code for:
7
+ - Security vulnerabilities (SQL injection, XSS, etc.)
8
+ - Security anti-patterns and insecure practices
9
+ - Weak cryptography implementations
10
+ - Authentication/authorization flaws
11
+ - Potential injection vulnerabilities
12
+
13
+ Protocol-based design ensures:
14
+ - Type safety via runtime_checkable protocol
15
+ - Loose coupling for testing and mocking
16
+ - Consistent interface across all SAST tools
17
+ - Integration with ACB dependency injection
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import typing as t
23
+ from pathlib import Path
24
+ from typing import Protocol, runtime_checkable
25
+ from uuid import UUID
26
+
27
+ from crackerjack.adapters._tool_adapter_base import (
28
+ ToolAdapterSettings,
29
+ ToolExecutionResult,
30
+ ToolIssue,
31
+ )
32
+
33
+ if t.TYPE_CHECKING:
34
+ from crackerjack.models.qa_config import QACheckConfig
35
+ from crackerjack.models.qa_results import QACheckType
36
+
37
+
38
+ @runtime_checkable
39
+ class SASTAdapterProtocol(Protocol):
40
+ """Protocol for SAST (Static Application Security Testing) adapters.
41
+
42
+ All SAST adapters must implement this protocol to ensure consistent
43
+ behavior and integration with the Crackerjack quality assurance framework.
44
+
45
+ SAST tools focus on finding security vulnerabilities in source code through
46
+ static analysis, complementing secret detection (gitleaks) which prevents
47
+ credential leaks.
48
+
49
+ Attributes:
50
+ settings: Tool-specific settings (severity thresholds, rulesets, etc.)
51
+ adapter_name: Human-readable adapter name (e.g., "Semgrep (SAST)")
52
+ module_id: Unique UUID7 identifier for this adapter module
53
+ tool_name: CLI tool name for command execution
54
+
55
+ Example:
56
+ ```python
57
+ from crackerjack.adapters.sast import SemgrepAdapter
58
+
59
+ adapter: SASTAdapterProtocol = SemgrepAdapter()
60
+ await adapter.init()
61
+ result = await adapter.check(files=[Path("src/")])
62
+ ```
63
+ """
64
+
65
+ settings: ToolAdapterSettings | None
66
+
67
+ @property
68
+ def adapter_name(self) -> str:
69
+ """Human-readable adapter name.
70
+
71
+ Returns:
72
+ Name identifying the adapter (e.g., "Bandit (SAST)", "Semgrep (SAST)")
73
+ """
74
+ ...
75
+
76
+ @property
77
+ def module_id(self) -> UUID:
78
+ """Unique module identifier.
79
+
80
+ Returns:
81
+ UUID7 for reproducible module identity (ACB registration)
82
+ """
83
+ ...
84
+
85
+ @property
86
+ def tool_name(self) -> str:
87
+ """CLI tool name.
88
+
89
+ Returns:
90
+ Command-line tool name for subprocess execution
91
+ """
92
+ ...
93
+
94
+ async def init(self) -> None:
95
+ """Initialize adapter with settings and dependencies.
96
+
97
+ Must be called before using check() or other operations.
98
+ Sets up default settings if not provided during construction.
99
+
100
+ Raises:
101
+ RuntimeError: If initialization fails
102
+ """
103
+ ...
104
+
105
+ def build_command(
106
+ self,
107
+ files: list[Path],
108
+ config: QACheckConfig | None = None,
109
+ ) -> list[str]:
110
+ """Build tool command for execution.
111
+
112
+ Args:
113
+ files: Files or directories to scan for vulnerabilities
114
+ config: Optional configuration override
115
+
116
+ Returns:
117
+ Command as list of strings for subprocess execution
118
+
119
+ Example:
120
+ ```python
121
+ cmd = adapter.build_command(
122
+ files=[Path("src/")],
123
+ config=None,
124
+ )
125
+ # Returns: ["semgrep", "scan", "--json", "--config", "p/security-audit", "src/"]
126
+ ```
127
+ """
128
+ ...
129
+
130
+ async def check(
131
+ self,
132
+ files: list[Path],
133
+ config: QACheckConfig | None = None,
134
+ ) -> ToolExecutionResult:
135
+ """Execute SAST scan on specified files.
136
+
137
+ Args:
138
+ files: Files or directories to analyze for security issues
139
+ config: Optional configuration override
140
+
141
+ Returns:
142
+ Execution result with parsed issues, timing, and metadata
143
+
144
+ Example:
145
+ ```python
146
+ result = await adapter.check(files=[Path("src/")])
147
+ for issue in result.issues:
148
+ print(f"{issue.file_path}:{issue.line_number} - {issue.message}")
149
+ ```
150
+ """
151
+ ...
152
+
153
+ async def parse_output(
154
+ self,
155
+ result: ToolExecutionResult,
156
+ ) -> list[ToolIssue]:
157
+ """Parse tool output into standardized issues.
158
+
159
+ Args:
160
+ result: Raw execution result from SAST tool
161
+
162
+ Returns:
163
+ List of parsed security issues with severity, location, and suggestions
164
+
165
+ Note:
166
+ Implementations should handle both JSON and text output formats,
167
+ with JSON preferred for structured parsing.
168
+ """
169
+ ...
170
+
171
+ def _get_check_type(self) -> QACheckType:
172
+ """Return the check type for this adapter.
173
+
174
+ Returns:
175
+ QACheckType.SAST for all SAST adapters
176
+ """
177
+ ...
178
+
179
+ def get_default_config(self) -> QACheckConfig:
180
+ """Get default configuration for this SAST adapter.
181
+
182
+ Returns:
183
+ Default QACheckConfig with sensible defaults for the tool
184
+
185
+ Example:
186
+ ```python
187
+ config = adapter.get_default_config()
188
+ assert config.check_type == QACheckType.SAST
189
+ assert config.stage == "comprehensive"
190
+ ```
191
+ """
192
+ ...
193
+
194
+
195
+ # Type alias for convenience
196
+ SASTAdapter = SASTAdapterProtocol
197
+
198
+ __all__ = [
199
+ "SASTAdapterProtocol",
200
+ "SASTAdapter",
201
+ ]
@@ -0,0 +1,423 @@
1
+ """Bandit adapter for ACB QA framework - Python security linting.
2
+
3
+ Bandit is a security linter designed to find common security issues in Python code.
4
+ It performs static analysis to identify potential vulnerabilities like:
5
+ - SQL injection risks
6
+ - Hard-coded passwords/secrets
7
+ - Insecure use of eval/exec
8
+ - Weak cryptography
9
+ - And many more security anti-patterns
10
+
11
+ ACB Patterns:
12
+ - MODULE_ID and MODULE_STATUS at module level
13
+ - depends.set() registration after class definition
14
+ - Extends BaseToolAdapter for tool execution
15
+ - Async execution with JSON output parsing
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import json
21
+ import logging
22
+ import typing as t
23
+ from contextlib import suppress
24
+ from pathlib import Path
25
+ from uuid import UUID
26
+
27
+ from acb.depends import depends
28
+ from pydantic import Field
29
+
30
+ from crackerjack.adapters._tool_adapter_base import (
31
+ BaseToolAdapter,
32
+ ToolAdapterSettings,
33
+ ToolExecutionResult,
34
+ ToolIssue,
35
+ )
36
+ from crackerjack.models.qa_results import QACheckType
37
+
38
+ if t.TYPE_CHECKING:
39
+ from crackerjack.models.qa_config import QACheckConfig
40
+
41
+ # ACB Module Registration (REQUIRED)
42
+ MODULE_ID = UUID(
43
+ "01937d86-4f2a-7b3c-8d9e-f3b4d3c2b1a0"
44
+ ) # Static UUID7 for reproducible module identity
45
+ MODULE_STATUS = "stable"
46
+
47
+ # Module-level logger for structured logging
48
+ logger = logging.getLogger(__name__)
49
+
50
+
51
+ class BanditSettings(ToolAdapterSettings):
52
+ """Settings for Bandit adapter."""
53
+
54
+ tool_name: str = "bandit"
55
+ use_json_output: bool = True
56
+ severity_level: str = "low" # low, medium, high
57
+ confidence_level: str = "low" # low, medium, high
58
+ exclude_tests: bool = True
59
+ skip_rules: list[str] = Field(default_factory=list)
60
+ tests_to_run: list[str] = Field(default_factory=list)
61
+ recursive: bool = True
62
+ timeout_seconds: int = (
63
+ 1200 # 20 minutes to allow for comprehensive security scanning
64
+ )
65
+
66
+
67
+ class BanditAdapter(BaseToolAdapter):
68
+ """Adapter for Bandit - Python security linter.
69
+
70
+ Performs static security analysis to identify common vulnerabilities:
71
+ - SQL injection
72
+ - Hard-coded credentials
73
+ - Insecure cryptography
74
+ - Command injection
75
+ - Path traversal
76
+ - And 100+ more security checks
77
+
78
+ Features:
79
+ - JSON output for structured issue reporting
80
+ - Configurable severity and confidence thresholds
81
+ - Rule selection and exclusion
82
+ - Recursive directory scanning
83
+ - Test file exclusion
84
+
85
+ Example:
86
+ ```python
87
+ settings = BanditSettings(
88
+ severity_level="medium",
89
+ confidence_level="medium",
90
+ exclude_tests=True,
91
+ skip_rules=["B101"], # Skip assert_used check
92
+ )
93
+ adapter = BanditAdapter(settings=settings)
94
+ await adapter.init()
95
+ result = await adapter.check(files=[Path("src/")])
96
+ ```
97
+ """
98
+
99
+ settings: BanditSettings | None = None
100
+
101
+ def __init__(self, settings: BanditSettings | None = None) -> None:
102
+ """Initialize Bandit adapter.
103
+
104
+ Args:
105
+ settings: Optional settings override
106
+ """
107
+ super().__init__(settings=settings)
108
+ logger.debug(
109
+ "BanditAdapter initialized", extra={"has_settings": settings is not None}
110
+ )
111
+
112
+ async def init(self) -> None:
113
+ """Initialize adapter with default settings."""
114
+ if not self.settings:
115
+ self.settings = BanditSettings()
116
+ logger.info("Using default BanditSettings")
117
+ await super().init()
118
+ logger.debug(
119
+ "BanditAdapter initialization complete",
120
+ extra={
121
+ "severity": self.settings.severity_level,
122
+ "confidence": self.settings.confidence_level,
123
+ "exclude_tests": self.settings.exclude_tests,
124
+ },
125
+ )
126
+
127
+ @property
128
+ def adapter_name(self) -> str:
129
+ """Human-readable adapter name."""
130
+ return "Bandit (Security)"
131
+
132
+ @property
133
+ def module_id(self) -> UUID:
134
+ """Reference to module-level MODULE_ID."""
135
+ return MODULE_ID
136
+
137
+ @property
138
+ def tool_name(self) -> str:
139
+ """CLI tool name."""
140
+ return "bandit"
141
+
142
+ def build_command(
143
+ self,
144
+ files: list[Path],
145
+ config: QACheckConfig | None = None,
146
+ ) -> list[str]:
147
+ """Build Bandit command.
148
+
149
+ Args:
150
+ files: Files/directories to scan
151
+ config: Optional configuration override
152
+
153
+ Returns:
154
+ Command as list of strings
155
+ """
156
+ if not self.settings:
157
+ raise RuntimeError("Settings not initialized")
158
+
159
+ cmd = [self.tool_name]
160
+
161
+ # Recursive scanning
162
+ if self.settings.recursive:
163
+ cmd.append("-r")
164
+
165
+ # Use HIGH severity and confidence to minimize issues that cause failures
166
+ cmd.extend(["-lll"]) # Use highest severity level (HIGH)
167
+ cmd.extend(["-iii"]) # Use highest confidence level (HIGH)
168
+
169
+ # Skip specific test IDs that are common false positives in development tools
170
+ # B101: assert_used (common in test/development tools)
171
+ # B110: try_except_pass (used in cleanup/error handling)
172
+ # B112: try_except_continue (used in scanning/parsing loops)
173
+ # B311: blacklist_random (used for jitter in retry mechanisms)
174
+ # B404: blacklist_import_subprocess (subprocess necessary for automation)
175
+ # B603: subprocess_without_shell_equals_true (common subprocess usage)
176
+ # B607: start_process_with_partial_path (necessary for many tools)
177
+ skip_rules = ["B101", "B110", "B112", "B311", "B404", "B603", "B607"]
178
+ cmd.extend(["-s", ",".join(skip_rules)])
179
+
180
+ # JSON output
181
+ if self.settings.use_json_output:
182
+ cmd.extend(["-f", "json"])
183
+
184
+ # Add targets
185
+ cmd.extend([str(f) for f in files])
186
+
187
+ logger.info(
188
+ "Built Bandit command with aggressive skip rules",
189
+ extra={
190
+ "file_count": len(files),
191
+ "severity": "high",
192
+ "confidence": "high",
193
+ "recursive": self.settings.recursive,
194
+ "skip_rules": skip_rules,
195
+ },
196
+ )
197
+ return cmd
198
+
199
+ async def parse_output(
200
+ self,
201
+ result: ToolExecutionResult,
202
+ ) -> list[ToolIssue]:
203
+ """Parse Bandit JSON output into standardized issues.
204
+
205
+ Args:
206
+ result: Raw execution result from Bandit
207
+
208
+ Returns:
209
+ List of parsed issues
210
+ """
211
+ if not result.raw_output:
212
+ logger.debug("No output to parse")
213
+ return []
214
+
215
+ try:
216
+ data = json.loads(result.raw_output)
217
+ logger.debug(
218
+ "Parsed Bandit JSON output",
219
+ extra={"results_count": len(data.get("results", []))},
220
+ )
221
+ except json.JSONDecodeError as e:
222
+ # Fallback to text parsing if JSON fails
223
+ logger.debug(
224
+ "JSON parse failed, falling back to text parsing",
225
+ extra={"error": str(e), "output_preview": result.raw_output[:200]},
226
+ )
227
+ return self._parse_text_output(result.raw_output)
228
+
229
+ issues = []
230
+
231
+ # Bandit JSON format:
232
+ # {
233
+ # "results": [
234
+ # {
235
+ # "code": "...",
236
+ # "filename": "path/to/file.py",
237
+ # "issue_confidence": "HIGH",
238
+ # "issue_severity": "HIGH",
239
+ # "issue_text": "...",
240
+ # "line_number": 42,
241
+ # "line_range": [42, 43],
242
+ # "more_info": "https://...",
243
+ # "test_id": "B201",
244
+ # "test_name": "flask_debug_true"
245
+ # }
246
+ # ],
247
+ # "metrics": {...}
248
+ # }
249
+
250
+ for item in data.get("results", []):
251
+ file_path = Path(item.get("filename", ""))
252
+
253
+ # Map Bandit severity to our severity levels
254
+ severity_mapping = {
255
+ "HIGH": "error",
256
+ "MEDIUM": "warning",
257
+ "LOW": "warning",
258
+ }
259
+ bandit_severity = item.get("issue_severity", "MEDIUM")
260
+ severity = severity_mapping.get(bandit_severity.upper(), "warning")
261
+
262
+ issue = ToolIssue(
263
+ file_path=file_path,
264
+ line_number=item.get("line_number"),
265
+ message=item.get("issue_text", ""),
266
+ code=item.get("test_id"),
267
+ severity=severity,
268
+ suggestion=f"Confidence: {item.get('issue_confidence', 'UNKNOWN')}, "
269
+ f"See: {item.get('more_info', '')}",
270
+ )
271
+ issues.append(issue)
272
+
273
+ logger.info(
274
+ "Parsed Bandit output",
275
+ extra={
276
+ "total_issues": len(issues),
277
+ "high_severity": sum(1 for i in issues if i.severity == "error"),
278
+ "files_affected": len({str(i.file_path) for i in issues}),
279
+ },
280
+ )
281
+ return issues
282
+
283
+ def _parse_text_output(self, output: str) -> list[ToolIssue]:
284
+ """Parse Bandit text output (fallback).
285
+
286
+ Args:
287
+ output: Text output from Bandit
288
+
289
+ Returns:
290
+ List of ToolIssue objects
291
+ """
292
+ issues = []
293
+ lines = output.strip().split("\n")
294
+
295
+ current_file: Path | None = None
296
+ current_line: int | None = None
297
+
298
+ for line in lines:
299
+ line = line.strip()
300
+
301
+ # Parse file path lines
302
+ if line.startswith(">>"):
303
+ try:
304
+ file_str = line.split(">>")[1].strip()
305
+ current_file = Path(file_str)
306
+ except (IndexError, ValueError):
307
+ continue
308
+
309
+ # Parse issue lines
310
+ elif line.startswith("Issue:") and current_file:
311
+ message = line.replace("Issue:", "").strip()
312
+ issue = ToolIssue(
313
+ file_path=current_file,
314
+ line_number=current_line,
315
+ message=message,
316
+ severity="warning",
317
+ )
318
+ issues.append(issue)
319
+
320
+ # Parse line numbers
321
+ elif "Line:" in line:
322
+ with suppress(IndexError, ValueError):
323
+ line_num_str = line.split("Line:")[1].strip()
324
+ current_line = int(line_num_str)
325
+
326
+ logger.info(
327
+ "Parsed Bandit text output (fallback)",
328
+ extra={
329
+ "total_issues": len(issues),
330
+ "files_with_issues": len(
331
+ {str(i.file_path) for i in issues if i.file_path}
332
+ ),
333
+ },
334
+ )
335
+ return issues
336
+
337
+ def _get_check_type(self) -> QACheckType:
338
+ """Return SAST check type."""
339
+ return QACheckType.SAST
340
+
341
+ def _detect_package_directory(self) -> str:
342
+ """Detect the package directory name from pyproject.toml.
343
+
344
+ Returns:
345
+ Package directory name (e.g., 'crackerjack', 'session_mgmt_mcp')
346
+ """
347
+ from contextlib import suppress
348
+
349
+ current_dir = Path.cwd()
350
+
351
+ # Try to read package name from pyproject.toml
352
+ pyproject_path = current_dir / "pyproject.toml"
353
+ if pyproject_path.exists():
354
+ with suppress(Exception):
355
+ import tomllib
356
+
357
+ with pyproject_path.open("rb") as f:
358
+ data = tomllib.load(f)
359
+
360
+ if "project" in data and "name" in data["project"]:
361
+ # Convert package name to directory name (replace - with _)
362
+ package_name = str(data["project"]["name"]).replace("-", "_")
363
+
364
+ # Verify directory exists
365
+ if (current_dir / package_name).exists():
366
+ return package_name
367
+
368
+ # Fallback to directory name if package dir exists
369
+ if (current_dir / current_dir.name).exists():
370
+ return current_dir.name
371
+
372
+ # Default fallback
373
+ return "src"
374
+
375
+ def get_default_config(self) -> QACheckConfig:
376
+ """Get default configuration for Bandit adapter.
377
+
378
+ Returns:
379
+ QACheckConfig with sensible defaults
380
+ """
381
+ from crackerjack.models.qa_config import QACheckConfig
382
+
383
+ # Dynamically detect package directory
384
+ package_dir = self._detect_package_directory()
385
+
386
+ return QACheckConfig(
387
+ check_id=MODULE_ID,
388
+ check_name=self.adapter_name,
389
+ check_type=QACheckType.SAST,
390
+ enabled=True,
391
+ file_patterns=[
392
+ f"{package_dir}/**/*.py"
393
+ ], # Dynamically detected package directory
394
+ exclude_patterns=[
395
+ "**/test_*.py",
396
+ "**/tests/**",
397
+ "**/.venv/**",
398
+ "**/venv/**",
399
+ "**/build/**",
400
+ "**/dist/**",
401
+ "**/__pycache__/**",
402
+ "**/.git/**",
403
+ "**/node_modules/**",
404
+ "**/.tox/**",
405
+ "**/.pytest_cache/**",
406
+ "**/htmlcov/**",
407
+ "**/.coverage*",
408
+ ],
409
+ timeout_seconds=1200, # Match the timeout in BanditSettings
410
+ parallel_safe=True,
411
+ stage="comprehensive", # Security checks in comprehensive stage
412
+ settings={
413
+ "severity_level": "low", # Will be overridden in command builder anyway
414
+ "confidence_level": "low", # Will be overridden in command builder anyway
415
+ "exclude_tests": True,
416
+ "skip_rules": [], # Handled in command builder with more aggressive set
417
+ },
418
+ )
419
+
420
+
421
+ # ACB Registration (REQUIRED at module level)
422
+ with suppress(Exception):
423
+ depends.set(BanditAdapter)