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,292 @@
1
+ """CLI handlers for semantic search operations."""
2
+
3
+ from pathlib import Path
4
+ from textwrap import dedent
5
+
6
+ from acb import console
7
+ from rich.panel import Panel
8
+ from rich.table import Table
9
+
10
+ from crackerjack.models.semantic_models import SearchQuery, SemanticConfig
11
+ from crackerjack.services.vector_store import VectorStore
12
+
13
+ # console imported from acb
14
+
15
+
16
+ def handle_semantic_index(file_path: str) -> None:
17
+ """Handle indexing a file for semantic search.
18
+
19
+ Args:
20
+ file_path: Path to the file or directory to index
21
+ """
22
+ try:
23
+ console.print(f"[cyan]Indexing file for semantic search:[/cyan] {file_path}")
24
+
25
+ # Validate path
26
+ path_obj = Path(file_path)
27
+ if not path_obj.exists():
28
+ console.print(f"[red]Error:[/red] File does not exist: {file_path}")
29
+ return
30
+
31
+ # Create default configuration
32
+ config = SemanticConfig(
33
+ embedding_model="sentence-transformers/all-MiniLM-L6-v2",
34
+ chunk_size=512,
35
+ chunk_overlap=50,
36
+ max_search_results=10,
37
+ similarity_threshold=0.7,
38
+ embedding_dimension=384,
39
+ )
40
+
41
+ # Initialize vector store with persistent database
42
+ db_path = Path.cwd() / ".crackerjack" / "semantic_index.db"
43
+ db_path.parent.mkdir(exist_ok=True)
44
+ vector_store = VectorStore(config, db_path=db_path)
45
+
46
+ if path_obj.is_file():
47
+ # Index single file
48
+ embeddings = vector_store.index_file(path_obj)
49
+ console.print(
50
+ f"[green]✅ Successfully indexed {len(embeddings)} chunks from {path_obj.name}[/green]"
51
+ )
52
+ else:
53
+ # Index directory (recursively)
54
+ total_files = 0
55
+ total_chunks = 0
56
+
57
+ for file in path_obj.rglob("*.py"): # Index Python files
58
+ try:
59
+ embeddings = vector_store.index_file(file)
60
+ total_files += 1
61
+ total_chunks += len(embeddings)
62
+ console.print(
63
+ f"[dim]Indexed {len(embeddings)} chunks from {file.relative_to(path_obj)}[/dim]"
64
+ )
65
+ except Exception as e:
66
+ console.print(
67
+ f"[yellow]Warning:[/yellow] Failed to index {file}: {e}"
68
+ )
69
+
70
+ console.print(
71
+ f"[green]✅ Successfully indexed {total_files} files with {total_chunks} total chunks[/green]"
72
+ )
73
+
74
+ # Show index stats
75
+ stats = vector_store.get_stats()
76
+ console.print(
77
+ f"[cyan]Index now contains:[/cyan] {stats.total_files} files, {stats.total_chunks} chunks"
78
+ )
79
+
80
+ except Exception as e:
81
+ console.print(
82
+ f"[red]Error indexing file:[/red] {str(e).replace('[', '\\[').replace(']', '\\]')}"
83
+ )
84
+
85
+
86
+ def handle_semantic_search(query: str) -> None:
87
+ """Handle semantic search across indexed files.
88
+
89
+ Args:
90
+ query: The search query text
91
+ """
92
+ try:
93
+ console.print(f"[cyan]Performing semantic search for:[/cyan] {query}")
94
+
95
+ # Create default configuration
96
+ config = SemanticConfig(
97
+ embedding_model="sentence-transformers/all-MiniLM-L6-v2",
98
+ chunk_size=512,
99
+ chunk_overlap=50,
100
+ max_search_results=10,
101
+ similarity_threshold=0.7,
102
+ embedding_dimension=384,
103
+ )
104
+
105
+ # Create search query
106
+ search_query = SearchQuery(
107
+ query=query,
108
+ max_results=10,
109
+ min_similarity=0.3, # Lower threshold for CLI to show more results
110
+ )
111
+
112
+ # Initialize vector store with persistent database
113
+ db_path = Path.cwd() / ".crackerjack" / "semantic_index.db"
114
+ db_path.parent.mkdir(exist_ok=True)
115
+ vector_store = VectorStore(config, db_path=db_path)
116
+ results = vector_store.search(search_query)
117
+
118
+ if not results:
119
+ console.print(
120
+ "[yellow]No results found. Try a different search term or index more files.[/yellow]"
121
+ )
122
+ return
123
+
124
+ # Display results in a table
125
+ table = Table(title=f"Semantic Search Results for: '{query}'")
126
+ table.add_column("File", style="cyan", no_wrap=True)
127
+ table.add_column("Lines", style="magenta", justify="center")
128
+ table.add_column("Score", style="green", justify="center")
129
+ table.add_column("Content Preview", style="white")
130
+
131
+ for result in results:
132
+ # Truncate content for display
133
+ content_preview = (
134
+ result.content[:80] + "..."
135
+ if len(result.content) > 80
136
+ else result.content
137
+ )
138
+ content_preview = content_preview.replace("\n", " ").strip()
139
+
140
+ # Escape Rich markup in content to prevent rendering issues
141
+ content_preview = content_preview.replace("[", "\\[").replace("]", "\\]")
142
+
143
+ table.add_row(
144
+ str(result.file_path.name),
145
+ f"{result.start_line}-{result.end_line}",
146
+ f"{result.similarity_score:.3f}",
147
+ content_preview,
148
+ )
149
+
150
+ console.print(
151
+ Panel(table, title="Semantic Search Results", border_style="cyan")
152
+ )
153
+
154
+ # Show detailed content for top result
155
+ if results:
156
+ top_result = results[0]
157
+ # Escape Rich markup in the detailed content
158
+ escaped_content = (
159
+ top_result.content.strip().replace("[", "\\[").replace("]", "\\]")
160
+ )
161
+ console.print(
162
+ Panel(
163
+ dedent(f"""
164
+ [cyan]Top Result Details:[/cyan]
165
+ [bold]File:[/bold] {top_result.file_path}
166
+ [bold]Lines:[/bold] {top_result.start_line}-{top_result.end_line}
167
+ [bold]Similarity Score:[/bold] {top_result.similarity_score:.4f}
168
+
169
+ [bold]Content:[/bold]
170
+ {escaped_content}
171
+ """).strip(),
172
+ title="🎯 Best Match",
173
+ border_style="green",
174
+ )
175
+ )
176
+
177
+ except Exception as e:
178
+ console.print(
179
+ f"[red]Error performing search:[/red] {str(e).replace('[', '\\[').replace(']', '\\]')}"
180
+ )
181
+
182
+
183
+ def handle_semantic_stats() -> None:
184
+ """Handle displaying semantic search index statistics."""
185
+ try:
186
+ console.print("[cyan]Retrieving semantic search index statistics...[/cyan]")
187
+
188
+ # Create default configuration
189
+ config = SemanticConfig(
190
+ embedding_model="sentence-transformers/all-MiniLM-L6-v2",
191
+ chunk_size=512,
192
+ chunk_overlap=50,
193
+ max_search_results=10,
194
+ similarity_threshold=0.7,
195
+ embedding_dimension=384,
196
+ )
197
+
198
+ # Initialize vector store with persistent database
199
+ db_path = Path.cwd() / ".crackerjack" / "semantic_index.db"
200
+ db_path.parent.mkdir(exist_ok=True)
201
+ vector_store = VectorStore(config, db_path=db_path)
202
+ stats = vector_store.get_stats()
203
+
204
+ # Create stats table
205
+ table = Table(title="Semantic Search Index Statistics")
206
+ table.add_column("Metric", style="cyan", no_wrap=True)
207
+ table.add_column("Value", style="green")
208
+
209
+ table.add_row("Total Files", str(stats.total_files))
210
+ table.add_row("Total Chunks", str(stats.total_chunks))
211
+ table.add_row("Index Size", f"{stats.index_size_mb:.2f} MB")
212
+
213
+ # Calculate average chunks per file
214
+ avg_chunks = (
215
+ stats.total_chunks / stats.total_files if stats.total_files > 0 else 0.0
216
+ )
217
+ table.add_row("Average Chunks per File", f"{avg_chunks:.1f}")
218
+
219
+ table.add_row("Embedding Model", config.embedding_model)
220
+ table.add_row("Embedding Dimension", "384") # ONNX fallback uses 384 dimensions
221
+
222
+ if stats.last_updated:
223
+ table.add_row(
224
+ "Last Updated", stats.last_updated.strftime("%Y-%m-%d %H:%M:%S")
225
+ )
226
+
227
+ console.print(Panel(table, border_style="cyan"))
228
+
229
+ if stats.total_files == 0:
230
+ console.print(
231
+ Panel(
232
+ "[yellow]The semantic search index is empty. Use [bold]--index[/bold] to add files.[/yellow]",
233
+ title="💡 Tip",
234
+ border_style="yellow",
235
+ )
236
+ )
237
+
238
+ except Exception as e:
239
+ console.print(
240
+ f"[red]Error retrieving stats:[/red] {str(e).replace('[', '\\[').replace(']', '\\]')}"
241
+ )
242
+
243
+
244
+ def handle_remove_from_semantic_index(file_path: str) -> None:
245
+ """Handle removing a file from the semantic search index.
246
+
247
+ Args:
248
+ file_path: Path to the file to remove
249
+ """
250
+ try:
251
+ console.print(
252
+ f"[cyan]Removing file from semantic search index:[/cyan] {file_path}"
253
+ )
254
+
255
+ # Validate path
256
+ path_obj = Path(file_path)
257
+
258
+ # Create default configuration
259
+ config = SemanticConfig(
260
+ embedding_model="sentence-transformers/all-MiniLM-L6-v2",
261
+ chunk_size=512,
262
+ chunk_overlap=50,
263
+ max_search_results=10,
264
+ similarity_threshold=0.7,
265
+ embedding_dimension=384,
266
+ )
267
+
268
+ # Initialize vector store with persistent database
269
+ db_path = Path.cwd() / ".crackerjack" / "semantic_index.db"
270
+ db_path.parent.mkdir(exist_ok=True)
271
+ vector_store = VectorStore(config, db_path=db_path)
272
+ success = vector_store.remove_file(path_obj)
273
+
274
+ if success:
275
+ console.print(
276
+ f"[green]✅ Successfully removed {path_obj.name} from index[/green]"
277
+ )
278
+ else:
279
+ console.print(
280
+ f"[yellow]Warning:[/yellow] File {path_obj.name} was not found in index"
281
+ )
282
+
283
+ # Show updated stats
284
+ stats = vector_store.get_stats()
285
+ console.print(
286
+ f"[cyan]Index now contains:[/cyan] {stats.total_files} files, {stats.total_chunks} chunks"
287
+ )
288
+
289
+ except Exception as e:
290
+ console.print(
291
+ f"[red]Error removing file:[/red] {str(e).replace('[', '\\[').replace(']', '\\]')}"
292
+ )
@@ -0,0 +1,19 @@
1
+ from pathlib import Path
2
+
3
+
4
+ def get_package_version() -> str:
5
+ try:
6
+ from importlib.metadata import version
7
+
8
+ return version("crackerjack")
9
+ except (ImportError, ModuleNotFoundError):
10
+ try:
11
+ import tomllib
12
+
13
+ pyproject_path = Path(__file__).parent.parent.parent / "pyproject.toml"
14
+ with pyproject_path.open("rb") as f:
15
+ pyproject_data = tomllib.load(f)
16
+ version_value = pyproject_data["project"]["version"]
17
+ return str(version_value)
18
+ except Exception:
19
+ return "unknown"
@@ -5,7 +5,6 @@ from pathlib import Path
5
5
  from typing import Protocol
6
6
 
7
7
  from pydantic import BaseModel, ConfigDict
8
- from rich.console import Console
9
8
 
10
9
  from .errors import ErrorCode, ExecutionError
11
10
  from .services.backup_service import BackupMetadata, PackageBackupService
@@ -23,10 +22,10 @@ from .services.security_logger import (
23
22
 
24
23
  class SafePatternApplicator:
25
24
  def apply_docstring_patterns(self, code: str) -> str:
26
- result = code
27
- result = SAFE_PATTERNS["docstring_triple_double"].apply(result)
28
- result = SAFE_PATTERNS["docstring_triple_single"].apply(result)
29
- return result
25
+ # Intentionally a no-op for docstrings here. Actual docstring removal is
26
+ # handled by the structured AST cleaning step (_create_docstring_step).
27
+ # This keeps SafePatternApplicator focused on formatting-only changes.
28
+ return code
30
29
 
31
30
  def apply_formatting_patterns(self, content: str) -> str:
32
31
  content = SAFE_PATTERNS["spacing_after_comma"].apply(content)
@@ -35,17 +34,23 @@ class SafePatternApplicator:
35
34
  return content
36
35
 
37
36
  def has_preserved_comment(self, line: str) -> bool:
38
- if line.strip().startswith("#! /"):
37
+ # Preserve shebangs (still useful for executable scripts)
38
+ if line.strip().startswith(("#! /", "#!/")):
39
39
  return True
40
40
 
41
41
  line_lower = line.lower()
42
42
  preserved_keywords = [
43
- "coding: ",
44
- "encoding: ",
45
- "type: ",
43
+ # Security & linting directives (critical)
44
+ "nosec",
46
45
  "noqa",
47
46
  "pragma",
47
+ # Type checking directives (critical)
48
+ "type: ",
49
+ # Security markers (custom)
48
50
  "regex ok",
51
+ # Task tracking (useful)
52
+ "todo",
53
+ # Note: "coding:" and "encoding:" removed - obsolete since Python 3.0
49
54
  ]
50
55
  return any(keyword in line_lower for keyword in preserved_keywords)
51
56
 
@@ -86,7 +91,7 @@ class CleaningStepProtocol(Protocol):
86
91
  class FileProcessor(BaseModel):
87
92
  model_config = ConfigDict(arbitrary_types_allowed=True, extra="allow")
88
93
 
89
- console: Console
94
+ console: t.Any
90
95
  logger: t.Any = None
91
96
  base_directory: Path | None = None
92
97
  security_logger: t.Any = None
@@ -198,7 +203,7 @@ class FileProcessor(BaseModel):
198
203
  class CleaningErrorHandler(BaseModel):
199
204
  model_config = ConfigDict(arbitrary_types_allowed=True)
200
205
 
201
- console: Console
206
+ console: t.Any
202
207
  logger: t.Any = None
203
208
 
204
209
  def model_post_init(self, _: t.Any) -> None:
@@ -256,7 +261,7 @@ class CleaningPipeline(BaseModel):
256
261
 
257
262
  file_processor: t.Any
258
263
  error_handler: t.Any
259
- console: Console
264
+ console: t.Any
260
265
  logger: t.Any = None
261
266
 
262
267
  def model_post_init(self, _: t.Any) -> None:
@@ -374,7 +379,7 @@ class CleaningPipeline(BaseModel):
374
379
  class CodeCleaner(BaseModel):
375
380
  model_config = ConfigDict(arbitrary_types_allowed=True, extra="allow")
376
381
 
377
- console: Console
382
+ console: t.Any
378
383
  file_processor: t.Any = None
379
384
  error_handler: t.Any = None
380
385
  pipeline: t.Any = None
@@ -442,7 +447,8 @@ class CodeCleaner(BaseModel):
442
447
  )
443
448
 
444
449
  if pkg_dir is None:
445
- pkg_dir = Path.cwd()
450
+ # Use configured base directory when no explicit path is provided
451
+ pkg_dir = self.base_directory or Path.cwd()
446
452
 
447
453
  python_files = self._discover_package_files(pkg_dir)
448
454
 
@@ -500,9 +506,20 @@ class CodeCleaner(BaseModel):
500
506
 
501
507
  def _prepare_package_directory(self, pkg_dir: Path | None) -> Path:
502
508
  if pkg_dir is None:
503
- pkg_dir = Path.cwd()
504
-
505
- return SecurePathValidator.validate_file_path(pkg_dir, self.base_directory)
509
+ pkg_dir = self.base_directory or Path.cwd()
510
+ # Avoid normalizing symlinks to preserve exact input path semantics
511
+ # while still enforcing base-directory containment.
512
+ if self.base_directory and not SecurePathValidator.is_within_directory(
513
+ pkg_dir, self.base_directory
514
+ ):
515
+ raise ExecutionError(
516
+ message=(
517
+ f"Path outside allowed directory: {pkg_dir} not within "
518
+ f"{self.base_directory}"
519
+ ),
520
+ error_code=ErrorCode.VALIDATION_ERROR,
521
+ )
522
+ return pkg_dir
506
523
 
507
524
  def _create_backup(self, validated_pkg_dir: Path) -> BackupMetadata:
508
525
  self.console.print(
@@ -1108,12 +1125,18 @@ class CodeCleaner(BaseModel):
1108
1125
  return '"' in line or "'" in line or "#" in line
1109
1126
 
1110
1127
  def _process_line_for_comment_removal(self, line: str) -> str:
1111
- """Process line to remove comments while preserving strings."""
1128
+ """Process line to remove comments while preserving strings and special comments."""
1112
1129
  result_chars = []
1113
1130
  string_state = {"in_string": False, "quote_char": None}
1114
1131
 
1115
1132
  for i, char in enumerate(line):
1116
- if self._should_break_for_comment(char, string_state):
1133
+ should_stop, preserve_rest = self._should_stop_for_comment(
1134
+ char, string_state, line, i
1135
+ )
1136
+ if should_stop:
1137
+ if preserve_rest:
1138
+ # Preserve the rest of the line (special comment like nosec, noqa, type:)
1139
+ result_chars.extend(line[i:])
1117
1140
  break
1118
1141
 
1119
1142
  self._update_string_state(char, i, line, string_state)
@@ -1121,11 +1144,24 @@ class CodeCleaner(BaseModel):
1121
1144
 
1122
1145
  return "".join(result_chars).rstrip()
1123
1146
 
1124
- def _should_break_for_comment(
1125
- self, char: str, string_state: dict[str, t.Any]
1126
- ) -> bool:
1127
- """Check if we should break for a comment character."""
1128
- return not string_state["in_string"] and char == "#"
1147
+ def _should_stop_for_comment(
1148
+ self, char: str, string_state: dict[str, t.Any], line: str, index: int
1149
+ ) -> tuple[bool, bool]:
1150
+ """Check if we should stop processing at comment.
1151
+
1152
+ Returns:
1153
+ (should_stop, preserve_rest): should_stop=True when comment found,
1154
+ preserve_rest=True if comment should be kept
1155
+ """
1156
+ if string_state["in_string"] or char != "#":
1157
+ return (False, False)
1158
+
1159
+ # Check if the comment portion should be preserved
1160
+ comment_part = line[index:].strip()
1161
+ if _safe_applicator.has_preserved_comment(comment_part):
1162
+ return (True, True) # Stop processing, preserve the comment
1163
+
1164
+ return (True, False) # Stop processing, discard the comment
1129
1165
 
1130
1166
  def _update_string_state(
1131
1167
  self, char: str, index: int, line: str, string_state: dict[str, t.Any]