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
@@ -126,6 +126,59 @@ def find_safe_pattern_for_text(text: str) -> list[str]:
126
126
  return matches
127
127
 
128
128
 
129
+ def _determine_suggested_name(original_pattern: str) -> str:
130
+ """Determine a suggested name for the pattern based on its content.
131
+
132
+ Args:
133
+ original_pattern: The regex pattern to analyze
134
+
135
+ Returns:
136
+ Suggested pattern name
137
+ """
138
+ if "python.*-.*m" in original_pattern:
139
+ return "fix_python_command_spacing"
140
+ if r"\-\s*\-" in original_pattern:
141
+ return "fix_double_dash_spacing"
142
+ if "token" in original_pattern.lower():
143
+ return "fix_token_pattern"
144
+ if "password" in original_pattern.lower():
145
+ return "fix_password_pattern"
146
+
147
+ keyword_pattern = CompiledPatternCache.get_compiled_pattern(r"[a-zA-Z]+")
148
+ keywords = keyword_pattern.findall(original_pattern)
149
+ if keywords:
150
+ return f"fix_{'_'.join(keywords[:3])}_pattern".lower()
151
+
152
+ return "fix_custom_pattern"
153
+
154
+
155
+ def _build_test_cases(original_pattern: str, sample_text: str) -> list[tuple[str, str]]:
156
+ """Build test cases based on pattern and sample text.
157
+
158
+ Args:
159
+ original_pattern: The regex pattern
160
+ sample_text: Optional sample text to include
161
+
162
+ Returns:
163
+ List of (input, expected_output) test case tuples
164
+ """
165
+ test_cases = []
166
+
167
+ if sample_text:
168
+ test_cases.append((sample_text, "Expected output needed"))
169
+
170
+ if "-" in original_pattern:
171
+ test_cases.extend(
172
+ [
173
+ ("word - word", "word-word"),
174
+ ("already-good", "already-good"),
175
+ ("multiple - word - spacing", "multiple-word - spacing"),
176
+ ]
177
+ )
178
+
179
+ return test_cases
180
+
181
+
129
182
  def suggest_migration_for_re_sub(
130
183
  original_pattern: str, original_replacement: str, sample_text: str = ""
131
184
  ) -> dict[str, t.Any]:
@@ -157,35 +210,8 @@ def suggest_migration_for_re_sub(
157
210
  if matches:
158
211
  suggestion["needs_new_pattern"] = False
159
212
 
160
- if "python.*-.*m" in original_pattern:
161
- suggestion["suggested_name"] = "fix_python_command_spacing"
162
- elif r"\-\s*\-" in original_pattern:
163
- suggestion["suggested_name"] = "fix_double_dash_spacing"
164
- elif "token" in original_pattern.lower():
165
- suggestion["suggested_name"] = "fix_token_pattern"
166
- elif "password" in original_pattern.lower():
167
- suggestion["suggested_name"] = "fix_password_pattern"
168
- else:
169
- keyword_pattern = CompiledPatternCache.get_compiled_pattern(r"[a-zA-Z]+")
170
- keywords = keyword_pattern.findall(original_pattern)
171
- if keywords:
172
- suggestion["suggested_name"] = (
173
- f"fix_{'_'.join(keywords[:3])}_pattern".lower()
174
- )
175
- else:
176
- suggestion["suggested_name"] = "fix_custom_pattern"
177
-
178
- if sample_text:
179
- suggestion["test_cases_needed"].append((sample_text, "Expected output needed"))
180
-
181
- if "-" in original_pattern:
182
- suggestion["test_cases_needed"].extend(
183
- [
184
- ("word - word", "word-word"),
185
- ("already-good", "already-good"),
186
- ("multiple - word - spacing", "multiple-word - spacing"),
187
- ]
188
- )
213
+ suggestion["suggested_name"] = _determine_suggested_name(original_pattern)
214
+ suggestion["test_cases_needed"] = _build_test_cases(original_pattern, sample_text)
189
215
 
190
216
  return suggestion
191
217
 
@@ -1,8 +1,13 @@
1
1
  import tempfile
2
+ import time
2
3
  import typing as t
4
+ from contextlib import suppress
3
5
  from enum import Enum
4
6
  from pathlib import Path
5
7
 
8
+ from crackerjack.models.protocols import SecureStatusFormatterProtocol, ServiceProtocol
9
+
10
+ from .regex_patterns import SAFE_PATTERNS, CompiledPatternCache, sanitize_internal_urls
6
11
  from .security_logger import get_security_logger
7
12
 
8
13
 
@@ -13,7 +18,7 @@ class StatusVerbosity(str, Enum):
13
18
  FULL = "full"
14
19
 
15
20
 
16
- class SecureStatusFormatter:
21
+ class SecureStatusFormatter(SecureStatusFormatterProtocol, ServiceProtocol):
17
22
  SENSITIVE_PATTERNS = {
18
23
  "absolute_paths": [
19
24
  r"(/[^/\s]*){2, }",
@@ -64,6 +69,42 @@ class SecureStatusFormatter:
64
69
  self.project_root = project_root or Path.cwd()
65
70
  self.security_logger = get_security_logger()
66
71
 
72
+ def initialize(self) -> None:
73
+ pass
74
+
75
+ def cleanup(self) -> None:
76
+ pass
77
+
78
+ def health_check(self) -> bool:
79
+ return True
80
+
81
+ def shutdown(self) -> None:
82
+ pass
83
+
84
+ def metrics(self) -> dict[str, t.Any]:
85
+ return {}
86
+
87
+ def is_healthy(self) -> bool:
88
+ return True
89
+
90
+ def register_resource(self, resource: t.Any) -> None:
91
+ pass
92
+
93
+ def cleanup_resource(self, resource: t.Any) -> None:
94
+ pass
95
+
96
+ def record_error(self, error: Exception) -> None:
97
+ pass
98
+
99
+ def increment_requests(self) -> None:
100
+ pass
101
+
102
+ def get_custom_metric(self, name: str) -> t.Any:
103
+ return None
104
+
105
+ def set_custom_metric(self, name: str, value: t.Any) -> None:
106
+ pass
107
+
67
108
  def format_status(
68
109
  self,
69
110
  status_data: dict[str, t.Any],
@@ -181,8 +222,6 @@ class SecureStatusFormatter:
181
222
  return text
182
223
 
183
224
  def _sanitize_paths(self, text: str) -> str:
184
- from .regex_patterns import SAFE_PATTERNS
185
-
186
225
  unix_path_pattern = SAFE_PATTERNS.get("detect_absolute_unix_paths")
187
226
 
188
227
  if not unix_path_pattern:
@@ -202,10 +241,6 @@ class SecureStatusFormatter:
202
241
  return text
203
242
 
204
243
  def _process_path_pattern(self, text: str, pattern_str: str) -> str:
205
- from contextlib import suppress
206
-
207
- from .regex_patterns import CompiledPatternCache
208
-
209
244
  with suppress(Exception):
210
245
  compiled = CompiledPatternCache.get_compiled_pattern(pattern_str)
211
246
  matches = compiled.findall(text)
@@ -236,8 +271,6 @@ class SecureStatusFormatter:
236
271
  return text.replace(match, "[REDACTED_PATH]")
237
272
 
238
273
  def _sanitize_internal_urls(self, text: str) -> str:
239
- from .regex_patterns import sanitize_internal_urls
240
-
241
274
  return sanitize_internal_urls(text)
242
275
 
243
276
  def _mask_potential_secrets(self, text: str) -> str:
@@ -254,8 +287,6 @@ class SecureStatusFormatter:
254
287
  return "[INTERNAL_URL]" in text or "[REDACTED_PATH]" in text
255
288
 
256
289
  def _get_validated_secret_patterns(self) -> list[t.Any]:
257
- from .regex_patterns import SAFE_PATTERNS
258
-
259
290
  patterns = []
260
291
  long_alphanumeric = SAFE_PATTERNS.get("detect_long_alphanumeric_tokens")
261
292
  base64_like = SAFE_PATTERNS.get("detect_base64_like_strings")
@@ -278,8 +309,6 @@ class SecureStatusFormatter:
278
309
  def _apply_fallback_secret_patterns(self, text: str) -> str:
279
310
  for pattern_str in self.SENSITIVE_PATTERNS["secrets"]:
280
311
  try:
281
- from .regex_patterns import CompiledPatternCache
282
-
283
312
  compiled = CompiledPatternCache.get_compiled_pattern(pattern_str)
284
313
  text = self._mask_pattern_matches(text, compiled.findall(text))
285
314
  except Exception:
@@ -317,8 +346,6 @@ class SecureStatusFormatter:
317
346
  return obj
318
347
 
319
348
  def _get_timestamp(self) -> float:
320
- import time
321
-
322
349
  return time.time()
323
350
 
324
351
  def format_error_response(
@@ -445,9 +445,42 @@ class SecureSubprocessExecutor:
445
445
  try:
446
446
  resolved_path = cwd_path.resolve()
447
447
 
448
+ # Get the original path's components to check for path traversal patterns
449
+ original_path_obj = Path(cwd)
450
+ original_parts = original_path_obj.parts
451
+ if ".." in original_parts or any(
452
+ part.startswith("../") for part in original_parts
453
+ ):
454
+ # Check if the resolved path is within the safe base (project directory or temp)
455
+ safe_root = (
456
+ Path.cwd().parent.resolve()
457
+ ) # Use parent of project root as broader safe root
458
+ try:
459
+ resolved_path.relative_to(safe_root)
460
+ except ValueError:
461
+ # If relative_to raises ValueError, path is outside safe root
462
+ path_str = str(resolved_path)
463
+ self.security_logger.log_path_traversal_attempt(
464
+ attempted_path=path_str,
465
+ base_directory=str(safe_root),
466
+ )
467
+ raise CommandValidationError(
468
+ f"Dangerous working directory: {path_str}"
469
+ )
470
+
448
471
  path_str = str(resolved_path)
449
- if ".." in path_str or path_str.startswith(
450
- ("/etc", "/usr/bin", "/bin", "/sbin")
472
+ # Check for system directories, including macOS /private variants
473
+ if path_str.startswith(
474
+ (
475
+ "/etc",
476
+ "/usr/bin",
477
+ "/bin",
478
+ "/sbin",
479
+ "/private/etc",
480
+ "/private/usr/bin",
481
+ "/private/bin",
482
+ "/private/sbin",
483
+ )
451
484
  ):
452
485
  self.security_logger.log_path_traversal_attempt(
453
486
  attempted_path=path_str,
@@ -5,14 +5,15 @@ from contextlib import suppress
5
5
  from pathlib import Path
6
6
 
7
7
  from crackerjack.errors import FileError, SecurityError
8
+ from crackerjack.models.protocols import SecurityServiceProtocol
8
9
  from crackerjack.services.regex_patterns import SAFE_PATTERNS
9
10
 
10
11
 
11
- class SecurityService:
12
+ class SecurityService(SecurityServiceProtocol):
12
13
  TOKEN_PATTERN_NAMES = [
13
14
  "mask_pypi_token",
14
15
  "mask_github_token",
15
- "mask_generic_long_token",
16
+ "mask_generic_long_token", # Changed from "mask_github_long_token" to correct name
16
17
  "mask_token_assignment",
17
18
  "mask_password_assignment",
18
19
  ]
@@ -188,21 +189,28 @@ class SecurityService:
188
189
  secrets = []
189
190
 
190
191
  patterns = {
191
- "api_key": r'api[_-]?key["\s]*[: =]["\s]*([a-zA-Z0-9_-]{20, })',
192
- "password": r'password["\s]*[: =]["\s]*([^\s"]{8, })',
193
- "token": r'token["\s]*[: =]["\s]*([a-zA-Z0-9_-]{20, })',
192
+ "api_key": r"(?i)(?:api[_-]?key)[\s]*[=:][\s]*[\"']([A-Za-z0-9_-]{20,})[\"']",
193
+ "password": r"(?i)(?:password)[\s]*[=:][\s]*[\"']([^\"'\s]{8,})[\"']",
194
+ "token": r"(?i)(?:token)[\s]*[=:][\s]*[\"']([A-Za-z0-9_-]{20,})[\"']",
194
195
  }
195
196
 
196
197
  import re
197
198
 
198
199
  for secret_type, pattern in patterns.items():
199
- matches = re.finditer(pattern, content, re.IGNORECASE)
200
+ matches = re.finditer(pattern, content)
200
201
  for match in matches:
202
+ # Extract the captured group (the secret value)
203
+ secret_value = match.group(1)
204
+
205
+ # Calculate line number where the match occurs
206
+ line_start_pos = match.start()
207
+ line_num = content[:line_start_pos].count("\n") + 1
208
+
201
209
  secrets.append(
202
210
  {
203
211
  "type": secret_type,
204
- "value": match.group(1)[:10] + "...",
205
- "line": content[: match.start()].count("\n") + 1,
212
+ "value": secret_value[:10] + "...",
213
+ "line": line_num,
206
214
  }
207
215
  )
208
216
  return secrets
@@ -5,9 +5,10 @@ import time
5
5
  import typing as t
6
6
  from pathlib import Path
7
7
 
8
- from rich.console import Console
8
+ from acb.console import Console
9
+ from acb.depends import Inject, depends
10
+ from mcp_common.ui import ServerPanels
9
11
 
10
- from ..ui.server_panels import create_server_panels
11
12
  from .secure_subprocess import execute_secure_subprocess
12
13
  from .security_logger import get_security_logger
13
14
 
@@ -198,18 +199,17 @@ def stop_process(pid: int, force: bool = False) -> bool:
198
199
  return True
199
200
 
200
201
 
201
- def stop_mcp_server(console: Console | None = None) -> bool:
202
- if console is None:
203
- console = Console()
204
-
205
- panels = create_server_panels(console)
202
+ @depends.inject
203
+ def stop_mcp_server(console: Inject[Console]) -> bool:
206
204
  processes = find_mcp_server_processes()
207
205
 
208
206
  if not processes:
209
207
  console.print("[yellow]⚠️ No MCP server processes found[/ yellow]")
210
208
  return True
211
209
 
212
- panels.stop_servers(len(processes))
210
+ ServerPanels.info(
211
+ title="MCP Server", message=f"Stopping {len(processes)} process(es)"
212
+ )
213
213
 
214
214
  success = True
215
215
  for proc in processes:
@@ -221,15 +221,16 @@ def stop_mcp_server(console: Console | None = None) -> bool:
221
221
  success = False
222
222
 
223
223
  if success:
224
- panels.stop_complete(len(processes))
224
+ ServerPanels.info(
225
+ title="MCP Server",
226
+ message=f"Successfully stopped {len(processes)} process(es)",
227
+ )
225
228
 
226
229
  return success
227
230
 
228
231
 
229
- def stop_websocket_server(console: Console | None = None) -> bool:
230
- if console is None:
231
- console = Console()
232
-
232
+ @depends.inject
233
+ def stop_websocket_server(console: Inject[Console]) -> bool:
233
234
  processes = find_websocket_server_processes()
234
235
 
235
236
  if not processes:
@@ -248,11 +249,9 @@ def stop_websocket_server(console: Console | None = None) -> bool:
248
249
  return success
249
250
 
250
251
 
251
- def stop_zuban_lsp(console: Console | None = None) -> bool:
252
+ @depends.inject
253
+ def stop_zuban_lsp(console: Inject[Console]) -> bool:
252
254
  """Stop running zuban LSP server processes."""
253
- if console is None:
254
- console = Console()
255
-
256
255
  processes = find_zuban_lsp_processes()
257
256
 
258
257
  if not processes:
@@ -271,33 +270,30 @@ def stop_zuban_lsp(console: Console | None = None) -> bool:
271
270
  return success
272
271
 
273
272
 
274
- def stop_all_servers(console: Console | None = None) -> bool:
275
- if console is None:
276
- console = Console()
277
-
278
- mcp_success = stop_mcp_server(console)
279
- websocket_success = stop_websocket_server(console)
280
- zuban_lsp_success = stop_zuban_lsp(console)
273
+ @depends.inject
274
+ def stop_all_servers(console: Inject[Console]) -> bool:
275
+ mcp_success = stop_mcp_server()
276
+ websocket_success = stop_websocket_server()
277
+ zuban_lsp_success = stop_zuban_lsp()
281
278
 
282
279
  return mcp_success and websocket_success and zuban_lsp_success
283
280
 
284
281
 
282
+ @depends.inject
285
283
  def restart_mcp_server(
286
284
  websocket_port: int | None = None,
287
- console: Console | None = None,
285
+ console: Inject[Console] = None,
288
286
  ) -> bool:
289
- if console is None:
290
- console = Console()
291
-
292
- panels = create_server_panels(console)
293
- panels.restart_header()
287
+ ServerPanels.info(
288
+ title="MCP Server", message="Restarting Crackerjack MCP Server..."
289
+ )
294
290
 
295
- stop_mcp_server(console)
291
+ stop_mcp_server()
296
292
 
297
- panels.cleanup_wait()
293
+ ServerPanels.simple_message("⏳ Waiting for cleanup...", style="dim")
298
294
  time.sleep(2)
299
295
 
300
- panels.starting_server()
296
+ ServerPanels.simple_message("🚀 Starting new server instance...", style="green")
301
297
  try:
302
298
  cmd = [sys.executable, "-m", "crackerjack", "--start-mcp-server"]
303
299
  if websocket_port:
@@ -323,35 +319,30 @@ def restart_mcp_server(
323
319
 
324
320
  # Display success panel with server details
325
321
  http_endpoint = "http://127.0.0.1:8676/mcp"
326
- websocket_monitor = (
327
- f"ws://127.0.0.1:{websocket_port or 8675}" if websocket_port else None
328
- )
329
322
 
330
- panels.success_panel(
331
- http_endpoint=http_endpoint,
332
- websocket_monitor=websocket_monitor,
323
+ ServerPanels.startup_success(
324
+ server_name="Crackerjack MCP",
325
+ endpoint=http_endpoint,
333
326
  process_id=process.pid,
334
327
  )
335
328
  return True
336
329
 
337
330
  except Exception as e:
338
- panels.failure_panel(str(e))
331
+ ServerPanels.error(title="MCP Restart Error", message=str(e))
339
332
  return False
340
333
 
341
334
 
342
- def restart_zuban_lsp(console: Console | None = None) -> bool:
335
+ @depends.inject
336
+ def restart_zuban_lsp(console: Inject[Console]) -> bool:
343
337
  """Restart zuban LSP server."""
344
- if console is None:
345
- console = Console()
346
-
347
338
  console.print("[bold cyan]🔄 Restarting Zuban LSP server...[/ bold cyan]")
348
339
 
349
- stop_zuban_lsp(console)
340
+ stop_zuban_lsp()
350
341
 
351
- console.print("⏳ Waiting for cleanup...")
342
+ console.print("⏳ Waiting for cleanup")
352
343
  time.sleep(2)
353
344
 
354
- console.print("🚀 Starting new Zuban LSP server...")
345
+ console.print("🚀 Starting new Zuban LSP server")
355
346
  try:
356
347
  cmd = [sys.executable, "-m", "crackerjack", "--start-zuban-lsp"]
357
348
 
@@ -378,10 +369,8 @@ def restart_zuban_lsp(console: Console | None = None) -> bool:
378
369
  return False
379
370
 
380
371
 
381
- def list_server_status(console: Console | None = None) -> None:
382
- if console is None:
383
- console = Console()
384
-
372
+ @depends.inject
373
+ def list_server_status(console: Inject[Console]) -> None:
385
374
  console.print("[bold cyan]📊 Crackerjack Server Status[/ bold cyan]")
386
375
 
387
376
  mcp_processes = find_mcp_server_processes()
@@ -1,18 +1,60 @@
1
1
  import os
2
2
  import subprocess
3
+ import typing as t
4
+ from contextlib import suppress
3
5
  from datetime import datetime, timedelta
4
6
  from pathlib import Path
5
7
 
6
- from rich.console import Console
8
+ from acb.console import Console
9
+ from acb.depends import Inject, depends
7
10
 
11
+ from crackerjack.models.protocols import ServiceProtocol, SmartSchedulingServiceProtocol
8
12
 
9
- class SmartSchedulingService:
10
- def __init__(self, console: Console, project_path: Path) -> None:
13
+
14
+ class SmartSchedulingService(SmartSchedulingServiceProtocol, ServiceProtocol):
15
+ @depends.inject
16
+ def __init__(self, console: Inject[Console], project_path: Path) -> None:
11
17
  self.console = console
12
18
  self.project_path = project_path
13
19
  self.cache_dir = Path.home() / ".cache" / "crackerjack"
14
20
  self.cache_dir.mkdir(parents=True, exist_ok=True)
15
21
 
22
+ def initialize(self) -> None:
23
+ pass
24
+
25
+ def cleanup(self) -> None:
26
+ pass
27
+
28
+ def health_check(self) -> bool:
29
+ return True
30
+
31
+ def shutdown(self) -> None:
32
+ pass
33
+
34
+ def metrics(self) -> dict[str, t.Any]:
35
+ return {}
36
+
37
+ def is_healthy(self) -> bool:
38
+ return True
39
+
40
+ def register_resource(self, resource: t.Any) -> None:
41
+ pass
42
+
43
+ def cleanup_resource(self, resource: t.Any) -> None:
44
+ pass
45
+
46
+ def record_error(self, error: Exception) -> None:
47
+ pass
48
+
49
+ def increment_requests(self) -> None:
50
+ pass
51
+
52
+ def get_custom_metric(self, name: str) -> t.Any:
53
+ return None
54
+
55
+ def set_custom_metric(self, name: str, value: t.Any) -> None:
56
+ pass
57
+
16
58
  def should_scheduled_init(self) -> bool:
17
59
  init_schedule = os.environ.get("CRACKERJACK_INIT_SCHEDULE", "weekly")
18
60
 
@@ -77,8 +119,6 @@ class SmartSchedulingService:
77
119
  timestamp_file = self.cache_dir / f"{self.project_path.name}.init_timestamp"
78
120
 
79
121
  if timestamp_file.exists():
80
- from contextlib import suppress
81
-
82
122
  with suppress(OSError, ValueError):
83
123
  timestamp_str = timestamp_file.read_text().strip()
84
124
  return datetime.fromisoformat(timestamp_str)
@@ -109,7 +149,7 @@ class SmartSchedulingService:
109
149
  def _has_recent_activity(self) -> bool:
110
150
  try:
111
151
  result = subprocess.run(
112
- ["git", "log", "- 1", "--since=24.hours", "--oneline"],
152
+ ["git", "log", "-1", "--since=24.hours", "--oneline"],
113
153
  cwd=self.project_path,
114
154
  capture_output=True,
115
155
  text=True,
@@ -18,9 +18,9 @@ class AccessLevel(str, Enum):
18
18
 
19
19
 
20
20
  class AuthenticationMethod(str, Enum):
21
- API_KEY = "api_key"
22
- JWT_TOKEN = "jwt_token"
23
- HMAC_SIGNATURE = "hmac_signature"
21
+ API_KEY = "api_key" # nosec B105
22
+ JWT_TOKEN = "jwt_token" # nosec B105
23
+ HMAC_SIGNATURE = "hmac_signature" # nosec B105
24
24
  LOCAL_ONLY = "local_only"
25
25
 
26
26
 
@@ -6,6 +6,7 @@ import typing as t
6
6
  from contextlib import asynccontextmanager
7
7
  from dataclasses import dataclass, field
8
8
 
9
+ from ..mcp.context import MCPServerContext
9
10
  from .security_logger import SecurityEventLevel, SecurityEventType, get_security_logger
10
11
 
11
12