crackerjack 0.37.9__py3-none-any.whl → 0.45.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (425) hide show
  1. crackerjack/README.md +19 -0
  2. crackerjack/__init__.py +30 -1
  3. crackerjack/__main__.py +342 -1263
  4. crackerjack/adapters/README.md +18 -0
  5. crackerjack/adapters/__init__.py +27 -5
  6. crackerjack/adapters/_output_paths.py +167 -0
  7. crackerjack/adapters/_qa_adapter_base.py +309 -0
  8. crackerjack/adapters/_tool_adapter_base.py +706 -0
  9. crackerjack/adapters/ai/README.md +65 -0
  10. crackerjack/adapters/ai/__init__.py +5 -0
  11. crackerjack/adapters/ai/claude.py +853 -0
  12. crackerjack/adapters/complexity/README.md +53 -0
  13. crackerjack/adapters/complexity/__init__.py +10 -0
  14. crackerjack/adapters/complexity/complexipy.py +641 -0
  15. crackerjack/adapters/dependency/__init__.py +22 -0
  16. crackerjack/adapters/dependency/pip_audit.py +418 -0
  17. crackerjack/adapters/format/README.md +72 -0
  18. crackerjack/adapters/format/__init__.py +11 -0
  19. crackerjack/adapters/format/mdformat.py +313 -0
  20. crackerjack/adapters/format/ruff.py +516 -0
  21. crackerjack/adapters/lint/README.md +47 -0
  22. crackerjack/adapters/lint/__init__.py +11 -0
  23. crackerjack/adapters/lint/codespell.py +273 -0
  24. crackerjack/adapters/lsp/README.md +49 -0
  25. crackerjack/adapters/lsp/__init__.py +27 -0
  26. crackerjack/adapters/{rust_tool_manager.py → lsp/_manager.py} +3 -3
  27. crackerjack/adapters/{skylos_adapter.py → lsp/skylos.py} +59 -7
  28. crackerjack/adapters/{zuban_adapter.py → lsp/zuban.py} +3 -6
  29. crackerjack/adapters/refactor/README.md +59 -0
  30. crackerjack/adapters/refactor/__init__.py +12 -0
  31. crackerjack/adapters/refactor/creosote.py +318 -0
  32. crackerjack/adapters/refactor/refurb.py +406 -0
  33. crackerjack/adapters/refactor/skylos.py +494 -0
  34. crackerjack/adapters/sast/README.md +132 -0
  35. crackerjack/adapters/sast/__init__.py +32 -0
  36. crackerjack/adapters/sast/_base.py +201 -0
  37. crackerjack/adapters/sast/bandit.py +423 -0
  38. crackerjack/adapters/sast/pyscn.py +405 -0
  39. crackerjack/adapters/sast/semgrep.py +241 -0
  40. crackerjack/adapters/security/README.md +111 -0
  41. crackerjack/adapters/security/__init__.py +17 -0
  42. crackerjack/adapters/security/gitleaks.py +339 -0
  43. crackerjack/adapters/type/README.md +52 -0
  44. crackerjack/adapters/type/__init__.py +12 -0
  45. crackerjack/adapters/type/pyrefly.py +402 -0
  46. crackerjack/adapters/type/ty.py +402 -0
  47. crackerjack/adapters/type/zuban.py +522 -0
  48. crackerjack/adapters/utility/README.md +51 -0
  49. crackerjack/adapters/utility/__init__.py +10 -0
  50. crackerjack/adapters/utility/checks.py +884 -0
  51. crackerjack/agents/README.md +264 -0
  52. crackerjack/agents/__init__.py +40 -12
  53. crackerjack/agents/base.py +1 -0
  54. crackerjack/agents/claude_code_bridge.py +641 -0
  55. crackerjack/agents/coordinator.py +49 -53
  56. crackerjack/agents/dry_agent.py +187 -3
  57. crackerjack/agents/enhanced_coordinator.py +279 -0
  58. crackerjack/agents/enhanced_proactive_agent.py +185 -0
  59. crackerjack/agents/error_middleware.py +53 -0
  60. crackerjack/agents/formatting_agent.py +6 -8
  61. crackerjack/agents/helpers/__init__.py +9 -0
  62. crackerjack/agents/helpers/performance/__init__.py +22 -0
  63. crackerjack/agents/helpers/performance/performance_ast_analyzer.py +357 -0
  64. crackerjack/agents/helpers/performance/performance_pattern_detector.py +909 -0
  65. crackerjack/agents/helpers/performance/performance_recommender.py +572 -0
  66. crackerjack/agents/helpers/refactoring/__init__.py +22 -0
  67. crackerjack/agents/helpers/refactoring/code_transformer.py +536 -0
  68. crackerjack/agents/helpers/refactoring/complexity_analyzer.py +344 -0
  69. crackerjack/agents/helpers/refactoring/dead_code_detector.py +437 -0
  70. crackerjack/agents/helpers/test_creation/__init__.py +19 -0
  71. crackerjack/agents/helpers/test_creation/test_ast_analyzer.py +216 -0
  72. crackerjack/agents/helpers/test_creation/test_coverage_analyzer.py +643 -0
  73. crackerjack/agents/helpers/test_creation/test_template_generator.py +1031 -0
  74. crackerjack/agents/performance_agent.py +121 -1152
  75. crackerjack/agents/refactoring_agent.py +156 -655
  76. crackerjack/agents/semantic_agent.py +479 -0
  77. crackerjack/agents/semantic_helpers.py +356 -0
  78. crackerjack/agents/test_creation_agent.py +19 -1605
  79. crackerjack/api.py +5 -7
  80. crackerjack/cli/README.md +394 -0
  81. crackerjack/cli/__init__.py +1 -1
  82. crackerjack/cli/cache_handlers.py +23 -18
  83. crackerjack/cli/cache_handlers_enhanced.py +1 -4
  84. crackerjack/cli/facade.py +70 -8
  85. crackerjack/cli/formatting.py +13 -0
  86. crackerjack/cli/handlers/__init__.py +85 -0
  87. crackerjack/cli/handlers/advanced.py +103 -0
  88. crackerjack/cli/handlers/ai_features.py +62 -0
  89. crackerjack/cli/handlers/analytics.py +479 -0
  90. crackerjack/cli/handlers/changelog.py +271 -0
  91. crackerjack/cli/handlers/config_handlers.py +16 -0
  92. crackerjack/cli/handlers/coverage.py +84 -0
  93. crackerjack/cli/handlers/documentation.py +280 -0
  94. crackerjack/cli/handlers/main_handlers.py +497 -0
  95. crackerjack/cli/handlers/monitoring.py +371 -0
  96. crackerjack/cli/handlers.py +249 -49
  97. crackerjack/cli/interactive.py +8 -5
  98. crackerjack/cli/options.py +203 -110
  99. crackerjack/cli/semantic_handlers.py +292 -0
  100. crackerjack/cli/version.py +19 -0
  101. crackerjack/code_cleaner.py +60 -24
  102. crackerjack/config/README.md +472 -0
  103. crackerjack/config/__init__.py +256 -0
  104. crackerjack/config/global_lock_config.py +191 -54
  105. crackerjack/config/hooks.py +188 -16
  106. crackerjack/config/loader.py +239 -0
  107. crackerjack/config/settings.py +141 -0
  108. crackerjack/config/tool_commands.py +331 -0
  109. crackerjack/core/README.md +393 -0
  110. crackerjack/core/async_workflow_orchestrator.py +79 -53
  111. crackerjack/core/autofix_coordinator.py +22 -9
  112. crackerjack/core/container.py +10 -9
  113. crackerjack/core/enhanced_container.py +9 -9
  114. crackerjack/core/performance.py +1 -1
  115. crackerjack/core/performance_monitor.py +5 -3
  116. crackerjack/core/phase_coordinator.py +1018 -634
  117. crackerjack/core/proactive_workflow.py +3 -3
  118. crackerjack/core/retry.py +275 -0
  119. crackerjack/core/service_watchdog.py +167 -23
  120. crackerjack/core/session_coordinator.py +187 -382
  121. crackerjack/core/timeout_manager.py +161 -44
  122. crackerjack/core/workflow/__init__.py +21 -0
  123. crackerjack/core/workflow/workflow_ai_coordinator.py +863 -0
  124. crackerjack/core/workflow/workflow_event_orchestrator.py +1107 -0
  125. crackerjack/core/workflow/workflow_issue_parser.py +714 -0
  126. crackerjack/core/workflow/workflow_phase_executor.py +1158 -0
  127. crackerjack/core/workflow/workflow_security_gates.py +400 -0
  128. crackerjack/core/workflow_orchestrator.py +1247 -953
  129. crackerjack/data/README.md +11 -0
  130. crackerjack/data/__init__.py +8 -0
  131. crackerjack/data/models.py +79 -0
  132. crackerjack/data/repository.py +210 -0
  133. crackerjack/decorators/README.md +180 -0
  134. crackerjack/decorators/__init__.py +35 -0
  135. crackerjack/decorators/error_handling.py +649 -0
  136. crackerjack/decorators/error_handling_decorators.py +334 -0
  137. crackerjack/decorators/helpers.py +58 -0
  138. crackerjack/decorators/patterns.py +281 -0
  139. crackerjack/decorators/utils.py +58 -0
  140. crackerjack/docs/README.md +11 -0
  141. crackerjack/docs/generated/api/CLI_REFERENCE.md +1 -1
  142. crackerjack/documentation/README.md +11 -0
  143. crackerjack/documentation/ai_templates.py +1 -1
  144. crackerjack/documentation/dual_output_generator.py +11 -9
  145. crackerjack/documentation/reference_generator.py +104 -59
  146. crackerjack/dynamic_config.py +52 -61
  147. crackerjack/errors.py +1 -1
  148. crackerjack/events/README.md +11 -0
  149. crackerjack/events/__init__.py +16 -0
  150. crackerjack/events/telemetry.py +175 -0
  151. crackerjack/events/workflow_bus.py +346 -0
  152. crackerjack/exceptions/README.md +301 -0
  153. crackerjack/exceptions/__init__.py +5 -0
  154. crackerjack/exceptions/config.py +4 -0
  155. crackerjack/exceptions/tool_execution_error.py +245 -0
  156. crackerjack/executors/README.md +591 -0
  157. crackerjack/executors/__init__.py +2 -0
  158. crackerjack/executors/async_hook_executor.py +539 -77
  159. crackerjack/executors/cached_hook_executor.py +3 -3
  160. crackerjack/executors/hook_executor.py +967 -102
  161. crackerjack/executors/hook_lock_manager.py +31 -22
  162. crackerjack/executors/individual_hook_executor.py +66 -32
  163. crackerjack/executors/lsp_aware_hook_executor.py +136 -57
  164. crackerjack/executors/progress_hook_executor.py +282 -0
  165. crackerjack/executors/tool_proxy.py +23 -7
  166. crackerjack/hooks/README.md +485 -0
  167. crackerjack/hooks/lsp_hook.py +8 -9
  168. crackerjack/intelligence/README.md +557 -0
  169. crackerjack/interactive.py +37 -10
  170. crackerjack/managers/README.md +369 -0
  171. crackerjack/managers/async_hook_manager.py +41 -57
  172. crackerjack/managers/hook_manager.py +449 -79
  173. crackerjack/managers/publish_manager.py +81 -36
  174. crackerjack/managers/test_command_builder.py +290 -12
  175. crackerjack/managers/test_executor.py +93 -8
  176. crackerjack/managers/test_manager.py +1082 -75
  177. crackerjack/managers/test_progress.py +118 -26
  178. crackerjack/mcp/README.md +374 -0
  179. crackerjack/mcp/cache.py +25 -2
  180. crackerjack/mcp/client_runner.py +35 -18
  181. crackerjack/mcp/context.py +9 -9
  182. crackerjack/mcp/dashboard.py +24 -8
  183. crackerjack/mcp/enhanced_progress_monitor.py +34 -23
  184. crackerjack/mcp/file_monitor.py +27 -6
  185. crackerjack/mcp/progress_components.py +45 -34
  186. crackerjack/mcp/progress_monitor.py +6 -9
  187. crackerjack/mcp/rate_limiter.py +11 -7
  188. crackerjack/mcp/server.py +2 -0
  189. crackerjack/mcp/server_core.py +187 -55
  190. crackerjack/mcp/service_watchdog.py +12 -9
  191. crackerjack/mcp/task_manager.py +2 -2
  192. crackerjack/mcp/tools/README.md +27 -0
  193. crackerjack/mcp/tools/__init__.py +2 -0
  194. crackerjack/mcp/tools/core_tools.py +75 -52
  195. crackerjack/mcp/tools/execution_tools.py +87 -31
  196. crackerjack/mcp/tools/intelligence_tools.py +2 -2
  197. crackerjack/mcp/tools/proactive_tools.py +1 -1
  198. crackerjack/mcp/tools/semantic_tools.py +584 -0
  199. crackerjack/mcp/tools/utility_tools.py +180 -132
  200. crackerjack/mcp/tools/workflow_executor.py +87 -46
  201. crackerjack/mcp/websocket/README.md +31 -0
  202. crackerjack/mcp/websocket/app.py +11 -1
  203. crackerjack/mcp/websocket/event_bridge.py +188 -0
  204. crackerjack/mcp/websocket/jobs.py +27 -4
  205. crackerjack/mcp/websocket/monitoring/__init__.py +25 -0
  206. crackerjack/mcp/websocket/monitoring/api/__init__.py +19 -0
  207. crackerjack/mcp/websocket/monitoring/api/dependencies.py +141 -0
  208. crackerjack/mcp/websocket/monitoring/api/heatmap.py +154 -0
  209. crackerjack/mcp/websocket/monitoring/api/intelligence.py +199 -0
  210. crackerjack/mcp/websocket/monitoring/api/metrics.py +203 -0
  211. crackerjack/mcp/websocket/monitoring/api/telemetry.py +101 -0
  212. crackerjack/mcp/websocket/monitoring/dashboard.py +18 -0
  213. crackerjack/mcp/websocket/monitoring/factory.py +109 -0
  214. crackerjack/mcp/websocket/monitoring/filters.py +10 -0
  215. crackerjack/mcp/websocket/monitoring/metrics.py +64 -0
  216. crackerjack/mcp/websocket/monitoring/models.py +90 -0
  217. crackerjack/mcp/websocket/monitoring/utils.py +171 -0
  218. crackerjack/mcp/websocket/monitoring/websocket_manager.py +78 -0
  219. crackerjack/mcp/websocket/monitoring/websockets/__init__.py +17 -0
  220. crackerjack/mcp/websocket/monitoring/websockets/dependencies.py +126 -0
  221. crackerjack/mcp/websocket/monitoring/websockets/heatmap.py +176 -0
  222. crackerjack/mcp/websocket/monitoring/websockets/intelligence.py +291 -0
  223. crackerjack/mcp/websocket/monitoring/websockets/metrics.py +291 -0
  224. crackerjack/mcp/websocket/monitoring_endpoints.py +16 -2930
  225. crackerjack/mcp/websocket/server.py +1 -3
  226. crackerjack/mcp/websocket/websocket_handler.py +107 -6
  227. crackerjack/models/README.md +308 -0
  228. crackerjack/models/__init__.py +10 -1
  229. crackerjack/models/config.py +639 -22
  230. crackerjack/models/config_adapter.py +6 -6
  231. crackerjack/models/protocols.py +1167 -23
  232. crackerjack/models/pydantic_models.py +320 -0
  233. crackerjack/models/qa_config.py +145 -0
  234. crackerjack/models/qa_results.py +134 -0
  235. crackerjack/models/results.py +35 -0
  236. crackerjack/models/semantic_models.py +258 -0
  237. crackerjack/models/task.py +19 -3
  238. crackerjack/models/test_models.py +60 -0
  239. crackerjack/monitoring/README.md +11 -0
  240. crackerjack/monitoring/ai_agent_watchdog.py +5 -4
  241. crackerjack/monitoring/metrics_collector.py +4 -3
  242. crackerjack/monitoring/regression_prevention.py +4 -3
  243. crackerjack/monitoring/websocket_server.py +4 -241
  244. crackerjack/orchestration/README.md +340 -0
  245. crackerjack/orchestration/__init__.py +43 -0
  246. crackerjack/orchestration/advanced_orchestrator.py +20 -67
  247. crackerjack/orchestration/cache/README.md +312 -0
  248. crackerjack/orchestration/cache/__init__.py +37 -0
  249. crackerjack/orchestration/cache/memory_cache.py +338 -0
  250. crackerjack/orchestration/cache/tool_proxy_cache.py +340 -0
  251. crackerjack/orchestration/config.py +297 -0
  252. crackerjack/orchestration/coverage_improvement.py +13 -6
  253. crackerjack/orchestration/execution_strategies.py +6 -6
  254. crackerjack/orchestration/hook_orchestrator.py +1398 -0
  255. crackerjack/orchestration/strategies/README.md +401 -0
  256. crackerjack/orchestration/strategies/__init__.py +39 -0
  257. crackerjack/orchestration/strategies/adaptive_strategy.py +630 -0
  258. crackerjack/orchestration/strategies/parallel_strategy.py +237 -0
  259. crackerjack/orchestration/strategies/sequential_strategy.py +299 -0
  260. crackerjack/orchestration/test_progress_streamer.py +1 -1
  261. crackerjack/plugins/README.md +11 -0
  262. crackerjack/plugins/hooks.py +3 -2
  263. crackerjack/plugins/loader.py +3 -3
  264. crackerjack/plugins/managers.py +1 -1
  265. crackerjack/py313.py +191 -0
  266. crackerjack/security/README.md +11 -0
  267. crackerjack/services/README.md +374 -0
  268. crackerjack/services/__init__.py +8 -21
  269. crackerjack/services/ai/README.md +295 -0
  270. crackerjack/services/ai/__init__.py +7 -0
  271. crackerjack/services/ai/advanced_optimizer.py +878 -0
  272. crackerjack/services/{contextual_ai_assistant.py → ai/contextual_ai_assistant.py} +5 -3
  273. crackerjack/services/ai/embeddings.py +444 -0
  274. crackerjack/services/ai/intelligent_commit.py +328 -0
  275. crackerjack/services/ai/predictive_analytics.py +510 -0
  276. crackerjack/services/api_extractor.py +5 -3
  277. crackerjack/services/bounded_status_operations.py +45 -5
  278. crackerjack/services/cache.py +249 -318
  279. crackerjack/services/changelog_automation.py +7 -3
  280. crackerjack/services/command_execution_service.py +305 -0
  281. crackerjack/services/config_integrity.py +83 -39
  282. crackerjack/services/config_merge.py +9 -6
  283. crackerjack/services/config_service.py +198 -0
  284. crackerjack/services/config_template.py +13 -26
  285. crackerjack/services/coverage_badge_service.py +6 -4
  286. crackerjack/services/coverage_ratchet.py +53 -27
  287. crackerjack/services/debug.py +18 -7
  288. crackerjack/services/dependency_analyzer.py +4 -4
  289. crackerjack/services/dependency_monitor.py +13 -13
  290. crackerjack/services/documentation_generator.py +4 -2
  291. crackerjack/services/documentation_service.py +62 -33
  292. crackerjack/services/enhanced_filesystem.py +81 -27
  293. crackerjack/services/enterprise_optimizer.py +1 -1
  294. crackerjack/services/error_pattern_analyzer.py +10 -10
  295. crackerjack/services/file_filter.py +221 -0
  296. crackerjack/services/file_hasher.py +5 -7
  297. crackerjack/services/file_io_service.py +361 -0
  298. crackerjack/services/file_modifier.py +615 -0
  299. crackerjack/services/filesystem.py +80 -109
  300. crackerjack/services/git.py +99 -5
  301. crackerjack/services/health_metrics.py +4 -6
  302. crackerjack/services/heatmap_generator.py +12 -3
  303. crackerjack/services/incremental_executor.py +380 -0
  304. crackerjack/services/initialization.py +101 -49
  305. crackerjack/services/log_manager.py +2 -2
  306. crackerjack/services/logging.py +120 -68
  307. crackerjack/services/lsp_client.py +12 -12
  308. crackerjack/services/memory_optimizer.py +27 -22
  309. crackerjack/services/monitoring/README.md +30 -0
  310. crackerjack/services/monitoring/__init__.py +9 -0
  311. crackerjack/services/monitoring/dependency_monitor.py +678 -0
  312. crackerjack/services/monitoring/error_pattern_analyzer.py +676 -0
  313. crackerjack/services/monitoring/health_metrics.py +716 -0
  314. crackerjack/services/monitoring/metrics.py +587 -0
  315. crackerjack/services/{performance_benchmarks.py → monitoring/performance_benchmarks.py} +100 -14
  316. crackerjack/services/{performance_cache.py → monitoring/performance_cache.py} +21 -15
  317. crackerjack/services/{performance_monitor.py → monitoring/performance_monitor.py} +10 -6
  318. crackerjack/services/parallel_executor.py +166 -55
  319. crackerjack/services/patterns/__init__.py +142 -0
  320. crackerjack/services/patterns/agents.py +107 -0
  321. crackerjack/services/patterns/code/__init__.py +15 -0
  322. crackerjack/services/patterns/code/detection.py +118 -0
  323. crackerjack/services/patterns/code/imports.py +107 -0
  324. crackerjack/services/patterns/code/paths.py +159 -0
  325. crackerjack/services/patterns/code/performance.py +119 -0
  326. crackerjack/services/patterns/code/replacement.py +36 -0
  327. crackerjack/services/patterns/core.py +212 -0
  328. crackerjack/services/patterns/documentation/__init__.py +14 -0
  329. crackerjack/services/patterns/documentation/badges_markdown.py +96 -0
  330. crackerjack/services/patterns/documentation/comments_blocks.py +83 -0
  331. crackerjack/services/patterns/documentation/docstrings.py +89 -0
  332. crackerjack/services/patterns/formatting.py +226 -0
  333. crackerjack/services/patterns/operations.py +339 -0
  334. crackerjack/services/patterns/security/__init__.py +23 -0
  335. crackerjack/services/patterns/security/code_injection.py +122 -0
  336. crackerjack/services/patterns/security/credentials.py +190 -0
  337. crackerjack/services/patterns/security/path_traversal.py +221 -0
  338. crackerjack/services/patterns/security/unsafe_operations.py +216 -0
  339. crackerjack/services/patterns/templates.py +62 -0
  340. crackerjack/services/patterns/testing/__init__.py +18 -0
  341. crackerjack/services/patterns/testing/error_patterns.py +107 -0
  342. crackerjack/services/patterns/testing/pytest_output.py +126 -0
  343. crackerjack/services/patterns/tool_output/__init__.py +16 -0
  344. crackerjack/services/patterns/tool_output/bandit.py +72 -0
  345. crackerjack/services/patterns/tool_output/other.py +97 -0
  346. crackerjack/services/patterns/tool_output/pyright.py +67 -0
  347. crackerjack/services/patterns/tool_output/ruff.py +44 -0
  348. crackerjack/services/patterns/url_sanitization.py +114 -0
  349. crackerjack/services/patterns/utilities.py +42 -0
  350. crackerjack/services/patterns/utils.py +339 -0
  351. crackerjack/services/patterns/validation.py +46 -0
  352. crackerjack/services/patterns/versioning.py +62 -0
  353. crackerjack/services/predictive_analytics.py +21 -8
  354. crackerjack/services/profiler.py +280 -0
  355. crackerjack/services/quality/README.md +415 -0
  356. crackerjack/services/quality/__init__.py +11 -0
  357. crackerjack/services/quality/anomaly_detector.py +392 -0
  358. crackerjack/services/quality/pattern_cache.py +333 -0
  359. crackerjack/services/quality/pattern_detector.py +479 -0
  360. crackerjack/services/quality/qa_orchestrator.py +491 -0
  361. crackerjack/services/{quality_baseline.py → quality/quality_baseline.py} +163 -2
  362. crackerjack/services/{quality_baseline_enhanced.py → quality/quality_baseline_enhanced.py} +4 -1
  363. crackerjack/services/{quality_intelligence.py → quality/quality_intelligence.py} +180 -16
  364. crackerjack/services/regex_patterns.py +58 -2987
  365. crackerjack/services/regex_utils.py +55 -29
  366. crackerjack/services/secure_status_formatter.py +42 -15
  367. crackerjack/services/secure_subprocess.py +35 -2
  368. crackerjack/services/security.py +16 -8
  369. crackerjack/services/server_manager.py +40 -51
  370. crackerjack/services/smart_scheduling.py +46 -6
  371. crackerjack/services/status_authentication.py +3 -3
  372. crackerjack/services/thread_safe_status_collector.py +1 -0
  373. crackerjack/services/tool_filter.py +368 -0
  374. crackerjack/services/tool_version_service.py +9 -5
  375. crackerjack/services/unified_config.py +43 -351
  376. crackerjack/services/vector_store.py +689 -0
  377. crackerjack/services/version_analyzer.py +6 -4
  378. crackerjack/services/version_checker.py +14 -8
  379. crackerjack/services/zuban_lsp_service.py +5 -4
  380. crackerjack/slash_commands/README.md +11 -0
  381. crackerjack/slash_commands/init.md +2 -12
  382. crackerjack/slash_commands/run.md +84 -50
  383. crackerjack/tools/README.md +11 -0
  384. crackerjack/tools/__init__.py +30 -0
  385. crackerjack/tools/_git_utils.py +105 -0
  386. crackerjack/tools/check_added_large_files.py +139 -0
  387. crackerjack/tools/check_ast.py +105 -0
  388. crackerjack/tools/check_json.py +103 -0
  389. crackerjack/tools/check_jsonschema.py +297 -0
  390. crackerjack/tools/check_toml.py +103 -0
  391. crackerjack/tools/check_yaml.py +110 -0
  392. crackerjack/tools/codespell_wrapper.py +72 -0
  393. crackerjack/tools/end_of_file_fixer.py +202 -0
  394. crackerjack/tools/format_json.py +128 -0
  395. crackerjack/tools/mdformat_wrapper.py +114 -0
  396. crackerjack/tools/trailing_whitespace.py +198 -0
  397. crackerjack/tools/validate_regex_patterns.py +7 -3
  398. crackerjack/ui/README.md +11 -0
  399. crackerjack/ui/dashboard_renderer.py +28 -0
  400. crackerjack/ui/templates/README.md +11 -0
  401. crackerjack/utils/console_utils.py +13 -0
  402. crackerjack/utils/dependency_guard.py +230 -0
  403. crackerjack/utils/retry_utils.py +275 -0
  404. crackerjack/workflows/README.md +590 -0
  405. crackerjack/workflows/__init__.py +46 -0
  406. crackerjack/workflows/actions.py +811 -0
  407. crackerjack/workflows/auto_fix.py +444 -0
  408. crackerjack/workflows/container_builder.py +499 -0
  409. crackerjack/workflows/definitions.py +443 -0
  410. crackerjack/workflows/engine.py +177 -0
  411. crackerjack/workflows/event_bridge.py +242 -0
  412. {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/METADATA +678 -98
  413. crackerjack-0.45.2.dist-info/RECORD +478 -0
  414. {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/WHEEL +1 -1
  415. crackerjack/managers/test_manager_backup.py +0 -1075
  416. crackerjack/mcp/tools/execution_tools_backup.py +0 -1011
  417. crackerjack/mixins/__init__.py +0 -3
  418. crackerjack/mixins/error_handling.py +0 -145
  419. crackerjack/services/config.py +0 -358
  420. crackerjack/ui/server_panels.py +0 -125
  421. crackerjack-0.37.9.dist-info/RECORD +0 -231
  422. /crackerjack/adapters/{rust_tool_adapter.py → lsp/_base.py} +0 -0
  423. /crackerjack/adapters/{lsp_client.py → lsp/_client.py} +0 -0
  424. {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/entry_points.txt +0 -0
  425. {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,494 @@
1
+ """Skylos adapter for ACB QA framework - dead code detection.
2
+
3
+ Skylos identifies unused imports, functions, classes, and variables in Python codebases.
4
+ It helps maintain clean code by detecting elements that are no longer used.
5
+
6
+ ACB Patterns:
7
+ - MODULE_ID and MODULE_STATUS at module level
8
+ - depends.set() registration after class definition
9
+ - Extends BaseToolAdapter for tool execution
10
+ - Async execution with output parsing
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import json
16
+ import logging
17
+ import typing as t
18
+ from contextlib import suppress
19
+ from pathlib import Path
20
+ from uuid import UUID
21
+
22
+ from acb.depends import depends
23
+
24
+ from crackerjack.adapters._tool_adapter_base import (
25
+ BaseToolAdapter,
26
+ ToolAdapterSettings,
27
+ ToolExecutionResult,
28
+ ToolIssue,
29
+ )
30
+ from crackerjack.models.qa_results import QACheckType
31
+
32
+ if t.TYPE_CHECKING:
33
+ from crackerjack.models.qa_config import QACheckConfig
34
+
35
+ # ACB Module Registration (REQUIRED)
36
+ MODULE_ID = UUID(
37
+ "01937d86-5f2a-7b3c-9d1e-a2b3c4d5e6f8"
38
+ ) # Static UUID7 for reproducible module identity
39
+ MODULE_STATUS = "stable"
40
+
41
+ # Module-level logger for structured logging
42
+ logger = logging.getLogger(__name__)
43
+
44
+
45
+ class SkylosSettings(ToolAdapterSettings):
46
+ """Settings for Skylos adapter."""
47
+
48
+ tool_name: str = "skylos"
49
+ use_json_output: bool = True # Skylos supports JSON output
50
+ confidence_threshold: int = 86
51
+ web_dashboard_port: int = 5090
52
+
53
+
54
+ class SkylosAdapter(BaseToolAdapter):
55
+ """Adapter for Skylos - dead code detector.
56
+
57
+ Identifies unused imports, functions, classes, variables, and other code elements.
58
+ Helps maintain clean codebases by detecting dead code that can be safely removed.
59
+
60
+ Features:
61
+ - Confidence-based detection
62
+ - JSON output for structured analysis
63
+ - Integration with web dashboard
64
+ - Configurable confidence thresholds
65
+
66
+ Example:
67
+ ```python
68
+ settings = SkylosSettings(
69
+ confidence_threshold=90,
70
+ web_dashboard_port=5091,
71
+ )
72
+ adapter = SkylosAdapter(settings=settings)
73
+ await adapter.init()
74
+ result = await adapter.check(files=[Path("src/")])
75
+ ```
76
+ """
77
+
78
+ settings: SkylosSettings | None = None
79
+
80
+ def __init__(self, settings: SkylosSettings | None = None) -> None:
81
+ """Initialize Skylos adapter.
82
+
83
+ Args:
84
+ settings: Optional settings override
85
+ """
86
+ super().__init__(settings=settings)
87
+ logger.debug(
88
+ "SkylosAdapter initialized", extra={"has_settings": settings is not None}
89
+ )
90
+
91
+ async def init(self) -> None:
92
+ """Initialize adapter with default settings."""
93
+ if not self.settings:
94
+ self.settings = SkylosSettings()
95
+ logger.info("Using default SkylosSettings")
96
+ await super().init()
97
+ logger.debug(
98
+ "SkylosAdapter initialization complete",
99
+ extra={"confidence_threshold": self.settings.confidence_threshold},
100
+ )
101
+
102
+ @property
103
+ def adapter_name(self) -> str:
104
+ """Human-readable adapter name."""
105
+ return "Skylos (Dead Code)"
106
+
107
+ @property
108
+ def module_id(self) -> UUID:
109
+ """Reference to module-level MODULE_ID."""
110
+ return MODULE_ID
111
+
112
+ @property
113
+ def tool_name(self) -> str:
114
+ """CLI tool name."""
115
+ return "skylos"
116
+
117
+ def build_command(
118
+ self,
119
+ files: list[Path],
120
+ config: QACheckConfig | None = None,
121
+ ) -> list[str]:
122
+ """Build Skylos command.
123
+
124
+ Args:
125
+ files: Files/directories to scan for dead code
126
+ config: Optional configuration override
127
+
128
+ Returns:
129
+ Command as list of strings
130
+ """
131
+ if not self.settings:
132
+ raise RuntimeError("Settings not initialized")
133
+
134
+ cmd = ["uv", "run", "skylos"]
135
+
136
+ # Add confidence threshold
137
+ cmd.extend(["--confidence", str(self.settings.confidence_threshold)])
138
+
139
+ # JSON output for structured parsing
140
+ if self.settings.use_json_output:
141
+ cmd.append("--json")
142
+
143
+ # Add targets - use package directory to avoid scanning .venv
144
+ target = self._determine_scan_target(files)
145
+ cmd.append(target)
146
+
147
+ logger.info(
148
+ "Built Skylos command",
149
+ extra={
150
+ "file_count": len(files) if files else 1,
151
+ "confidence_threshold": self.settings.confidence_threshold,
152
+ "target_directory": target,
153
+ },
154
+ )
155
+ return cmd
156
+
157
+ def _determine_scan_target(self, files: list[Path]) -> str:
158
+ """Determine the target directory or files for scanning.
159
+
160
+ Args:
161
+ files: Files specified by user
162
+
163
+ Returns:
164
+ Target string for Skylos command
165
+ """
166
+ if files:
167
+ # Join multiple files into a single string
168
+ return " ".join(str(f) for f in files)
169
+
170
+ # Auto-detect package directory
171
+ package_name = self._detect_package_name()
172
+ return f"./{package_name}"
173
+
174
+ def _detect_package_name(self) -> str:
175
+ """Detect package name from pyproject.toml or directory structure.
176
+
177
+ Returns:
178
+ Package name to scan
179
+ """
180
+ cwd = Path.cwd()
181
+
182
+ # Try reading from pyproject.toml
183
+ package_name = self._read_package_from_toml(cwd)
184
+ if package_name:
185
+ return package_name
186
+
187
+ # Fallback: find first directory with __init__.py
188
+ package_name = self._find_package_directory(cwd)
189
+ if package_name:
190
+ return package_name
191
+
192
+ # Default fallback
193
+ return "crackerjack"
194
+
195
+ def _read_package_from_toml(self, cwd: Path) -> str | None:
196
+ """Read package name from pyproject.toml.
197
+
198
+ Args:
199
+ cwd: Current working directory
200
+
201
+ Returns:
202
+ Package name if found, None otherwise
203
+ """
204
+ import tomllib
205
+ from contextlib import suppress
206
+
207
+ pyproject_path = cwd / "pyproject.toml"
208
+ if not pyproject_path.exists():
209
+ return None
210
+
211
+ with suppress(Exception):
212
+ with pyproject_path.open("rb") as f:
213
+ data = tomllib.load(f)
214
+ project_name = data.get("project", {}).get("name")
215
+ if project_name:
216
+ return project_name.replace("-", "_")
217
+
218
+ return None
219
+
220
+ def _find_package_directory(self, cwd: Path) -> str | None:
221
+ """Find package directory with __init__.py.
222
+
223
+ Args:
224
+ cwd: Current working directory
225
+
226
+ Returns:
227
+ Package directory name if found, None otherwise
228
+ """
229
+ excluded = {"tests", "docs", ".venv", "venv", "build", "dist"}
230
+
231
+ for item in cwd.iterdir():
232
+ if item.is_dir() and (item / "__init__.py").exists():
233
+ if item.name not in excluded:
234
+ return item.name
235
+
236
+ return None
237
+
238
+ async def parse_output(
239
+ self,
240
+ result: ToolExecutionResult,
241
+ ) -> list[ToolIssue]:
242
+ """Parse Skylos output into standardized issues.
243
+
244
+ Args:
245
+ result: Raw execution result from Skylos
246
+
247
+ Returns:
248
+ List of parsed issues
249
+ """
250
+ if not result.raw_output:
251
+ logger.debug("No output to parse")
252
+ return []
253
+
254
+ # Try JSON parsing first, fallback to text parsing
255
+ try:
256
+ issues = self._parse_json_output(result.raw_output)
257
+ except json.JSONDecodeError:
258
+ logger.debug(
259
+ "JSON parse failed, falling back to text parsing",
260
+ extra={"output_preview": result.raw_output[:200]},
261
+ )
262
+ issues = self._parse_text_output(result.raw_output)
263
+
264
+ logger.info(
265
+ "Parsed Skylos output",
266
+ extra={
267
+ "total_issues": len(issues),
268
+ "files_affected": len({str(i.file_path) for i in issues}),
269
+ },
270
+ )
271
+ return issues
272
+
273
+ def _parse_json_output(self, output: str) -> list[ToolIssue]:
274
+ """Parse Skylos JSON output.
275
+
276
+ Args:
277
+ output: JSON output from Skylos
278
+
279
+ Returns:
280
+ List of parsed issues
281
+ """
282
+ data = json.loads(output)
283
+ logger.debug(
284
+ "Parsed Skylos JSON output",
285
+ extra={"results_count": len(data.get("dead_code", []))},
286
+ )
287
+
288
+ issues = []
289
+ for item in data.get("dead_code", []):
290
+ issue = self._create_issue_from_json(item)
291
+ issues.append(issue)
292
+
293
+ return issues
294
+
295
+ def _create_issue_from_json(self, item: dict) -> ToolIssue:
296
+ """Create ToolIssue from JSON item.
297
+
298
+ Args:
299
+ item: JSON item representing dead code
300
+
301
+ Returns:
302
+ ToolIssue object
303
+ """
304
+ file_path = Path(item.get("file", ""))
305
+ code_type = item.get("type", "code")
306
+ code_name = item.get("name", "")
307
+ confidence = item.get("confidence", "unknown")
308
+
309
+ return ToolIssue(
310
+ file_path=file_path,
311
+ line_number=item.get("line"),
312
+ message=f"Dead {code_type}: {code_name}",
313
+ code=code_type,
314
+ severity="warning", # Dead code is typically a warning
315
+ suggestion=f"Confidence: {confidence}%",
316
+ )
317
+
318
+ def _parse_text_output(self, output: str) -> list[ToolIssue]:
319
+ """Parse Skylos text output (fallback).
320
+
321
+ Args:
322
+ output: Text output from Skylos
323
+
324
+ Returns:
325
+ List of ToolIssue objects
326
+ """
327
+ issues = []
328
+ lines = output.strip().split("\n")
329
+
330
+ for line in lines:
331
+ line = line.strip()
332
+ if not line or ":" not in line:
333
+ continue
334
+
335
+ issue = self._parse_text_line(line)
336
+ if issue:
337
+ issues.append(issue)
338
+
339
+ logger.info(
340
+ "Parsed Skylos text output (fallback)",
341
+ extra={"total_issues": len(issues)},
342
+ )
343
+ return issues
344
+
345
+ def _parse_text_line(self, line: str) -> ToolIssue | None:
346
+ """Parse a single Skylos text output line.
347
+
348
+ Args:
349
+ line: Line of text output
350
+
351
+ Returns:
352
+ ToolIssue if parsing successful, None otherwise
353
+ """
354
+ try:
355
+ # Parse format: "file.py:line: message (confidence: XX%)"
356
+ parts = line.split(":", 2)
357
+ if len(parts) < 3:
358
+ return None
359
+
360
+ file_path = Path(parts[0].strip())
361
+ line_number = self._parse_line_number(parts[1])
362
+ message_part = parts[2].strip()
363
+
364
+ confidence = self._extract_confidence_from_message(message_part)
365
+
366
+ return ToolIssue(
367
+ file_path=file_path,
368
+ line_number=line_number,
369
+ message=message_part,
370
+ severity="warning",
371
+ suggestion=f"Confidence: {confidence}",
372
+ )
373
+
374
+ except (ValueError, IndexError):
375
+ return None
376
+
377
+ def _parse_line_number(self, line_part: str) -> int | None:
378
+ """Parse line number from text part.
379
+
380
+ Args:
381
+ line_part: Part containing line number
382
+
383
+ Returns:
384
+ Line number if valid, None otherwise
385
+ """
386
+ try:
387
+ return int(line_part.strip())
388
+ except ValueError:
389
+ return None
390
+
391
+ def _extract_confidence_from_message(self, message_part: str) -> str:
392
+ """Extract confidence percentage from message.
393
+
394
+ Args:
395
+ message_part: Message containing confidence info
396
+
397
+ Returns:
398
+ Confidence value or "unknown"
399
+ """
400
+ if "(confidence:" not in message_part:
401
+ return "unknown"
402
+
403
+ conf_start = message_part.find("(confidence:") + len("(confidence:")
404
+ conf_end = message_part.find(")", conf_start)
405
+ if conf_end != -1:
406
+ return message_part[conf_start:conf_end].strip()
407
+
408
+ return "unknown"
409
+
410
+ def _get_check_type(self) -> QACheckType:
411
+ """Return refactor check type."""
412
+ return QACheckType.REFACTOR
413
+
414
+ def _detect_package_directory(self) -> str:
415
+ """Detect the package directory name from pyproject.toml.
416
+
417
+ Returns:
418
+ Package directory name (e.g., 'crackerjack', 'session_mgmt_mcp')
419
+ """
420
+ from contextlib import suppress
421
+
422
+ current_dir = Path.cwd()
423
+
424
+ # Try to read package name from pyproject.toml
425
+ pyproject_path = current_dir / "pyproject.toml"
426
+ if pyproject_path.exists():
427
+ with suppress(Exception):
428
+ import tomllib
429
+
430
+ with pyproject_path.open("rb") as f:
431
+ data = tomllib.load(f)
432
+
433
+ if "project" in data and "name" in data["project"]:
434
+ # Convert package name to directory name (replace - with _)
435
+ package_name = str(data["project"]["name"]).replace("-", "_")
436
+
437
+ # Verify directory exists
438
+ if (current_dir / package_name).exists():
439
+ return package_name
440
+
441
+ # Fallback to directory name if package dir exists
442
+ if (current_dir / current_dir.name).exists():
443
+ return current_dir.name
444
+
445
+ # Default fallback
446
+ return "src"
447
+
448
+ def get_default_config(self) -> QACheckConfig:
449
+ """Get default configuration for Skylos adapter.
450
+
451
+ Returns:
452
+ QACheckConfig with sensible defaults
453
+ """
454
+ from crackerjack.models.qa_config import QACheckConfig
455
+
456
+ # Dynamically detect package directory
457
+ package_dir = self._detect_package_directory()
458
+
459
+ return QACheckConfig(
460
+ check_id=MODULE_ID,
461
+ check_name=self.adapter_name,
462
+ check_type=QACheckType.REFACTOR, # Dead code detection is refactoring
463
+ enabled=True,
464
+ file_patterns=[
465
+ f"{package_dir}/**/*.py"
466
+ ], # Dynamically detected package directory
467
+ exclude_patterns=[
468
+ "**/test_*.py",
469
+ "**/tests/**",
470
+ "**/.venv/**",
471
+ "**/venv/**",
472
+ "**/build/**",
473
+ "**/dist/**",
474
+ "**/__pycache__/**",
475
+ "**/.git/**",
476
+ "**/node_modules/**",
477
+ "**/.tox/**",
478
+ "**/.pytest_cache/**",
479
+ "**/htmlcov/**",
480
+ "**/.coverage*",
481
+ ],
482
+ timeout_seconds=300,
483
+ parallel_safe=True,
484
+ stage="comprehensive", # Dead code detection in comprehensive stage
485
+ settings={
486
+ "confidence_threshold": 86,
487
+ "web_dashboard_port": 5090,
488
+ },
489
+ )
490
+
491
+
492
+ # ACB Registration (REQUIRED at module level)
493
+ with suppress(Exception):
494
+ depends.set(SkylosAdapter)
@@ -0,0 +1,132 @@
1
+ > Crackerjack Docs: [Main](<../../../README.md>) | [Adapters](<../README.md>) | [SAST](<./README.md>)
2
+
3
+ # SAST Adapters
4
+
5
+ Static Application Security Testing tools for finding code vulnerabilities and security anti-patterns.
6
+
7
+ ## Overview
8
+
9
+ SAST (Static Application Security Testing) adapters analyze source code for security vulnerabilities, insecure practices, and exploitable weaknesses. Unlike secret detection (gitleaks), SAST tools focus on application code quality and security patterns.
10
+
11
+ ## Built-in Implementations
12
+
13
+ | Module | Description | Status | Recommended |
14
+ | ------ | ----------- | ------ | ----------- |
15
+ | `semgrep.py` | Multi-language static analysis with extensive rulesets | Stable | ✅ Primary |
16
+ | `bandit.py` | Python security linter with severity/confidence thresholds | Stable | Legacy |
17
+ | `pyscn.py` | Python security static analyzer | Experimental | ❌ No |
18
+
19
+ ## Protocol Interface
20
+
21
+ All SAST adapters implement `SASTAdapterProtocol` defined in `_base.py`:
22
+
23
+ ```python
24
+ from crackerjack.adapters.sast import SASTAdapterProtocol, SemgrepAdapter
25
+
26
+ adapter: SASTAdapterProtocol = SemgrepAdapter()
27
+ await adapter.init()
28
+ result = await adapter.check(files=[Path("src/")])
29
+ ```
30
+
31
+ ## Recommended: Semgrep
32
+
33
+ Semgrep is the recommended SAST tool for Crackerjack due to:
34
+
35
+ - **Multi-language support** (Python, JS, Go, etc.)
36
+ - **Extensive rulesets** (`p/security-audit`, `p/python`, custom rules)
37
+ - **Active development** (r2c/semgrep community)
38
+ - **Better accuracy** than legacy Python-only tools
39
+
40
+ ### Example: Semgrep
41
+
42
+ ```python
43
+ from pathlib import Path
44
+ from crackerjack.adapters.sast.semgrep import SemgrepAdapter, SemgrepSettings
45
+
46
+
47
+ async def run_semgrep() -> None:
48
+ adapter = SemgrepAdapter(
49
+ settings=SemgrepSettings(
50
+ config="p/security-audit", # Comprehensive security ruleset
51
+ exclude_tests=True,
52
+ )
53
+ )
54
+ await adapter.init()
55
+ result = await adapter.check(files=[Path("src/")])
56
+
57
+ for issue in result.issues:
58
+ print(f"{issue.severity}: {issue.file_path}:{issue.line_number}")
59
+ print(f" {issue.message}")
60
+ ```
61
+
62
+ ## Legacy: Bandit
63
+
64
+ Bandit remains available but is superseded by Semgrep:
65
+
66
+ ```python
67
+ from pathlib import Path
68
+ from crackerjack.adapters.sast.bandit import BanditAdapter, BanditSettings
69
+
70
+
71
+ async def run_bandit() -> None:
72
+ adapter = BanditAdapter(
73
+ settings=BanditSettings(
74
+ severity_level="high", # Reduce noise
75
+ confidence_level="high",
76
+ )
77
+ )
78
+ await adapter.init()
79
+ result = await adapter.check(files=[Path("src/")])
80
+ ```
81
+
82
+ ## Configuration
83
+
84
+ ### SAST in Comprehensive Hooks
85
+
86
+ SAST tools run in the **comprehensive stage** (after fast hooks):
87
+
88
+ ```python
89
+ # crackerjack/config/hooks.py
90
+ HookDefinition(
91
+ name="semgrep",
92
+ command=[],
93
+ timeout=1200, # 20 minutes for thorough scanning
94
+ stage=HookStage.COMPREHENSIVE,
95
+ manual_stage=True,
96
+ security_level=SecurityLevel.CRITICAL,
97
+ use_precommit_legacy=False,
98
+ accepts_file_paths=True,
99
+ )
100
+ ```
101
+
102
+ ### QACheckType
103
+
104
+ All SAST adapters use `QACheckType.SAST`:
105
+
106
+ ```python
107
+ from crackerjack.models.qa_results import QACheckType
108
+
109
+ # SAST = code vulnerability analysis
110
+ # SECURITY = secret leak prevention (gitleaks)
111
+ assert adapter._get_check_type() == QACheckType.SAST
112
+ ```
113
+
114
+ ## Comparison: SAST vs Security
115
+
116
+ | Category | Purpose | Tools | Stage | Scope |
117
+ |----------|---------|-------|-------|-------|
118
+ | **SAST** | Find code vulnerabilities | Semgrep, Bandit, Pyscn | Comprehensive | `**/*.py` |
119
+ | **Security** | Prevent credential leaks | Gitleaks | Fast | `**/*` |
120
+
121
+ ## Notes
122
+
123
+ - **Semgrep is recommended** for new projects and comprehensive coverage
124
+ - Bandit legacy support maintained for existing workflows
125
+ - Pyscn is experimental and disabled by default
126
+ - SAST tools complement (not replace) secret detection
127
+
128
+ ## Related
129
+
130
+ - [Security](<../security/README.md>) — Secret leak prevention with Gitleaks
131
+ - [Type](<../type/README.md>) — Type safety prevents classes of vulnerabilities
132
+ - [Lint](<../lint/README.md>) — Code quality supports secure coding practices
@@ -0,0 +1,32 @@
1
+ """SAST (Static Application Security Testing) adapters for ACB QA framework.
2
+
3
+ This package contains adapters for static application security testing tools
4
+ that analyze source code for vulnerabilities, security anti-patterns, and
5
+ exploitable weaknesses.
6
+
7
+ Tools:
8
+ - Semgrep: Multi-language static analysis with custom rules (recommended)
9
+ - Bandit: Python-specific security linter (legacy)
10
+ - Pyscn: Python security static analyzer (experimental)
11
+
12
+ Protocol:
13
+ - SASTAdapterProtocol: Protocol interface for all SAST adapters
14
+ """
15
+
16
+ from crackerjack.adapters.sast._base import SASTAdapter, SASTAdapterProtocol
17
+ from crackerjack.adapters.sast.bandit import BanditAdapter, BanditSettings
18
+ from crackerjack.adapters.sast.pyscn import PyscnAdapter, PyscnSettings
19
+ from crackerjack.adapters.sast.semgrep import SemgrepAdapter, SemgrepSettings
20
+
21
+ __all__ = [
22
+ # Protocol
23
+ "SASTAdapter",
24
+ "SASTAdapterProtocol",
25
+ # Adapters
26
+ "BanditAdapter",
27
+ "BanditSettings",
28
+ "PyscnAdapter",
29
+ "PyscnSettings",
30
+ "SemgrepAdapter",
31
+ "SemgrepSettings",
32
+ ]