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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (533) hide show
  1. crackerjack/README.md +19 -0
  2. crackerjack/__init__.py +96 -2
  3. crackerjack/__main__.py +637 -138
  4. crackerjack/adapters/README.md +18 -0
  5. crackerjack/adapters/__init__.py +39 -0
  6. crackerjack/adapters/_output_paths.py +167 -0
  7. crackerjack/adapters/_qa_adapter_base.py +309 -0
  8. crackerjack/adapters/_tool_adapter_base.py +706 -0
  9. crackerjack/adapters/ai/README.md +65 -0
  10. crackerjack/adapters/ai/__init__.py +5 -0
  11. crackerjack/adapters/ai/claude.py +853 -0
  12. crackerjack/adapters/complexity/README.md +53 -0
  13. crackerjack/adapters/complexity/__init__.py +10 -0
  14. crackerjack/adapters/complexity/complexipy.py +641 -0
  15. crackerjack/adapters/dependency/__init__.py +22 -0
  16. crackerjack/adapters/dependency/pip_audit.py +418 -0
  17. crackerjack/adapters/format/README.md +72 -0
  18. crackerjack/adapters/format/__init__.py +11 -0
  19. crackerjack/adapters/format/mdformat.py +313 -0
  20. crackerjack/adapters/format/ruff.py +516 -0
  21. crackerjack/adapters/lint/README.md +47 -0
  22. crackerjack/adapters/lint/__init__.py +11 -0
  23. crackerjack/adapters/lint/codespell.py +273 -0
  24. crackerjack/adapters/lsp/README.md +49 -0
  25. crackerjack/adapters/lsp/__init__.py +27 -0
  26. crackerjack/adapters/lsp/_base.py +194 -0
  27. crackerjack/adapters/lsp/_client.py +358 -0
  28. crackerjack/adapters/lsp/_manager.py +193 -0
  29. crackerjack/adapters/lsp/skylos.py +283 -0
  30. crackerjack/adapters/lsp/zuban.py +557 -0
  31. crackerjack/adapters/refactor/README.md +59 -0
  32. crackerjack/adapters/refactor/__init__.py +12 -0
  33. crackerjack/adapters/refactor/creosote.py +318 -0
  34. crackerjack/adapters/refactor/refurb.py +406 -0
  35. crackerjack/adapters/refactor/skylos.py +494 -0
  36. crackerjack/adapters/sast/README.md +132 -0
  37. crackerjack/adapters/sast/__init__.py +32 -0
  38. crackerjack/adapters/sast/_base.py +201 -0
  39. crackerjack/adapters/sast/bandit.py +423 -0
  40. crackerjack/adapters/sast/pyscn.py +405 -0
  41. crackerjack/adapters/sast/semgrep.py +241 -0
  42. crackerjack/adapters/security/README.md +111 -0
  43. crackerjack/adapters/security/__init__.py +17 -0
  44. crackerjack/adapters/security/gitleaks.py +339 -0
  45. crackerjack/adapters/type/README.md +52 -0
  46. crackerjack/adapters/type/__init__.py +12 -0
  47. crackerjack/adapters/type/pyrefly.py +402 -0
  48. crackerjack/adapters/type/ty.py +402 -0
  49. crackerjack/adapters/type/zuban.py +522 -0
  50. crackerjack/adapters/utility/README.md +51 -0
  51. crackerjack/adapters/utility/__init__.py +10 -0
  52. crackerjack/adapters/utility/checks.py +884 -0
  53. crackerjack/agents/README.md +264 -0
  54. crackerjack/agents/__init__.py +66 -0
  55. crackerjack/agents/architect_agent.py +238 -0
  56. crackerjack/agents/base.py +167 -0
  57. crackerjack/agents/claude_code_bridge.py +641 -0
  58. crackerjack/agents/coordinator.py +600 -0
  59. crackerjack/agents/documentation_agent.py +520 -0
  60. crackerjack/agents/dry_agent.py +585 -0
  61. crackerjack/agents/enhanced_coordinator.py +279 -0
  62. crackerjack/agents/enhanced_proactive_agent.py +185 -0
  63. crackerjack/agents/error_middleware.py +53 -0
  64. crackerjack/agents/formatting_agent.py +230 -0
  65. crackerjack/agents/helpers/__init__.py +9 -0
  66. crackerjack/agents/helpers/performance/__init__.py +22 -0
  67. crackerjack/agents/helpers/performance/performance_ast_analyzer.py +357 -0
  68. crackerjack/agents/helpers/performance/performance_pattern_detector.py +909 -0
  69. crackerjack/agents/helpers/performance/performance_recommender.py +572 -0
  70. crackerjack/agents/helpers/refactoring/__init__.py +22 -0
  71. crackerjack/agents/helpers/refactoring/code_transformer.py +536 -0
  72. crackerjack/agents/helpers/refactoring/complexity_analyzer.py +344 -0
  73. crackerjack/agents/helpers/refactoring/dead_code_detector.py +437 -0
  74. crackerjack/agents/helpers/test_creation/__init__.py +19 -0
  75. crackerjack/agents/helpers/test_creation/test_ast_analyzer.py +216 -0
  76. crackerjack/agents/helpers/test_creation/test_coverage_analyzer.py +643 -0
  77. crackerjack/agents/helpers/test_creation/test_template_generator.py +1031 -0
  78. crackerjack/agents/import_optimization_agent.py +1181 -0
  79. crackerjack/agents/performance_agent.py +325 -0
  80. crackerjack/agents/performance_helpers.py +205 -0
  81. crackerjack/agents/proactive_agent.py +55 -0
  82. crackerjack/agents/refactoring_agent.py +511 -0
  83. crackerjack/agents/refactoring_helpers.py +247 -0
  84. crackerjack/agents/security_agent.py +793 -0
  85. crackerjack/agents/semantic_agent.py +479 -0
  86. crackerjack/agents/semantic_helpers.py +356 -0
  87. crackerjack/agents/test_creation_agent.py +570 -0
  88. crackerjack/agents/test_specialist_agent.py +526 -0
  89. crackerjack/agents/tracker.py +110 -0
  90. crackerjack/api.py +647 -0
  91. crackerjack/cli/README.md +394 -0
  92. crackerjack/cli/__init__.py +24 -0
  93. crackerjack/cli/cache_handlers.py +209 -0
  94. crackerjack/cli/cache_handlers_enhanced.py +680 -0
  95. crackerjack/cli/facade.py +162 -0
  96. crackerjack/cli/formatting.py +13 -0
  97. crackerjack/cli/handlers/__init__.py +85 -0
  98. crackerjack/cli/handlers/advanced.py +103 -0
  99. crackerjack/cli/handlers/ai_features.py +62 -0
  100. crackerjack/cli/handlers/analytics.py +479 -0
  101. crackerjack/cli/handlers/changelog.py +271 -0
  102. crackerjack/cli/handlers/config_handlers.py +16 -0
  103. crackerjack/cli/handlers/coverage.py +84 -0
  104. crackerjack/cli/handlers/documentation.py +280 -0
  105. crackerjack/cli/handlers/main_handlers.py +497 -0
  106. crackerjack/cli/handlers/monitoring.py +371 -0
  107. crackerjack/cli/handlers.py +700 -0
  108. crackerjack/cli/interactive.py +488 -0
  109. crackerjack/cli/options.py +1216 -0
  110. crackerjack/cli/semantic_handlers.py +292 -0
  111. crackerjack/cli/utils.py +19 -0
  112. crackerjack/cli/version.py +19 -0
  113. crackerjack/code_cleaner.py +1307 -0
  114. crackerjack/config/README.md +472 -0
  115. crackerjack/config/__init__.py +275 -0
  116. crackerjack/config/global_lock_config.py +207 -0
  117. crackerjack/config/hooks.py +390 -0
  118. crackerjack/config/loader.py +239 -0
  119. crackerjack/config/settings.py +141 -0
  120. crackerjack/config/tool_commands.py +331 -0
  121. crackerjack/core/README.md +393 -0
  122. crackerjack/core/__init__.py +0 -0
  123. crackerjack/core/async_workflow_orchestrator.py +738 -0
  124. crackerjack/core/autofix_coordinator.py +282 -0
  125. crackerjack/core/container.py +105 -0
  126. crackerjack/core/enhanced_container.py +583 -0
  127. crackerjack/core/file_lifecycle.py +472 -0
  128. crackerjack/core/performance.py +244 -0
  129. crackerjack/core/performance_monitor.py +357 -0
  130. crackerjack/core/phase_coordinator.py +1227 -0
  131. crackerjack/core/proactive_workflow.py +267 -0
  132. crackerjack/core/resource_manager.py +425 -0
  133. crackerjack/core/retry.py +275 -0
  134. crackerjack/core/service_watchdog.py +601 -0
  135. crackerjack/core/session_coordinator.py +239 -0
  136. crackerjack/core/timeout_manager.py +563 -0
  137. crackerjack/core/websocket_lifecycle.py +410 -0
  138. crackerjack/core/workflow/__init__.py +21 -0
  139. crackerjack/core/workflow/workflow_ai_coordinator.py +863 -0
  140. crackerjack/core/workflow/workflow_event_orchestrator.py +1107 -0
  141. crackerjack/core/workflow/workflow_issue_parser.py +714 -0
  142. crackerjack/core/workflow/workflow_phase_executor.py +1158 -0
  143. crackerjack/core/workflow/workflow_security_gates.py +400 -0
  144. crackerjack/core/workflow_orchestrator.py +2243 -0
  145. crackerjack/data/README.md +11 -0
  146. crackerjack/data/__init__.py +8 -0
  147. crackerjack/data/models.py +79 -0
  148. crackerjack/data/repository.py +210 -0
  149. crackerjack/decorators/README.md +180 -0
  150. crackerjack/decorators/__init__.py +35 -0
  151. crackerjack/decorators/error_handling.py +649 -0
  152. crackerjack/decorators/error_handling_decorators.py +334 -0
  153. crackerjack/decorators/helpers.py +58 -0
  154. crackerjack/decorators/patterns.py +281 -0
  155. crackerjack/decorators/utils.py +58 -0
  156. crackerjack/docs/INDEX.md +11 -0
  157. crackerjack/docs/README.md +11 -0
  158. crackerjack/docs/generated/api/API_REFERENCE.md +10895 -0
  159. crackerjack/docs/generated/api/CLI_REFERENCE.md +109 -0
  160. crackerjack/docs/generated/api/CROSS_REFERENCES.md +1755 -0
  161. crackerjack/docs/generated/api/PROTOCOLS.md +3 -0
  162. crackerjack/docs/generated/api/SERVICES.md +1252 -0
  163. crackerjack/documentation/README.md +11 -0
  164. crackerjack/documentation/__init__.py +31 -0
  165. crackerjack/documentation/ai_templates.py +756 -0
  166. crackerjack/documentation/dual_output_generator.py +767 -0
  167. crackerjack/documentation/mkdocs_integration.py +518 -0
  168. crackerjack/documentation/reference_generator.py +1065 -0
  169. crackerjack/dynamic_config.py +678 -0
  170. crackerjack/errors.py +378 -0
  171. crackerjack/events/README.md +11 -0
  172. crackerjack/events/__init__.py +16 -0
  173. crackerjack/events/telemetry.py +175 -0
  174. crackerjack/events/workflow_bus.py +346 -0
  175. crackerjack/exceptions/README.md +301 -0
  176. crackerjack/exceptions/__init__.py +5 -0
  177. crackerjack/exceptions/config.py +4 -0
  178. crackerjack/exceptions/tool_execution_error.py +245 -0
  179. crackerjack/executors/README.md +591 -0
  180. crackerjack/executors/__init__.py +13 -0
  181. crackerjack/executors/async_hook_executor.py +938 -0
  182. crackerjack/executors/cached_hook_executor.py +316 -0
  183. crackerjack/executors/hook_executor.py +1295 -0
  184. crackerjack/executors/hook_lock_manager.py +708 -0
  185. crackerjack/executors/individual_hook_executor.py +739 -0
  186. crackerjack/executors/lsp_aware_hook_executor.py +349 -0
  187. crackerjack/executors/progress_hook_executor.py +282 -0
  188. crackerjack/executors/tool_proxy.py +433 -0
  189. crackerjack/hooks/README.md +485 -0
  190. crackerjack/hooks/lsp_hook.py +93 -0
  191. crackerjack/intelligence/README.md +557 -0
  192. crackerjack/intelligence/__init__.py +37 -0
  193. crackerjack/intelligence/adaptive_learning.py +693 -0
  194. crackerjack/intelligence/agent_orchestrator.py +485 -0
  195. crackerjack/intelligence/agent_registry.py +377 -0
  196. crackerjack/intelligence/agent_selector.py +439 -0
  197. crackerjack/intelligence/integration.py +250 -0
  198. crackerjack/interactive.py +719 -0
  199. crackerjack/managers/README.md +369 -0
  200. crackerjack/managers/__init__.py +11 -0
  201. crackerjack/managers/async_hook_manager.py +135 -0
  202. crackerjack/managers/hook_manager.py +585 -0
  203. crackerjack/managers/publish_manager.py +631 -0
  204. crackerjack/managers/test_command_builder.py +391 -0
  205. crackerjack/managers/test_executor.py +474 -0
  206. crackerjack/managers/test_manager.py +1357 -0
  207. crackerjack/managers/test_progress.py +187 -0
  208. crackerjack/mcp/README.md +374 -0
  209. crackerjack/mcp/__init__.py +0 -0
  210. crackerjack/mcp/cache.py +352 -0
  211. crackerjack/mcp/client_runner.py +121 -0
  212. crackerjack/mcp/context.py +802 -0
  213. crackerjack/mcp/dashboard.py +657 -0
  214. crackerjack/mcp/enhanced_progress_monitor.py +493 -0
  215. crackerjack/mcp/file_monitor.py +394 -0
  216. crackerjack/mcp/progress_components.py +607 -0
  217. crackerjack/mcp/progress_monitor.py +1016 -0
  218. crackerjack/mcp/rate_limiter.py +336 -0
  219. crackerjack/mcp/server.py +24 -0
  220. crackerjack/mcp/server_core.py +526 -0
  221. crackerjack/mcp/service_watchdog.py +505 -0
  222. crackerjack/mcp/state.py +407 -0
  223. crackerjack/mcp/task_manager.py +259 -0
  224. crackerjack/mcp/tools/README.md +27 -0
  225. crackerjack/mcp/tools/__init__.py +19 -0
  226. crackerjack/mcp/tools/core_tools.py +469 -0
  227. crackerjack/mcp/tools/error_analyzer.py +283 -0
  228. crackerjack/mcp/tools/execution_tools.py +384 -0
  229. crackerjack/mcp/tools/intelligence_tool_registry.py +46 -0
  230. crackerjack/mcp/tools/intelligence_tools.py +264 -0
  231. crackerjack/mcp/tools/monitoring_tools.py +628 -0
  232. crackerjack/mcp/tools/proactive_tools.py +367 -0
  233. crackerjack/mcp/tools/progress_tools.py +222 -0
  234. crackerjack/mcp/tools/semantic_tools.py +584 -0
  235. crackerjack/mcp/tools/utility_tools.py +358 -0
  236. crackerjack/mcp/tools/workflow_executor.py +699 -0
  237. crackerjack/mcp/websocket/README.md +31 -0
  238. crackerjack/mcp/websocket/__init__.py +14 -0
  239. crackerjack/mcp/websocket/app.py +54 -0
  240. crackerjack/mcp/websocket/endpoints.py +492 -0
  241. crackerjack/mcp/websocket/event_bridge.py +188 -0
  242. crackerjack/mcp/websocket/jobs.py +406 -0
  243. crackerjack/mcp/websocket/monitoring/__init__.py +25 -0
  244. crackerjack/mcp/websocket/monitoring/api/__init__.py +19 -0
  245. crackerjack/mcp/websocket/monitoring/api/dependencies.py +141 -0
  246. crackerjack/mcp/websocket/monitoring/api/heatmap.py +154 -0
  247. crackerjack/mcp/websocket/monitoring/api/intelligence.py +199 -0
  248. crackerjack/mcp/websocket/monitoring/api/metrics.py +203 -0
  249. crackerjack/mcp/websocket/monitoring/api/telemetry.py +101 -0
  250. crackerjack/mcp/websocket/monitoring/dashboard.py +18 -0
  251. crackerjack/mcp/websocket/monitoring/factory.py +109 -0
  252. crackerjack/mcp/websocket/monitoring/filters.py +10 -0
  253. crackerjack/mcp/websocket/monitoring/metrics.py +64 -0
  254. crackerjack/mcp/websocket/monitoring/models.py +90 -0
  255. crackerjack/mcp/websocket/monitoring/utils.py +171 -0
  256. crackerjack/mcp/websocket/monitoring/websocket_manager.py +78 -0
  257. crackerjack/mcp/websocket/monitoring/websockets/__init__.py +17 -0
  258. crackerjack/mcp/websocket/monitoring/websockets/dependencies.py +126 -0
  259. crackerjack/mcp/websocket/monitoring/websockets/heatmap.py +176 -0
  260. crackerjack/mcp/websocket/monitoring/websockets/intelligence.py +291 -0
  261. crackerjack/mcp/websocket/monitoring/websockets/metrics.py +291 -0
  262. crackerjack/mcp/websocket/monitoring_endpoints.py +21 -0
  263. crackerjack/mcp/websocket/server.py +174 -0
  264. crackerjack/mcp/websocket/websocket_handler.py +276 -0
  265. crackerjack/mcp/websocket_server.py +10 -0
  266. crackerjack/models/README.md +308 -0
  267. crackerjack/models/__init__.py +40 -0
  268. crackerjack/models/config.py +730 -0
  269. crackerjack/models/config_adapter.py +265 -0
  270. crackerjack/models/protocols.py +1535 -0
  271. crackerjack/models/pydantic_models.py +320 -0
  272. crackerjack/models/qa_config.py +145 -0
  273. crackerjack/models/qa_results.py +134 -0
  274. crackerjack/models/resource_protocols.py +299 -0
  275. crackerjack/models/results.py +35 -0
  276. crackerjack/models/semantic_models.py +258 -0
  277. crackerjack/models/task.py +173 -0
  278. crackerjack/models/test_models.py +60 -0
  279. crackerjack/monitoring/README.md +11 -0
  280. crackerjack/monitoring/__init__.py +0 -0
  281. crackerjack/monitoring/ai_agent_watchdog.py +405 -0
  282. crackerjack/monitoring/metrics_collector.py +427 -0
  283. crackerjack/monitoring/regression_prevention.py +580 -0
  284. crackerjack/monitoring/websocket_server.py +406 -0
  285. crackerjack/orchestration/README.md +340 -0
  286. crackerjack/orchestration/__init__.py +43 -0
  287. crackerjack/orchestration/advanced_orchestrator.py +894 -0
  288. crackerjack/orchestration/cache/README.md +312 -0
  289. crackerjack/orchestration/cache/__init__.py +37 -0
  290. crackerjack/orchestration/cache/memory_cache.py +338 -0
  291. crackerjack/orchestration/cache/tool_proxy_cache.py +340 -0
  292. crackerjack/orchestration/config.py +297 -0
  293. crackerjack/orchestration/coverage_improvement.py +180 -0
  294. crackerjack/orchestration/execution_strategies.py +361 -0
  295. crackerjack/orchestration/hook_orchestrator.py +1398 -0
  296. crackerjack/orchestration/strategies/README.md +401 -0
  297. crackerjack/orchestration/strategies/__init__.py +39 -0
  298. crackerjack/orchestration/strategies/adaptive_strategy.py +630 -0
  299. crackerjack/orchestration/strategies/parallel_strategy.py +237 -0
  300. crackerjack/orchestration/strategies/sequential_strategy.py +299 -0
  301. crackerjack/orchestration/test_progress_streamer.py +647 -0
  302. crackerjack/plugins/README.md +11 -0
  303. crackerjack/plugins/__init__.py +15 -0
  304. crackerjack/plugins/base.py +200 -0
  305. crackerjack/plugins/hooks.py +254 -0
  306. crackerjack/plugins/loader.py +335 -0
  307. crackerjack/plugins/managers.py +264 -0
  308. crackerjack/py313.py +191 -0
  309. crackerjack/security/README.md +11 -0
  310. crackerjack/security/__init__.py +0 -0
  311. crackerjack/security/audit.py +197 -0
  312. crackerjack/services/README.md +374 -0
  313. crackerjack/services/__init__.py +9 -0
  314. crackerjack/services/ai/README.md +295 -0
  315. crackerjack/services/ai/__init__.py +7 -0
  316. crackerjack/services/ai/advanced_optimizer.py +878 -0
  317. crackerjack/services/ai/contextual_ai_assistant.py +542 -0
  318. crackerjack/services/ai/embeddings.py +444 -0
  319. crackerjack/services/ai/intelligent_commit.py +328 -0
  320. crackerjack/services/ai/predictive_analytics.py +510 -0
  321. crackerjack/services/anomaly_detector.py +392 -0
  322. crackerjack/services/api_extractor.py +617 -0
  323. crackerjack/services/backup_service.py +467 -0
  324. crackerjack/services/bounded_status_operations.py +530 -0
  325. crackerjack/services/cache.py +369 -0
  326. crackerjack/services/changelog_automation.py +399 -0
  327. crackerjack/services/command_execution_service.py +305 -0
  328. crackerjack/services/config_integrity.py +132 -0
  329. crackerjack/services/config_merge.py +546 -0
  330. crackerjack/services/config_service.py +198 -0
  331. crackerjack/services/config_template.py +493 -0
  332. crackerjack/services/coverage_badge_service.py +173 -0
  333. crackerjack/services/coverage_ratchet.py +381 -0
  334. crackerjack/services/debug.py +733 -0
  335. crackerjack/services/dependency_analyzer.py +460 -0
  336. crackerjack/services/dependency_monitor.py +622 -0
  337. crackerjack/services/documentation_generator.py +493 -0
  338. crackerjack/services/documentation_service.py +704 -0
  339. crackerjack/services/enhanced_filesystem.py +497 -0
  340. crackerjack/services/enterprise_optimizer.py +865 -0
  341. crackerjack/services/error_pattern_analyzer.py +676 -0
  342. crackerjack/services/file_filter.py +221 -0
  343. crackerjack/services/file_hasher.py +149 -0
  344. crackerjack/services/file_io_service.py +361 -0
  345. crackerjack/services/file_modifier.py +615 -0
  346. crackerjack/services/filesystem.py +381 -0
  347. crackerjack/services/git.py +422 -0
  348. crackerjack/services/health_metrics.py +615 -0
  349. crackerjack/services/heatmap_generator.py +744 -0
  350. crackerjack/services/incremental_executor.py +380 -0
  351. crackerjack/services/initialization.py +823 -0
  352. crackerjack/services/input_validator.py +668 -0
  353. crackerjack/services/intelligent_commit.py +327 -0
  354. crackerjack/services/log_manager.py +289 -0
  355. crackerjack/services/logging.py +228 -0
  356. crackerjack/services/lsp_client.py +628 -0
  357. crackerjack/services/memory_optimizer.py +414 -0
  358. crackerjack/services/metrics.py +587 -0
  359. crackerjack/services/monitoring/README.md +30 -0
  360. crackerjack/services/monitoring/__init__.py +9 -0
  361. crackerjack/services/monitoring/dependency_monitor.py +678 -0
  362. crackerjack/services/monitoring/error_pattern_analyzer.py +676 -0
  363. crackerjack/services/monitoring/health_metrics.py +716 -0
  364. crackerjack/services/monitoring/metrics.py +587 -0
  365. crackerjack/services/monitoring/performance_benchmarks.py +410 -0
  366. crackerjack/services/monitoring/performance_cache.py +388 -0
  367. crackerjack/services/monitoring/performance_monitor.py +569 -0
  368. crackerjack/services/parallel_executor.py +527 -0
  369. crackerjack/services/pattern_cache.py +333 -0
  370. crackerjack/services/pattern_detector.py +478 -0
  371. crackerjack/services/patterns/__init__.py +142 -0
  372. crackerjack/services/patterns/agents.py +107 -0
  373. crackerjack/services/patterns/code/__init__.py +15 -0
  374. crackerjack/services/patterns/code/detection.py +118 -0
  375. crackerjack/services/patterns/code/imports.py +107 -0
  376. crackerjack/services/patterns/code/paths.py +159 -0
  377. crackerjack/services/patterns/code/performance.py +119 -0
  378. crackerjack/services/patterns/code/replacement.py +36 -0
  379. crackerjack/services/patterns/core.py +212 -0
  380. crackerjack/services/patterns/documentation/__init__.py +14 -0
  381. crackerjack/services/patterns/documentation/badges_markdown.py +96 -0
  382. crackerjack/services/patterns/documentation/comments_blocks.py +83 -0
  383. crackerjack/services/patterns/documentation/docstrings.py +89 -0
  384. crackerjack/services/patterns/formatting.py +226 -0
  385. crackerjack/services/patterns/operations.py +339 -0
  386. crackerjack/services/patterns/security/__init__.py +23 -0
  387. crackerjack/services/patterns/security/code_injection.py +122 -0
  388. crackerjack/services/patterns/security/credentials.py +190 -0
  389. crackerjack/services/patterns/security/path_traversal.py +221 -0
  390. crackerjack/services/patterns/security/unsafe_operations.py +216 -0
  391. crackerjack/services/patterns/templates.py +62 -0
  392. crackerjack/services/patterns/testing/__init__.py +18 -0
  393. crackerjack/services/patterns/testing/error_patterns.py +107 -0
  394. crackerjack/services/patterns/testing/pytest_output.py +126 -0
  395. crackerjack/services/patterns/tool_output/__init__.py +16 -0
  396. crackerjack/services/patterns/tool_output/bandit.py +72 -0
  397. crackerjack/services/patterns/tool_output/other.py +97 -0
  398. crackerjack/services/patterns/tool_output/pyright.py +67 -0
  399. crackerjack/services/patterns/tool_output/ruff.py +44 -0
  400. crackerjack/services/patterns/url_sanitization.py +114 -0
  401. crackerjack/services/patterns/utilities.py +42 -0
  402. crackerjack/services/patterns/utils.py +339 -0
  403. crackerjack/services/patterns/validation.py +46 -0
  404. crackerjack/services/patterns/versioning.py +62 -0
  405. crackerjack/services/predictive_analytics.py +523 -0
  406. crackerjack/services/profiler.py +280 -0
  407. crackerjack/services/quality/README.md +415 -0
  408. crackerjack/services/quality/__init__.py +11 -0
  409. crackerjack/services/quality/anomaly_detector.py +392 -0
  410. crackerjack/services/quality/pattern_cache.py +333 -0
  411. crackerjack/services/quality/pattern_detector.py +479 -0
  412. crackerjack/services/quality/qa_orchestrator.py +491 -0
  413. crackerjack/services/quality/quality_baseline.py +395 -0
  414. crackerjack/services/quality/quality_baseline_enhanced.py +649 -0
  415. crackerjack/services/quality/quality_intelligence.py +949 -0
  416. crackerjack/services/regex_patterns.py +58 -0
  417. crackerjack/services/regex_utils.py +483 -0
  418. crackerjack/services/secure_path_utils.py +524 -0
  419. crackerjack/services/secure_status_formatter.py +450 -0
  420. crackerjack/services/secure_subprocess.py +635 -0
  421. crackerjack/services/security.py +239 -0
  422. crackerjack/services/security_logger.py +495 -0
  423. crackerjack/services/server_manager.py +411 -0
  424. crackerjack/services/smart_scheduling.py +167 -0
  425. crackerjack/services/status_authentication.py +460 -0
  426. crackerjack/services/status_security_manager.py +315 -0
  427. crackerjack/services/terminal_utils.py +0 -0
  428. crackerjack/services/thread_safe_status_collector.py +441 -0
  429. crackerjack/services/tool_filter.py +368 -0
  430. crackerjack/services/tool_version_service.py +43 -0
  431. crackerjack/services/unified_config.py +115 -0
  432. crackerjack/services/validation_rate_limiter.py +220 -0
  433. crackerjack/services/vector_store.py +689 -0
  434. crackerjack/services/version_analyzer.py +461 -0
  435. crackerjack/services/version_checker.py +223 -0
  436. crackerjack/services/websocket_resource_limiter.py +438 -0
  437. crackerjack/services/zuban_lsp_service.py +391 -0
  438. crackerjack/slash_commands/README.md +11 -0
  439. crackerjack/slash_commands/__init__.py +59 -0
  440. crackerjack/slash_commands/init.md +112 -0
  441. crackerjack/slash_commands/run.md +197 -0
  442. crackerjack/slash_commands/status.md +127 -0
  443. crackerjack/tools/README.md +11 -0
  444. crackerjack/tools/__init__.py +30 -0
  445. crackerjack/tools/_git_utils.py +105 -0
  446. crackerjack/tools/check_added_large_files.py +139 -0
  447. crackerjack/tools/check_ast.py +105 -0
  448. crackerjack/tools/check_json.py +103 -0
  449. crackerjack/tools/check_jsonschema.py +297 -0
  450. crackerjack/tools/check_toml.py +103 -0
  451. crackerjack/tools/check_yaml.py +110 -0
  452. crackerjack/tools/codespell_wrapper.py +72 -0
  453. crackerjack/tools/end_of_file_fixer.py +202 -0
  454. crackerjack/tools/format_json.py +128 -0
  455. crackerjack/tools/mdformat_wrapper.py +114 -0
  456. crackerjack/tools/trailing_whitespace.py +198 -0
  457. crackerjack/tools/validate_input_validator_patterns.py +236 -0
  458. crackerjack/tools/validate_regex_patterns.py +188 -0
  459. crackerjack/ui/README.md +11 -0
  460. crackerjack/ui/__init__.py +1 -0
  461. crackerjack/ui/dashboard_renderer.py +28 -0
  462. crackerjack/ui/templates/README.md +11 -0
  463. crackerjack/utils/console_utils.py +13 -0
  464. crackerjack/utils/dependency_guard.py +230 -0
  465. crackerjack/utils/retry_utils.py +275 -0
  466. crackerjack/workflows/README.md +590 -0
  467. crackerjack/workflows/__init__.py +46 -0
  468. crackerjack/workflows/actions.py +811 -0
  469. crackerjack/workflows/auto_fix.py +444 -0
  470. crackerjack/workflows/container_builder.py +499 -0
  471. crackerjack/workflows/definitions.py +443 -0
  472. crackerjack/workflows/engine.py +177 -0
  473. crackerjack/workflows/event_bridge.py +242 -0
  474. crackerjack-0.45.2.dist-info/METADATA +1678 -0
  475. crackerjack-0.45.2.dist-info/RECORD +478 -0
  476. {crackerjack-0.18.2.dist-info → crackerjack-0.45.2.dist-info}/WHEEL +1 -1
  477. crackerjack-0.45.2.dist-info/entry_points.txt +2 -0
  478. crackerjack/.gitignore +0 -14
  479. crackerjack/.libcst.codemod.yaml +0 -18
  480. crackerjack/.pdm.toml +0 -1
  481. crackerjack/.pre-commit-config.yaml +0 -91
  482. crackerjack/.pytest_cache/.gitignore +0 -2
  483. crackerjack/.pytest_cache/CACHEDIR.TAG +0 -4
  484. crackerjack/.pytest_cache/README.md +0 -8
  485. crackerjack/.pytest_cache/v/cache/nodeids +0 -1
  486. crackerjack/.pytest_cache/v/cache/stepwise +0 -1
  487. crackerjack/.ruff_cache/.gitignore +0 -1
  488. crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
  489. crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
  490. crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
  491. crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
  492. crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
  493. crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
  494. crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
  495. crackerjack/.ruff_cache/0.11.3/9818742842212983150 +0 -0
  496. crackerjack/.ruff_cache/0.11.4/9818742842212983150 +0 -0
  497. crackerjack/.ruff_cache/0.11.6/3557596832929915217 +0 -0
  498. crackerjack/.ruff_cache/0.11.7/10386934055395314831 +0 -0
  499. crackerjack/.ruff_cache/0.11.7/3557596832929915217 +0 -0
  500. crackerjack/.ruff_cache/0.11.8/530407680854991027 +0 -0
  501. crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
  502. crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
  503. crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
  504. crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
  505. crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
  506. crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
  507. crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
  508. crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
  509. crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
  510. crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
  511. crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
  512. crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
  513. crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
  514. crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
  515. crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
  516. crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
  517. crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
  518. crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
  519. crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
  520. crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
  521. crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
  522. crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
  523. crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
  524. crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
  525. crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
  526. crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
  527. crackerjack/.ruff_cache/CACHEDIR.TAG +0 -1
  528. crackerjack/crackerjack.py +0 -855
  529. crackerjack/pyproject.toml +0 -214
  530. crackerjack-0.18.2.dist-info/METADATA +0 -420
  531. crackerjack-0.18.2.dist-info/RECORD +0 -59
  532. crackerjack-0.18.2.dist-info/entry_points.txt +0 -4
  533. {crackerjack-0.18.2.dist-info → crackerjack-0.45.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,367 @@
1
+ import typing as t
2
+
3
+
4
+ def _create_architectural_assessment(
5
+ args: str, parsed_kwargs: dict[str, t.Any]
6
+ ) -> dict[str, t.Any]:
7
+ assessment = {
8
+ "feature": parsed_kwargs.get("feature", "unknown"),
9
+ "complexity": parsed_kwargs.get("complexity", "medium"),
10
+ "context": args or "General development planning",
11
+ "proactive_recommendations": [],
12
+ }
13
+
14
+ recommendations = []
15
+
16
+ recommendations.append(
17
+ {
18
+ "agent": "crackerjack-architect",
19
+ "priority": "high",
20
+ "reason": "Expert architectural planning for crackerjack compliance",
21
+ "action": 'Task tool with subagent_type ="crackerjack-architect" for feature planning and architecture',
22
+ "benefits": [
23
+ "Prevents violations through proper initial architecture",
24
+ "Applies crackerjack patterns from the start",
25
+ "Reduces iteration cycles by 50 % +",
26
+ "Ensures consistency with project standards",
27
+ ],
28
+ }
29
+ )
30
+
31
+ complexity = parsed_kwargs.get("complexity", "medium")
32
+ if complexity in ("high", "complex"):
33
+ recommendations.append(
34
+ {
35
+ "agent": "refactoring-specialist",
36
+ "priority": "high",
37
+ "reason": "Complex features require careful structural planning",
38
+ "action": 'Task tool with subagent_type ="refactoring-specialist" for complexity management',
39
+ }
40
+ )
41
+
42
+ feature = parsed_kwargs.get("feature", "")
43
+ if any(
44
+ keyword in feature.lower() for keyword in ("auth", "security", "api", "data")
45
+ ):
46
+ recommendations.append(
47
+ {
48
+ "agent": "security-auditor",
49
+ "priority": "medium",
50
+ "reason": "Security-sensitive feature requires expert review",
51
+ "action": 'Task tool with subagent_type ="security-auditor" for security validation',
52
+ }
53
+ )
54
+
55
+ assessment["proactive_recommendations"] = recommendations
56
+ assessment["planning_strategy"] = "proactive_architecture_first"
57
+
58
+ return assessment
59
+
60
+
61
+ def _create_validation_results(file_path: str) -> dict[str, t.Any]:
62
+ validation = {
63
+ "file_path": file_path,
64
+ "validation_results": [],
65
+ "architectural_compliance": "unknown",
66
+ "recommendations": [],
67
+ }
68
+
69
+ compliance_checks = [
70
+ {
71
+ "check": "complexity_compliance",
72
+ "status": "requires_analysis",
73
+ "message": "Cognitive complexity should be ≤15 per function",
74
+ "tool": "complexipy",
75
+ },
76
+ {
77
+ "check": "clean_code_patterns",
78
+ "status": "requires_analysis",
79
+ "message": "Follow DRY, YAGNI, KISS principles",
80
+ "patterns": [
81
+ "extract_method",
82
+ "protocol_interfaces",
83
+ "dependency_injection",
84
+ ],
85
+ },
86
+ {
87
+ "check": "security_patterns",
88
+ "status": "requires_analysis",
89
+ "message": "Use secure temp files, proper input validation",
90
+ "tool": "bandit",
91
+ },
92
+ {
93
+ "check": "type_annotations",
94
+ "status": "requires_analysis",
95
+ "message": "All functions must have proper type hints",
96
+ "tool": "pyright",
97
+ },
98
+ ]
99
+
100
+ validation["validation_results"] = [
101
+ f"{check['check']}: {check['status']} - {check['message']}"
102
+ for check in compliance_checks
103
+ ]
104
+
105
+ validation["recommendations"] = [
106
+ "Run full crackerjack quality process: python - m crackerjack-t",
107
+ "Use crackerjack-architect for complex refactoring decisions",
108
+ "Apply pattern learning from successful fixes",
109
+ "Validate against architectural plan before committing",
110
+ ]
111
+
112
+ validation["next_steps"] = [
113
+ 'Task tool with subagent_type ="crackerjack-architect" for architectural guidance',
114
+ "Run comprehensive quality checks",
115
+ "Apply learned patterns from pattern cache",
116
+ ]
117
+
118
+ return validation
119
+
120
+
121
+ def _create_pattern_suggestions(problem_context: str) -> dict[str, t.Any]:
122
+ pattern_suggestions: dict[str, t.Any] = {
123
+ "context": problem_context,
124
+ "recommended_patterns": [],
125
+ "implementation_guidance": [],
126
+ "specialist_agents": [],
127
+ }
128
+
129
+ _add_complexity_patterns(pattern_suggestions, problem_context)
130
+ _add_dry_patterns(pattern_suggestions, problem_context)
131
+ _add_performance_patterns(pattern_suggestions, problem_context)
132
+ _add_security_patterns(pattern_suggestions, problem_context)
133
+
134
+ pattern_suggestions["specialist_agents"] = [
135
+ {
136
+ "agent": "crackerjack-architect",
137
+ "when_to_use": "For architectural decisions and complex pattern application",
138
+ "action": 'Task tool with subagent_type ="crackerjack-architect"',
139
+ },
140
+ {
141
+ "agent": "refactoring-specialist",
142
+ "when_to_use": "For complexity reduction and structural improvements",
143
+ "action": 'Task tool with subagent_type ="refactoring-specialist"',
144
+ },
145
+ {
146
+ "agent": "security-auditor",
147
+ "when_to_use": "For security pattern validation and vulnerability assessment",
148
+ "action": 'Task tool with subagent_type ="security-auditor"',
149
+ },
150
+ ]
151
+
152
+ pattern_suggestions["implementation_guidance"] = [
153
+ "Start with crackerjack-architect for overall planning",
154
+ "Apply one pattern at a time to avoid complexity",
155
+ "Validate each pattern with crackerjack quality checks",
156
+ "Cache successful patterns for future use",
157
+ "Document architectural decisions for team knowledge",
158
+ ]
159
+
160
+ if not pattern_suggestions["recommended_patterns"]:
161
+ pattern_suggestions["recommended_patterns"] = [
162
+ {
163
+ "pattern": "standard_crackerjack_patterns",
164
+ "description": "Apply standard crackerjack clean code patterns",
165
+ "benefits": [
166
+ "Consistent code quality",
167
+ "Better maintainability",
168
+ "Team alignment",
169
+ ],
170
+ }
171
+ ]
172
+
173
+ return pattern_suggestions
174
+
175
+
176
+ def _add_complexity_patterns(
177
+ pattern_suggestions: dict[str, t.Any], problem_context: str
178
+ ) -> None:
179
+ if any(
180
+ keyword in problem_context.lower()
181
+ for keyword in ("complex", "refactor", "cleanup")
182
+ ):
183
+ pattern_suggestions["recommended_patterns"].extend(
184
+ [
185
+ {
186
+ "pattern": "extract_method",
187
+ "description": "Break complex functions into smaller, focused methods",
188
+ "benefits": [
189
+ "Reduces cognitive complexity",
190
+ "Improves testability",
191
+ "Follows KISS principle",
192
+ ],
193
+ },
194
+ {
195
+ "pattern": "dependency_injection",
196
+ "description": "Use protocol interfaces for better decoupling",
197
+ "benefits": [
198
+ "Improves testability",
199
+ "Reduces coupling",
200
+ "Enables better mocking",
201
+ ],
202
+ },
203
+ ]
204
+ )
205
+
206
+
207
+ def _add_dry_patterns(
208
+ pattern_suggestions: dict[str, t.Any], problem_context: str
209
+ ) -> None:
210
+ if any(
211
+ keyword in problem_context.lower() for keyword in ("duplicate", "repeat", "dry")
212
+ ):
213
+ pattern_suggestions["recommended_patterns"].extend(
214
+ [
215
+ {
216
+ "pattern": "common_base_class",
217
+ "description": "Extract shared functionality to base classes or mixins",
218
+ "benefits": [
219
+ "Reduces duplication",
220
+ "Centralizes common logic",
221
+ "Easier maintenance",
222
+ ],
223
+ },
224
+ {
225
+ "pattern": "utility_functions",
226
+ "description": "Create reusable utility functions for common operations",
227
+ "benefits": [
228
+ "Single source of truth",
229
+ "Reduces code duplication",
230
+ "Easier testing",
231
+ ],
232
+ },
233
+ ]
234
+ )
235
+
236
+
237
+ def _add_performance_patterns(
238
+ pattern_suggestions: dict[str, t.Any], problem_context: str
239
+ ) -> None:
240
+ if any(
241
+ keyword in problem_context.lower()
242
+ for keyword in ("slow", "performance", "optimize")
243
+ ):
244
+ pattern_suggestions["recommended_patterns"].extend(
245
+ [
246
+ {
247
+ "pattern": "list_comprehension",
248
+ "description": "Use list[t.Any] comprehensions instead of manual loops",
249
+ "benefits": [
250
+ "Better performance",
251
+ "More readable",
252
+ "Pythonic code",
253
+ ],
254
+ },
255
+ {
256
+ "pattern": "generator_pattern",
257
+ "description": "Use generators for memory-efficient processing",
258
+ "benefits": [
259
+ "Reduced memory usage",
260
+ "Lazy evaluation",
261
+ "Better for large datasets",
262
+ ],
263
+ },
264
+ ]
265
+ )
266
+
267
+
268
+ def _add_security_patterns(
269
+ pattern_suggestions: dict[str, t.Any], problem_context: str
270
+ ) -> None:
271
+ if any(
272
+ keyword in problem_context.lower() for keyword in ("security", "safe", "secure")
273
+ ):
274
+ pattern_suggestions["recommended_patterns"].extend(
275
+ [
276
+ {
277
+ "pattern": "secure_temp_files",
278
+ "description": "Use tempfile module instead of hardcoded paths",
279
+ "benefits": [
280
+ "Prevents security vulnerabilities",
281
+ "Cross-platform compatibility",
282
+ "Automatic cleanup",
283
+ ],
284
+ },
285
+ {
286
+ "pattern": "input_validation",
287
+ "description": "Validate and sanitize all user inputs",
288
+ "benefits": [
289
+ "Prevents injection attacks",
290
+ "Better error handling",
291
+ "Data integrity",
292
+ ],
293
+ },
294
+ ]
295
+ )
296
+
297
+
298
+ def _create_error_response(error: Exception, recommendation: str) -> str:
299
+ import json
300
+
301
+ return json.dumps(
302
+ {
303
+ "error": str(error),
304
+ "fallback_patterns": [
305
+ "clean_code",
306
+ "single_responsibility",
307
+ "dry_principle",
308
+ ],
309
+ "recommendation": recommendation,
310
+ }
311
+ )
312
+
313
+
314
+ def register_proactive_tools(mcp_app: t.Any) -> None:
315
+ return _register_proactive_tools(mcp_app)
316
+
317
+
318
+ def _register_proactive_tools(mcp_app: t.Any) -> None:
319
+ _register_plan_development_tool(mcp_app)
320
+ _register_validate_architecture_tool(mcp_app)
321
+ _register_suggest_patterns_tool(mcp_app)
322
+
323
+
324
+ def _register_plan_development_tool(mcp_app: t.Any) -> None:
325
+ @mcp_app.tool()
326
+ async def plan_development(args: str, kwargs: str) -> str:
327
+ import json
328
+
329
+ try:
330
+ parsed_kwargs: dict[str, t.Any] = json.loads(kwargs) if kwargs else {}
331
+ assessment = _create_architectural_assessment(args, parsed_kwargs)
332
+ return json.dumps(assessment, indent=2)
333
+ except Exception as e:
334
+ return _create_error_response(e, "Use standard development approach")
335
+
336
+
337
+ def _register_validate_architecture_tool(mcp_app: t.Any) -> None:
338
+ @mcp_app.tool()
339
+ async def validate_architecture(args: str, kwargs: str) -> str:
340
+ import json
341
+
342
+ try:
343
+ parsed_kwargs: dict[str, t.Any] = json.loads(kwargs) if kwargs else {}
344
+ file_path = args or parsed_kwargs.get("file_path", "")
345
+ validation = _create_validation_results(file_path)
346
+ return json.dumps(validation, indent=2)
347
+ except Exception as e:
348
+ return _create_error_response(
349
+ e, "Run standard crackerjack validation: python-m crackerjack"
350
+ )
351
+
352
+
353
+ def _register_suggest_patterns_tool(mcp_app: t.Any) -> None:
354
+ @mcp_app.tool()
355
+ async def suggest_patterns(args: str, kwargs: str) -> str:
356
+ import json
357
+
358
+ try:
359
+ json.loads(kwargs) if kwargs else {}
360
+ problem_context = args or "General pattern suggestions"
361
+ pattern_suggestions = _create_pattern_suggestions(problem_context)
362
+ return json.dumps(pattern_suggestions, indent=2)
363
+ except Exception as e:
364
+ return _create_error_response(
365
+ e,
366
+ 'Use Task tool with subagent_type ="crackerjack-architect" for expert guidance',
367
+ )
@@ -0,0 +1,222 @@
1
+ import contextlib
2
+ import json
3
+ import typing as t
4
+ from pathlib import Path
5
+
6
+ from crackerjack.mcp.context import get_context
7
+ from crackerjack.services.input_validator import get_input_validator
8
+
9
+
10
+ def _create_progress_file(job_id: str) -> Path:
11
+ import tempfile
12
+
13
+ job_id_result = get_input_validator().validate_job_id(job_id)
14
+
15
+ if not job_id_result.valid:
16
+ msg = f"Invalid job_id: {job_id_result.error_message}"
17
+ raise ValueError(msg)
18
+
19
+ sanitized_job_id = job_id_result.sanitized_value
20
+
21
+ context = get_context()
22
+ if context:
23
+ return context.progress_dir / f"job-{sanitized_job_id}.json"
24
+
25
+ progress_dir = Path(tempfile.gettempdir()) / "crackerjack-mcp-progress"
26
+ progress_dir.mkdir(exist_ok=True, mode=0o750)
27
+ return progress_dir / f"job-{sanitized_job_id}.json"
28
+
29
+
30
+ def _clamp_progress(value: int) -> int:
31
+ return min(100, max(0, value))
32
+
33
+
34
+ def _get_timestamp() -> str:
35
+ context = get_context()
36
+ return context.get_current_time() if context else ""
37
+
38
+
39
+ def _build_dict_format_progress(
40
+ job_id: str,
41
+ progress_data: dict[str, t.Any],
42
+ iteration: int,
43
+ max_iterations: int,
44
+ overall_progress: int,
45
+ current_stage: str,
46
+ stage_progress: int,
47
+ message: str,
48
+ ) -> dict[str, t.Any]:
49
+ return {
50
+ "job_id": job_id,
51
+ "status": progress_data.get("status", "running"),
52
+ "iteration": progress_data.get("iteration", iteration),
53
+ "max_iterations": progress_data.get("max_iterations", max_iterations),
54
+ "overall_progress": _clamp_progress(
55
+ progress_data.get("overall_progress", overall_progress)
56
+ ),
57
+ "current_stage": progress_data.get("type", current_stage),
58
+ "stage_progress": _clamp_progress(
59
+ progress_data.get("stage_progress", stage_progress)
60
+ ),
61
+ "message": progress_data.get("message", message),
62
+ "timestamp": _get_timestamp(),
63
+ }
64
+
65
+
66
+ def _build_legacy_format_progress(
67
+ job_id: str,
68
+ progress_data: str | None,
69
+ iteration: int,
70
+ max_iterations: int,
71
+ overall_progress: int,
72
+ current_stage: str,
73
+ stage_progress: int,
74
+ message: str,
75
+ ) -> dict[str, t.Any]:
76
+ status = progress_data if isinstance(progress_data, str) else "running"
77
+ return {
78
+ "job_id": job_id,
79
+ "status": status,
80
+ "iteration": iteration,
81
+ "max_iterations": max_iterations,
82
+ "overall_progress": _clamp_progress(overall_progress),
83
+ "current_stage": current_stage,
84
+ "stage_progress": _clamp_progress(stage_progress),
85
+ "message": message,
86
+ "timestamp": _get_timestamp(),
87
+ }
88
+
89
+
90
+ def _notify_websocket(final_progress_data: dict[str, t.Any]) -> None:
91
+ context = get_context()
92
+ if context and hasattr(context, "websocket_progress_queue"):
93
+ with contextlib.suppress(Exception):
94
+ context.websocket_progress_queue.put_nowait(final_progress_data)
95
+
96
+
97
+ def _update_progress(
98
+ job_id: str,
99
+ progress_data: dict[str, t.Any] | str | None = None,
100
+ context: t.Any = None,
101
+ iteration: int = 1,
102
+ max_iterations: int = 5,
103
+ overall_progress: int = 0,
104
+ current_stage: str = "initialization",
105
+ stage_progress: int = 0,
106
+ message: str = "",
107
+ ) -> None:
108
+ try:
109
+ progress_file = _create_progress_file(job_id)
110
+
111
+ if isinstance(progress_data, dict):
112
+ final_progress_data = _build_dict_format_progress(
113
+ job_id,
114
+ progress_data,
115
+ iteration,
116
+ max_iterations,
117
+ overall_progress,
118
+ current_stage,
119
+ stage_progress,
120
+ message,
121
+ )
122
+ else:
123
+ final_progress_data = _build_legacy_format_progress(
124
+ job_id,
125
+ progress_data,
126
+ iteration,
127
+ max_iterations,
128
+ overall_progress,
129
+ current_stage,
130
+ stage_progress,
131
+ message,
132
+ )
133
+
134
+ progress_file.write_text(json.dumps(final_progress_data, indent=2))
135
+ _notify_websocket(final_progress_data)
136
+
137
+ except Exception as e:
138
+ context = get_context()
139
+ if context:
140
+ context.safe_print(f"Warning: Failed to update progress for {job_id}: {e}")
141
+
142
+
143
+ def _handle_get_job_progress(job_id: str) -> str:
144
+ context = get_context()
145
+ if not context:
146
+ return '{"error": "Server context not available"}'
147
+
148
+ if not context.validate_job_id(job_id):
149
+ return f'{{"error": "Invalid job_id: {job_id}"}}'
150
+
151
+ try:
152
+ progress_file = _create_progress_file(job_id)
153
+
154
+ if not progress_file.exists():
155
+ return f'{{"error": "Job {job_id} not found", "job_id": "{job_id}"}}'
156
+
157
+ progress_data = json.loads(progress_file.read_text())
158
+ return json.dumps(progress_data, indent=2)
159
+
160
+ except json.JSONDecodeError as e:
161
+ return f'{{"error": "Invalid progress data for job {job_id}: {e}"}}'
162
+ except Exception as e:
163
+ return f'{{"error": "Failed to get progress for job {job_id}: {e}"}}'
164
+
165
+
166
+ async def _execute_session_action(
167
+ state_manager: t.Any,
168
+ action: str,
169
+ checkpoint_name: str | None,
170
+ context: t.Any,
171
+ ) -> str:
172
+ if action == "start":
173
+ state_manager.start_session()
174
+ return '{"status": "session_started", "action": "start"}'
175
+
176
+ if action == "checkpoint":
177
+ checkpoint_name = checkpoint_name or f"checkpoint_{context.get_current_time()}"
178
+ await state_manager.save_checkpoint(checkpoint_name)
179
+ return f'{{"status": "checkpoint_created", "action": "checkpoint", "name": "{checkpoint_name}"}}'
180
+
181
+ if action == "complete":
182
+ state_manager.complete_session()
183
+ return '{"status": "session_completed", "action": "complete"}'
184
+
185
+ if action == "reset":
186
+ state_manager.reset_session()
187
+ return '{"status": "session_reset", "action": "reset"}'
188
+
189
+ return f'{{"error": "Invalid action: {action}. Valid actions: start, checkpoint, complete, reset"}}'
190
+
191
+
192
+ async def _handle_session_management(
193
+ action: str, checkpoint_name: str | None = None
194
+ ) -> str:
195
+ context = get_context()
196
+ if not context:
197
+ return '{"error": "Server context not available"}'
198
+
199
+ try:
200
+ state_manager = getattr(context, "state_manager", None)
201
+ if not state_manager:
202
+ return '{"error": "State manager not available"}'
203
+
204
+ return await _execute_session_action(
205
+ state_manager, action, checkpoint_name, context
206
+ )
207
+
208
+ except Exception as e:
209
+ return f'{{"error": "Session management failed: {e}"}}'
210
+
211
+
212
+ def register_progress_tools(mcp_app: t.Any) -> None:
213
+ @mcp_app.tool()
214
+ async def get_job_progress(job_id: str) -> str:
215
+ return _handle_get_job_progress(job_id)
216
+
217
+ @mcp_app.tool()
218
+ async def session_management(
219
+ action: str,
220
+ checkpoint_name: str | None = None,
221
+ ) -> str:
222
+ return await _handle_session_management(action, checkpoint_name)