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,878 @@
1
+ """Advanced-scale optimization service for monitoring system."""
2
+
3
+ import json
4
+ import logging
5
+ import statistics
6
+ import threading
7
+ import time
8
+ import typing as t
9
+ from collections import deque
10
+ from concurrent.futures import ThreadPoolExecutor
11
+ from dataclasses import asdict, dataclass, field
12
+ from datetime import datetime, timedelta
13
+ from pathlib import Path
14
+
15
+ import psutil
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ @dataclass
21
+ class ResourceMetrics:
22
+ """System resource utilization metrics."""
23
+
24
+ cpu_percent: float
25
+ memory_percent: float
26
+ disk_usage_percent: float
27
+ network_io: dict[str, int]
28
+ active_connections: int
29
+ thread_count: int
30
+ file_descriptors: int
31
+ timestamp: datetime = field(default_factory=datetime.now)
32
+
33
+ def to_dict(self) -> dict[str, t.Any]:
34
+ """Convert to dictionary for JSON serialization."""
35
+ return {
36
+ "cpu_percent": self.cpu_percent,
37
+ "memory_percent": self.memory_percent,
38
+ "disk_usage_percent": self.disk_usage_percent,
39
+ "network_io": self.network_io,
40
+ "active_connections": self.active_connections,
41
+ "thread_count": self.thread_count,
42
+ "file_descriptors": self.file_descriptors,
43
+ "timestamp": self.timestamp.isoformat(),
44
+ }
45
+
46
+
47
+ @dataclass
48
+ class PerformanceProfile:
49
+ """Performance profile for optimization decisions."""
50
+
51
+ workload_type: str # light, moderate, heavy, extreme
52
+ concurrent_clients: int
53
+ data_retention_days: int
54
+ analysis_frequency_minutes: int
55
+ resource_limits: dict[str, t.Any]
56
+ optimization_strategy: str # balanced, performance, memory, throughput
57
+
58
+ def to_dict(self) -> dict[str, t.Any]:
59
+ """Convert to dictionary for JSON serialization."""
60
+ return asdict(self)
61
+
62
+
63
+ @dataclass
64
+ class OptimizationRecommendation:
65
+ """Optimization recommendation with implementation details."""
66
+
67
+ category: str # performance, memory, storage, network
68
+ priority: str # critical, high, medium, low
69
+ title: str
70
+ description: str
71
+ impact: str
72
+ implementation: str
73
+ estimated_improvement: str
74
+ resource_cost: str
75
+ risk_level: str # low, medium, high
76
+
77
+ def to_dict(self) -> dict[str, t.Any]:
78
+ """Convert to dictionary for JSON serialization."""
79
+ return asdict(self)
80
+
81
+
82
+ @dataclass
83
+ class ScalingMetrics:
84
+ """Metrics for auto-scaling decisions."""
85
+
86
+ current_load: float # 0.0 to 1.0
87
+ projected_load: float
88
+ response_time_p95: float
89
+ error_rate: float
90
+ memory_pressure: float
91
+ cpu_saturation: float
92
+ recommended_scale_factor: float
93
+ confidence_score: float
94
+
95
+ def to_dict(self) -> dict[str, t.Any]:
96
+ """Convert to dictionary for JSON serialization."""
97
+ return asdict(self)
98
+
99
+
100
+ class ConnectionPool:
101
+ """Optimized connection pool for WebSocket management."""
102
+
103
+ def __init__(self, max_connections: int = 1000, cleanup_interval: int = 300):
104
+ """Initialize connection pool with limits and cleanup."""
105
+ self.max_connections = max_connections
106
+ self.cleanup_interval = cleanup_interval
107
+ self.connections: dict[str, t.Any] = {}
108
+ self.connection_stats: dict[str, dict[str, t.Any]] = {}
109
+ self.last_cleanup = time.time()
110
+ self._lock = threading.Lock()
111
+
112
+ def add_connection(
113
+ self,
114
+ connection_id: str,
115
+ websocket: t.Any,
116
+ metadata: dict[str, t.Any] | None = None,
117
+ ) -> None:
118
+ """Add connection with automatic cleanup if at capacity."""
119
+ with self._lock:
120
+ # Clean up stale connections if at capacity
121
+ if len(self.connections) >= self.max_connections:
122
+ self._cleanup_stale_connections()
123
+
124
+ # If still at capacity, remove oldest connection
125
+ if len(self.connections) >= self.max_connections:
126
+ oldest_id = min(
127
+ self.connection_stats.keys(),
128
+ key=lambda x: self.connection_stats[x]["last_activity"],
129
+ )
130
+ self.remove_connection(oldest_id)
131
+
132
+ self.connections[connection_id] = websocket
133
+ self.connection_stats[connection_id] = {
134
+ "created": time.time(),
135
+ "last_activity": time.time(),
136
+ "message_count": 0,
137
+ "metadata": metadata or {},
138
+ }
139
+
140
+ def remove_connection(self, connection_id: str) -> None:
141
+ """Remove connection and cleanup resources."""
142
+ with self._lock:
143
+ if connection_id in self.connections:
144
+ del self.connections[connection_id]
145
+ if connection_id in self.connection_stats:
146
+ del self.connection_stats[connection_id]
147
+
148
+ def update_activity(self, connection_id: str) -> None:
149
+ """Update last activity timestamp."""
150
+ with self._lock:
151
+ if connection_id in self.connection_stats:
152
+ self.connection_stats[connection_id]["last_activity"] = time.time()
153
+ self.connection_stats[connection_id]["message_count"] += 1
154
+
155
+ def _cleanup_stale_connections(self) -> None:
156
+ """Remove stale connections based on inactivity."""
157
+ current_time = time.time()
158
+ stale_threshold = 1800 # 30 minutes
159
+
160
+ stale_connections = [
161
+ conn_id
162
+ for conn_id, stats in self.connection_stats.items()
163
+ if current_time - stats["last_activity"] > stale_threshold
164
+ ]
165
+
166
+ for conn_id in stale_connections:
167
+ self.remove_connection(conn_id)
168
+
169
+ self.last_cleanup = current_time
170
+ logger.info(f"Cleaned up {len(stale_connections)} stale connections")
171
+
172
+ def get_stats(self) -> dict[str, t.Any]:
173
+ """Get connection pool statistics."""
174
+ with self._lock:
175
+ current_time = time.time()
176
+ active_count = len(
177
+ [
178
+ conn
179
+ for conn, stats in self.connection_stats.items()
180
+ if current_time - stats["last_activity"]
181
+ < 300 # Active in last 5 minutes
182
+ ]
183
+ )
184
+
185
+ return {
186
+ "total_connections": len(self.connections),
187
+ "active_connections": active_count,
188
+ "max_connections": self.max_connections,
189
+ "utilization_percent": (len(self.connections) / self.max_connections)
190
+ * 100,
191
+ "average_message_count": statistics.mean(
192
+ [stats["message_count"] for stats in self.connection_stats.values()]
193
+ )
194
+ if self.connection_stats
195
+ else 0,
196
+ }
197
+
198
+
199
+ class DataCompactionManager:
200
+ """Manages data compaction and archival for advanced scale."""
201
+
202
+ def __init__(self, storage_dir: Path, max_storage_gb: float = 10.0):
203
+ """Initialize with storage limits."""
204
+ self.storage_dir = Path(storage_dir)
205
+ self.max_storage_bytes = max_storage_gb * 1024**3
206
+ self.compaction_rules = self._load_compaction_rules()
207
+
208
+ def _load_compaction_rules(self) -> dict[str, dict[str, t.Any]]:
209
+ """Load data retention and compaction rules."""
210
+ rules = {}
211
+
212
+ # Raw metrics configuration
213
+ rules["metrics_raw"] = self._create_metrics_raw_config()
214
+
215
+ # Hourly metrics configuration
216
+ rules["metrics_hourly"] = self._create_metrics_hourly_config()
217
+
218
+ # Daily metrics configuration
219
+ rules["metrics_daily"] = self._create_metrics_daily_config()
220
+
221
+ # Error patterns configuration
222
+ rules["error_patterns"] = self._create_error_patterns_config()
223
+
224
+ # Dependency graphs configuration
225
+ rules["dependency_graphs"] = self._create_dependency_graphs_config()
226
+
227
+ return rules
228
+
229
+ @staticmethod
230
+ def _create_metrics_raw_config() -> dict[str, t.Any]:
231
+ """Create configuration for raw metrics data."""
232
+ return {
233
+ "retention_days": 7,
234
+ "compaction_interval_hours": 1,
235
+ "aggregation_method": "downsample",
236
+ }
237
+
238
+ @staticmethod
239
+ def _create_metrics_hourly_config() -> dict[str, t.Any]:
240
+ """Create configuration for hourly metrics data."""
241
+ return {
242
+ "retention_days": 30,
243
+ "compaction_interval_hours": 24,
244
+ "aggregation_method": "statistical",
245
+ }
246
+
247
+ @staticmethod
248
+ def _create_metrics_daily_config() -> dict[str, t.Any]:
249
+ """Create configuration for daily metrics data."""
250
+ return {
251
+ "retention_days": 365,
252
+ "compaction_interval_hours": 168, # Weekly
253
+ "aggregation_method": "statistical",
254
+ }
255
+
256
+ @staticmethod
257
+ def _create_error_patterns_config() -> dict[str, t.Any]:
258
+ """Create configuration for error patterns data."""
259
+ return {
260
+ "retention_days": 90,
261
+ "compaction_interval_hours": 24,
262
+ "aggregation_method": "deduplication",
263
+ }
264
+
265
+ @staticmethod
266
+ def _create_dependency_graphs_config() -> dict[str, t.Any]:
267
+ """Create configuration for dependency graphs data."""
268
+ return {
269
+ "retention_days": 30,
270
+ "compaction_interval_hours": 24,
271
+ "aggregation_method": "latest_version",
272
+ }
273
+
274
+ def compact_data(self, data_type: str) -> dict[str, t.Any]:
275
+ """Perform data compaction based on rules."""
276
+ if data_type not in self.compaction_rules:
277
+ return {"status": "error", "message": f"Unknown data type: {data_type}"}
278
+
279
+ rules = self.compaction_rules[data_type]
280
+ cutoff_date = self._calculate_cutoff_date(rules)
281
+
282
+ compaction_stats = self._process_data_directory(data_type, cutoff_date)
283
+
284
+ return self._build_compaction_result(data_type, rules, compaction_stats)
285
+
286
+ @staticmethod
287
+ def _calculate_cutoff_date(rules: dict[str, t.Any]) -> datetime:
288
+ """Calculate the cutoff date for data retention."""
289
+ return datetime.now() - timedelta(days=rules["retention_days"])
290
+
291
+ def _process_data_directory(
292
+ self, data_type: str, cutoff_date: datetime
293
+ ) -> dict[str, int | float]:
294
+ """Process files in data directory and return compaction statistics."""
295
+ compacted_records = 0
296
+ freed_space_mb: float = 0.0
297
+
298
+ data_dir = self.storage_dir / data_type
299
+ if data_dir.exists():
300
+ for file_path in data_dir.glob("**/*"):
301
+ if self._should_compact_file(file_path, cutoff_date):
302
+ file_size_mb = file_path.stat().st_size / (1024**2)
303
+ freed_space_mb += file_size_mb
304
+ compacted_records += 1
305
+ # In production, would actually delete/archive the file
306
+ # file_path.unlink()
307
+
308
+ return {
309
+ "compacted_records": compacted_records,
310
+ "freed_space_mb": freed_space_mb,
311
+ }
312
+
313
+ @staticmethod
314
+ def _should_compact_file(file_path: Path, cutoff_date: datetime) -> bool:
315
+ """Determine if a file should be compacted based on age."""
316
+ if not file_path.is_file():
317
+ return False
318
+
319
+ file_mtime = datetime.fromtimestamp(file_path.stat().st_mtime)
320
+ return file_mtime < cutoff_date
321
+
322
+ @staticmethod
323
+ def _build_compaction_result(
324
+ data_type: str, rules: dict[str, t.Any], stats: dict[str, int]
325
+ ) -> dict[str, t.Any]:
326
+ """Build the compaction result dictionary."""
327
+ return {
328
+ "status": "success",
329
+ "data_type": data_type,
330
+ "compacted_records": stats["compacted_records"],
331
+ "freed_space_mb": round(stats["freed_space_mb"], 2),
332
+ "retention_days": rules["retention_days"],
333
+ "next_compaction": datetime.now()
334
+ + timedelta(hours=rules["compaction_interval_hours"]),
335
+ }
336
+
337
+ def get_storage_usage(self) -> dict[str, t.Any]:
338
+ """Get detailed storage usage information."""
339
+ total_size, type_sizes = self._calculate_storage_sizes()
340
+ return self._build_storage_usage_report(total_size, type_sizes)
341
+
342
+ def _calculate_storage_sizes(self) -> tuple[int, dict[str, int]]:
343
+ """Calculate total storage size and size by data type."""
344
+ total_size = 0
345
+ type_sizes = {}
346
+
347
+ if self.storage_dir.exists():
348
+ for data_type in self.compaction_rules.keys():
349
+ type_size = self._calculate_data_type_size(data_type)
350
+ type_sizes[data_type] = type_size
351
+ total_size += type_size
352
+
353
+ return total_size, type_sizes
354
+
355
+ def _calculate_data_type_size(self, data_type: str) -> int:
356
+ """Calculate storage size for a specific data type."""
357
+ data_dir = self.storage_dir / data_type
358
+ type_size = 0
359
+
360
+ if data_dir.exists():
361
+ for file_path in data_dir.glob("**/*"):
362
+ if file_path.is_file():
363
+ type_size += file_path.stat().st_size
364
+
365
+ return type_size
366
+
367
+ def _build_storage_usage_report(
368
+ self, total_size: int, type_sizes: dict[str, int]
369
+ ) -> dict[str, t.Any]:
370
+ """Build the storage usage report dictionary."""
371
+ return {
372
+ "total_size_gb": round(total_size / (1024**3), 3),
373
+ "max_size_gb": round(self.max_storage_bytes / (1024**3), 3),
374
+ "utilization_percent": self._calculate_utilization_percent(total_size),
375
+ "by_type_mb": {k: round(v / (1024**2), 2) for k, v in type_sizes.items()},
376
+ "compaction_needed": total_size > (self.max_storage_bytes * 0.8),
377
+ }
378
+
379
+ def _calculate_utilization_percent(self, total_size: int) -> float:
380
+ """Calculate storage utilization percentage."""
381
+ if self.max_storage_bytes > 0:
382
+ return round((total_size / self.max_storage_bytes) * 100, 2)
383
+ return 0.0
384
+
385
+
386
+ class AdvancedOptimizer:
387
+ """Advanced-scale optimization engine for monitoring system."""
388
+
389
+ def __init__(self, config_dir: Path, storage_dir: Path):
390
+ """Initialize optimizer with configuration and storage paths."""
391
+ self.config_dir = Path(config_dir)
392
+ self.storage_dir = Path(storage_dir)
393
+
394
+ # Initialize components
395
+ self.connection_pool = ConnectionPool()
396
+ self.compaction_manager = DataCompactionManager(storage_dir)
397
+ self.executor = ThreadPoolExecutor(max_workers=4)
398
+
399
+ # Metrics tracking
400
+ self.resource_history: deque[ResourceMetrics] = deque(
401
+ maxlen=1440
402
+ ) # 24 hours of minute-level data
403
+ self.performance_profile = self._load_performance_profile()
404
+
405
+ # Optimization state
406
+ self.last_optimization = datetime.now()
407
+ self.optimization_recommendations: list[OptimizationRecommendation] = []
408
+
409
+ def _load_performance_profile(self) -> PerformanceProfile:
410
+ """Load or create default performance profile."""
411
+ profile_path = self.config_dir / "performance_profile.json"
412
+
413
+ if profile_path.exists():
414
+ try:
415
+ with profile_path.open() as f:
416
+ data = json.load(f)
417
+ return PerformanceProfile(**data)
418
+ except Exception as e:
419
+ logger.warning(f"Failed to load performance profile: {e}")
420
+
421
+ # Return default profile for moderate workload
422
+ return PerformanceProfile(
423
+ workload_type="moderate",
424
+ concurrent_clients=100,
425
+ data_retention_days=30,
426
+ analysis_frequency_minutes=5,
427
+ resource_limits={
428
+ "max_memory_gb": 4.0,
429
+ "max_cpu_percent": 80.0,
430
+ "max_disk_gb": 10.0,
431
+ },
432
+ optimization_strategy="balanced",
433
+ )
434
+
435
+ def collect_resource_metrics(self) -> ResourceMetrics:
436
+ """Collect current system resource metrics."""
437
+ try:
438
+ # CPU metrics
439
+ cpu_percent = psutil.cpu_percent(interval=1)
440
+
441
+ # Memory metrics
442
+ memory = psutil.virtual_memory()
443
+ memory_percent = memory.percent
444
+
445
+ # Disk metrics
446
+ disk_usage = psutil.disk_usage(str(self.storage_dir))
447
+ disk_percent = (disk_usage.used / disk_usage.total) * 100
448
+
449
+ # Network metrics
450
+ net_io = psutil.net_io_counters()
451
+ network_io = {
452
+ "bytes_sent": net_io.bytes_sent,
453
+ "bytes_recv": net_io.bytes_recv,
454
+ "packets_sent": net_io.packets_sent,
455
+ "packets_recv": net_io.packets_recv,
456
+ }
457
+
458
+ # Process metrics
459
+ process = psutil.Process()
460
+ active_connections = len(process.connections())
461
+ thread_count = process.num_threads()
462
+ file_descriptors = process.num_fds() if hasattr(process, "num_fds") else 0
463
+
464
+ metrics = ResourceMetrics(
465
+ cpu_percent=cpu_percent,
466
+ memory_percent=memory_percent,
467
+ disk_usage_percent=disk_percent,
468
+ network_io=network_io,
469
+ active_connections=active_connections,
470
+ thread_count=thread_count,
471
+ file_descriptors=file_descriptors,
472
+ )
473
+
474
+ # Store in history
475
+ self.resource_history.append(metrics)
476
+
477
+ return metrics
478
+
479
+ except Exception as e:
480
+ logger.error(f"Failed to collect resource metrics: {e}")
481
+ return ResourceMetrics(
482
+ cpu_percent=0.0,
483
+ memory_percent=0.0,
484
+ disk_usage_percent=0.0,
485
+ network_io={},
486
+ active_connections=0,
487
+ thread_count=0,
488
+ file_descriptors=0,
489
+ )
490
+
491
+ def analyze_scaling_needs(self) -> ScalingMetrics:
492
+ """Analyze current load and recommend scaling actions."""
493
+ if len(self.resource_history) < 10:
494
+ # Not enough data for analysis
495
+ return ScalingMetrics(
496
+ current_load=0.0,
497
+ projected_load=0.0,
498
+ response_time_p95=100.0,
499
+ error_rate=0.0,
500
+ memory_pressure=0.0,
501
+ cpu_saturation=0.0,
502
+ recommended_scale_factor=1.0,
503
+ confidence_score=0.0,
504
+ )
505
+
506
+ recent_metrics = list[t.Any](self.resource_history)[-10:] # Last 10 minutes
507
+
508
+ # Calculate current load indicators
509
+ avg_cpu = statistics.mean([m.cpu_percent for m in recent_metrics])
510
+ avg_memory = statistics.mean([m.memory_percent for m in recent_metrics])
511
+ statistics.mean([m.active_connections for m in recent_metrics])
512
+
513
+ # Current load calculation (0.0 to 1.0)
514
+ current_load = max(avg_cpu / 100.0, avg_memory / 100.0)
515
+
516
+ # Trend analysis for projection
517
+ if len(recent_metrics) >= 5:
518
+ cpu_trend = (
519
+ recent_metrics[-1].cpu_percent - recent_metrics[-5].cpu_percent
520
+ ) / 5
521
+ memory_trend = (
522
+ recent_metrics[-1].memory_percent - recent_metrics[-5].memory_percent
523
+ ) / 5
524
+ projected_load = min(
525
+ 1.0, current_load + max(cpu_trend, memory_trend) / 100.0
526
+ )
527
+ else:
528
+ projected_load = current_load
529
+
530
+ # Memory pressure (based on rate of increase)
531
+ memory_pressure = min(1.0, avg_memory / 100.0)
532
+ if len(recent_metrics) >= 3:
533
+ memory_velocity = (
534
+ recent_metrics[-1].memory_percent - recent_metrics[-3].memory_percent
535
+ ) / 3
536
+ memory_pressure += memory_velocity / 100.0
537
+
538
+ # CPU saturation
539
+ cpu_saturation = min(1.0, avg_cpu / 100.0)
540
+
541
+ # Scaling recommendation
542
+ if projected_load > 0.8 or memory_pressure > 0.85:
543
+ scale_factor = 1.5 # Scale up
544
+ elif projected_load < 0.3 and memory_pressure < 0.4:
545
+ scale_factor = 0.8 # Scale down
546
+ else:
547
+ scale_factor = 1.0 # No scaling
548
+
549
+ # Confidence based on data consistency
550
+ cpu_variance = statistics.variance([m.cpu_percent for m in recent_metrics])
551
+ memory_variance = statistics.variance(
552
+ [m.memory_percent for m in recent_metrics]
553
+ )
554
+ confidence_score = max(0.0, 1.0 - (cpu_variance + memory_variance) / 2000.0)
555
+
556
+ return ScalingMetrics(
557
+ current_load=current_load,
558
+ projected_load=projected_load,
559
+ response_time_p95=100.0, # Would be measured from actual requests
560
+ error_rate=0.0, # Would be measured from actual errors
561
+ memory_pressure=memory_pressure,
562
+ cpu_saturation=cpu_saturation,
563
+ recommended_scale_factor=scale_factor,
564
+ confidence_score=confidence_score,
565
+ )
566
+
567
+ def generate_optimization_recommendations(self) -> list[OptimizationRecommendation]:
568
+ """Generate optimization recommendations based on current metrics."""
569
+ recommendations: list[OptimizationRecommendation] = []
570
+
571
+ if not self.resource_history:
572
+ return recommendations
573
+
574
+ latest_metrics = self.resource_history[-1]
575
+ scaling_metrics = self.analyze_scaling_needs()
576
+ storage_usage = self.compaction_manager.get_storage_usage()
577
+
578
+ # Generate different types of recommendations
579
+ recommendations.extend(self._generate_cpu_recommendations(latest_metrics))
580
+ recommendations.extend(self._generate_memory_recommendations(latest_metrics))
581
+ recommendations.extend(self._generate_storage_recommendations(storage_usage))
582
+ recommendations.extend(self._generate_connection_recommendations())
583
+ recommendations.extend(self._generate_scaling_recommendations(scaling_metrics))
584
+
585
+ self.optimization_recommendations = recommendations
586
+ return recommendations
587
+
588
+ @staticmethod
589
+ def _generate_cpu_recommendations(
590
+ metrics: ResourceMetrics,
591
+ ) -> list[OptimizationRecommendation]:
592
+ """Generate CPU-related optimization recommendations."""
593
+ recommendations: list[OptimizationRecommendation] = []
594
+
595
+ if metrics.cpu_percent > 80:
596
+ recommendations.append(
597
+ OptimizationRecommendation(
598
+ category="performance",
599
+ priority="high",
600
+ title="High CPU Usage Detected",
601
+ description=f"CPU usage at {metrics.cpu_percent:.1f}%, approaching saturation",
602
+ impact="May cause response time degradation and request queuing",
603
+ implementation="Consider scaling horizontally or optimizing CPU-intensive operations",
604
+ estimated_improvement="20-40% response time improvement",
605
+ resource_cost="Medium - additional compute resources",
606
+ risk_level="low",
607
+ )
608
+ )
609
+
610
+ return recommendations
611
+
612
+ @staticmethod
613
+ def _generate_memory_recommendations(
614
+ metrics: ResourceMetrics,
615
+ ) -> list[OptimizationRecommendation]:
616
+ """Generate memory-related optimization recommendations."""
617
+ recommendations: list[OptimizationRecommendation] = []
618
+
619
+ if metrics.memory_percent > 85:
620
+ recommendations.append(
621
+ OptimizationRecommendation(
622
+ category="memory",
623
+ priority="critical",
624
+ title="Memory Pressure Critical",
625
+ description=f"Memory usage at {metrics.memory_percent:.1f}%, risk of OOM",
626
+ impact="High risk of application crashes and data loss",
627
+ implementation="Immediately reduce memory consumption or add memory resources",
628
+ estimated_improvement="Prevents system crashes",
629
+ resource_cost="High - memory upgrade or optimization effort",
630
+ risk_level="high",
631
+ )
632
+ )
633
+
634
+ return recommendations
635
+
636
+ @staticmethod
637
+ def _generate_storage_recommendations(
638
+ storage_usage: dict[str, t.Any],
639
+ ) -> list[OptimizationRecommendation]:
640
+ """Generate storage-related optimization recommendations."""
641
+ recommendations: list[OptimizationRecommendation] = []
642
+
643
+ if storage_usage["utilization_percent"] > 80:
644
+ recommendations.append(
645
+ OptimizationRecommendation(
646
+ category="storage",
647
+ priority="high",
648
+ title="Storage Capacity Warning",
649
+ description=f"Storage at {storage_usage['utilization_percent']:.1f}% capacity",
650
+ impact="Risk of data collection failures and service degradation",
651
+ implementation="Run data compaction or extend storage capacity",
652
+ estimated_improvement="Frees 30-50% storage space",
653
+ resource_cost="Low - automated compaction process",
654
+ risk_level="low",
655
+ )
656
+ )
657
+
658
+ return recommendations
659
+
660
+ def _generate_connection_recommendations(self) -> list[OptimizationRecommendation]:
661
+ """Generate connection pool optimization recommendations."""
662
+ recommendations: list[OptimizationRecommendation] = []
663
+
664
+ pool_stats = self.connection_pool.get_stats()
665
+ if pool_stats["utilization_percent"] > 90:
666
+ recommendations.append(
667
+ OptimizationRecommendation(
668
+ category="network",
669
+ priority="medium",
670
+ title="Connection Pool Near Capacity",
671
+ description=f"WebSocket connections at {pool_stats['utilization_percent']:.1f}% capacity",
672
+ impact="New client connections may be rejected",
673
+ implementation="Increase connection pool size or implement connection sharing",
674
+ estimated_improvement="Supports 2-3x more concurrent clients",
675
+ resource_cost="Low - configuration change",
676
+ risk_level="low",
677
+ )
678
+ )
679
+
680
+ return recommendations
681
+
682
+ @staticmethod
683
+ def _generate_scaling_recommendations(
684
+ self, scaling_metrics: ScalingMetrics
685
+ ) -> list[OptimizationRecommendation]:
686
+ """Generate scaling-related optimization recommendations."""
687
+ recommendations: list[OptimizationRecommendation] = []
688
+
689
+ if scaling_metrics.recommended_scale_factor > 1.2:
690
+ recommendations.append(
691
+ OptimizationRecommendation(
692
+ category="performance",
693
+ priority="medium",
694
+ title="Horizontal Scaling Recommended",
695
+ description=f"Load analysis suggests {scaling_metrics.recommended_scale_factor:.1f}x scaling",
696
+ impact="Current load may exceed capacity during peak usage",
697
+ implementation="Deploy additional monitoring service instances",
698
+ estimated_improvement="Improved reliability and response times",
699
+ resource_cost="Medium - additional infrastructure",
700
+ risk_level="medium",
701
+ )
702
+ )
703
+
704
+ return recommendations
705
+
706
+ def optimize_configuration(self, strategy: str | None = None) -> dict[str, t.Any]:
707
+ """Apply automatic configuration optimizations."""
708
+ if strategy is None:
709
+ strategy = self.performance_profile.optimization_strategy
710
+
711
+ latest_metrics = self._get_latest_metrics()
712
+ if not latest_metrics:
713
+ return {"status": "error", "message": "No metrics available"}
714
+
715
+ optimizations_applied = self._apply_all_optimizations(latest_metrics, strategy)
716
+
717
+ return self._build_optimization_result(strategy, optimizations_applied)
718
+
719
+ def _get_latest_metrics(self) -> ResourceMetrics | None:
720
+ """Get the latest resource metrics."""
721
+ return self.resource_history[-1] if self.resource_history else None
722
+
723
+ def _apply_all_optimizations(
724
+ self, metrics: ResourceMetrics, strategy: str
725
+ ) -> list[str]:
726
+ """Apply all optimization strategies and collect results."""
727
+ optimizations_applied = []
728
+
729
+ # Apply different types of optimizations
730
+ optimizations_applied.extend(self._apply_memory_optimizations(metrics))
731
+ optimizations_applied.extend(
732
+ self._apply_performance_optimizations(metrics, strategy)
733
+ )
734
+ optimizations_applied.extend(self._apply_storage_optimizations())
735
+
736
+ return optimizations_applied
737
+
738
+ def _apply_memory_optimizations(self, metrics: ResourceMetrics) -> list[str]:
739
+ """Apply memory-related optimizations."""
740
+ optimizations = []
741
+
742
+ if metrics.memory_percent > 70:
743
+ if self.connection_pool.max_connections > 500:
744
+ self.connection_pool.max_connections = int(
745
+ self.connection_pool.max_connections * 0.8
746
+ )
747
+ optimizations.append("Reduced connection pool size")
748
+
749
+ return optimizations
750
+
751
+ def _apply_performance_optimizations(
752
+ self, metrics: ResourceMetrics, strategy: str
753
+ ) -> list[str]:
754
+ """Apply performance-related optimizations."""
755
+ optimizations = []
756
+
757
+ if metrics.cpu_percent > 60 and strategy in ("performance", "balanced"):
758
+ if self.performance_profile.analysis_frequency_minutes > 2:
759
+ self.performance_profile.analysis_frequency_minutes = max(
760
+ 1, self.performance_profile.analysis_frequency_minutes - 1
761
+ )
762
+ optimizations.append("Increased analysis frequency")
763
+
764
+ return optimizations
765
+
766
+ def _apply_storage_optimizations(self) -> list[str]:
767
+ """Apply storage-related optimizations."""
768
+ optimizations = []
769
+ storage_usage = self.compaction_manager.get_storage_usage()
770
+
771
+ if storage_usage["utilization_percent"] > 70:
772
+ for data_type in ("metrics_raw", "error_patterns"):
773
+ result = self.compaction_manager.compact_data(data_type)
774
+ if result["status"] == "success":
775
+ optimizations.append(f"Compacted {data_type} data")
776
+
777
+ return optimizations
778
+
779
+ @staticmethod
780
+ def _build_optimization_result(
781
+ strategy: str, optimizations_applied: list[str]
782
+ ) -> dict[str, t.Any]:
783
+ """Build the optimization result dictionary."""
784
+ return {
785
+ "status": "success",
786
+ "strategy": strategy,
787
+ "optimizations_applied": optimizations_applied,
788
+ "timestamp": datetime.now().isoformat(),
789
+ "next_optimization": (datetime.now() + timedelta(minutes=15)).isoformat(),
790
+ }
791
+
792
+ async def run_optimization_cycle(self) -> dict[str, t.Any]:
793
+ """Run a complete optimization cycle."""
794
+ try:
795
+ # Collect metrics
796
+ metrics = self.collect_resource_metrics()
797
+
798
+ # Analyze scaling needs
799
+ scaling_metrics = self.analyze_scaling_needs()
800
+
801
+ # Generate recommendations
802
+ recommendations = self.generate_optimization_recommendations()
803
+
804
+ # Apply automatic optimizations if needed
805
+ optimization_result = None
806
+ if (
807
+ metrics.cpu_percent > 80
808
+ or metrics.memory_percent > 85
809
+ or scaling_metrics.current_load > 0.8
810
+ ):
811
+ optimization_result = self.optimize_configuration()
812
+
813
+ return {
814
+ "status": "success",
815
+ "metrics": metrics.to_dict(),
816
+ "scaling_analysis": scaling_metrics.to_dict(),
817
+ "recommendations": [rec.to_dict() for rec in recommendations],
818
+ "automatic_optimization": optimization_result,
819
+ "connection_pool_stats": self.connection_pool.get_stats(),
820
+ "storage_usage": self.compaction_manager.get_storage_usage(),
821
+ "timestamp": datetime.now().isoformat(),
822
+ }
823
+
824
+ except Exception as e:
825
+ logger.error(f"Optimization cycle failed: {e}")
826
+ return {
827
+ "status": "error",
828
+ "message": str(e),
829
+ "timestamp": datetime.now().isoformat(),
830
+ }
831
+
832
+ def get_advanced_status(self) -> dict[str, t.Any]:
833
+ """Get comprehensive advanced monitoring status."""
834
+ return {
835
+ "performance_profile": self.performance_profile.to_dict(),
836
+ "resource_metrics": self.resource_history[-1].to_dict()
837
+ if self.resource_history
838
+ else None,
839
+ "scaling_metrics": self.analyze_scaling_needs().to_dict(),
840
+ "active_recommendations": [
841
+ rec.to_dict() for rec in self.optimization_recommendations
842
+ ],
843
+ "connection_pool": self.connection_pool.get_stats(),
844
+ "storage_usage": self.compaction_manager.get_storage_usage(),
845
+ "optimization_history": {
846
+ "last_optimization": self.last_optimization.isoformat(),
847
+ "total_optimizations": len(self.optimization_recommendations),
848
+ },
849
+ "health_score": self._calculate_health_score(),
850
+ }
851
+
852
+ def _calculate_health_score(self) -> float:
853
+ """Calculate overall system health score (0.0 to 100.0)."""
854
+ if not self.resource_history:
855
+ return 50.0 # Unknown, assume average
856
+
857
+ latest = self.resource_history[-1]
858
+ storage = self.compaction_manager.get_storage_usage()
859
+
860
+ # Individual component scores
861
+ cpu_score = max(0, 100 - latest.cpu_percent)
862
+ memory_score = max(0, 100 - latest.memory_percent)
863
+ storage_score = max(0, 100 - storage["utilization_percent"])
864
+
865
+ # Connection efficiency
866
+ pool_stats = self.connection_pool.get_stats()
867
+ connection_score = max(0, 100 - pool_stats["utilization_percent"])
868
+
869
+ # Weighted average
870
+ health_score = (
871
+ cpu_score * 0.3
872
+ + memory_score * 0.3
873
+ + storage_score * 0.2
874
+ + connection_score * 0.2
875
+ )
876
+
877
+ result: float = round(health_score, 1)
878
+ return result