moai-adk 0.25.4__py3-none-any.whl → 0.32.8__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.

Potentially problematic release.


This version of moai-adk might be problematic. Click here for more details.

Files changed (378) hide show
  1. moai_adk/__init__.py +2 -5
  2. moai_adk/__main__.py +114 -82
  3. moai_adk/cli/__init__.py +6 -1
  4. moai_adk/cli/commands/__init__.py +1 -3
  5. moai_adk/cli/commands/analyze.py +5 -16
  6. moai_adk/cli/commands/doctor.py +6 -18
  7. moai_adk/cli/commands/init.py +56 -125
  8. moai_adk/cli/commands/language.py +14 -35
  9. moai_adk/cli/commands/status.py +9 -15
  10. moai_adk/cli/commands/update.py +1555 -190
  11. moai_adk/cli/prompts/init_prompts.py +112 -56
  12. moai_adk/cli/spec_status.py +263 -0
  13. moai_adk/cli/ui/__init__.py +44 -0
  14. moai_adk/cli/ui/progress.py +422 -0
  15. moai_adk/cli/ui/prompts.py +389 -0
  16. moai_adk/cli/ui/theme.py +129 -0
  17. moai_adk/cli/worktree/__init__.py +27 -0
  18. moai_adk/cli/worktree/__main__.py +31 -0
  19. moai_adk/cli/worktree/cli.py +672 -0
  20. moai_adk/cli/worktree/exceptions.py +89 -0
  21. moai_adk/cli/worktree/manager.py +490 -0
  22. moai_adk/cli/worktree/models.py +65 -0
  23. moai_adk/cli/worktree/registry.py +128 -0
  24. moai_adk/core/PHASE2_OPTIMIZATIONS.md +467 -0
  25. moai_adk/core/analysis/session_analyzer.py +17 -56
  26. moai_adk/core/claude_integration.py +26 -54
  27. moai_adk/core/command_helpers.py +10 -10
  28. moai_adk/core/comprehensive_monitoring_system.py +1183 -0
  29. moai_adk/core/config/auto_spec_config.py +5 -11
  30. moai_adk/core/config/migration.py +19 -9
  31. moai_adk/core/config/unified.py +436 -0
  32. moai_adk/core/context_manager.py +6 -12
  33. moai_adk/core/enterprise_features.py +1404 -0
  34. moai_adk/core/error_recovery_system.py +725 -112
  35. moai_adk/core/event_driven_hook_system.py +1371 -0
  36. moai_adk/core/git/__init__.py +8 -0
  37. moai_adk/core/git/branch_manager.py +3 -11
  38. moai_adk/core/git/checkpoint.py +1 -3
  39. moai_adk/core/git/conflict_detector.py +413 -0
  40. moai_adk/core/git/manager.py +91 -1
  41. moai_adk/core/hooks/post_tool_auto_spec_completion.py +56 -80
  42. moai_adk/core/input_validation_middleware.py +1006 -0
  43. moai_adk/core/integration/engine.py +6 -18
  44. moai_adk/core/integration/integration_tester.py +10 -9
  45. moai_adk/core/integration/utils.py +1 -1
  46. moai_adk/core/issue_creator.py +10 -28
  47. moai_adk/core/jit_context_loader.py +956 -0
  48. moai_adk/core/jit_enhanced_hook_manager.py +1987 -0
  49. moai_adk/core/language_config_resolver.py +485 -0
  50. moai_adk/core/language_validator.py +28 -41
  51. moai_adk/core/mcp/setup.py +15 -12
  52. moai_adk/core/merge/__init__.py +9 -0
  53. moai_adk/core/merge/analyzer.py +481 -0
  54. moai_adk/core/migration/alfred_to_moai_migrator.py +383 -0
  55. moai_adk/core/migration/backup_manager.py +78 -9
  56. moai_adk/core/migration/custom_element_scanner.py +358 -0
  57. moai_adk/core/migration/file_migrator.py +8 -17
  58. moai_adk/core/migration/interactive_checkbox_ui.py +488 -0
  59. moai_adk/core/migration/selective_restorer.py +470 -0
  60. moai_adk/core/migration/template_utils.py +74 -0
  61. moai_adk/core/migration/user_selection_ui.py +338 -0
  62. moai_adk/core/migration/version_detector.py +6 -10
  63. moai_adk/core/migration/version_migrator.py +3 -3
  64. moai_adk/core/performance/cache_system.py +8 -10
  65. moai_adk/core/phase_optimized_hook_scheduler.py +879 -0
  66. moai_adk/core/project/checker.py +2 -4
  67. moai_adk/core/project/detector.py +1 -3
  68. moai_adk/core/project/initializer.py +135 -23
  69. moai_adk/core/project/phase_executor.py +54 -81
  70. moai_adk/core/project/validator.py +6 -12
  71. moai_adk/core/quality/trust_checker.py +9 -27
  72. moai_adk/core/realtime_monitoring_dashboard.py +1724 -0
  73. moai_adk/core/robust_json_parser.py +611 -0
  74. moai_adk/core/rollback_manager.py +73 -148
  75. moai_adk/core/session_manager.py +10 -26
  76. moai_adk/core/skill_loading_system.py +579 -0
  77. moai_adk/core/spec/confidence_scoring.py +31 -100
  78. moai_adk/core/spec/ears_template_engine.py +351 -286
  79. moai_adk/core/spec/quality_validator.py +35 -69
  80. moai_adk/core/spec_status_manager.py +64 -74
  81. moai_adk/core/template/backup.py +45 -20
  82. moai_adk/core/template/config.py +112 -39
  83. moai_adk/core/template/merger.py +11 -19
  84. moai_adk/core/template/processor.py +253 -149
  85. moai_adk/core/template_engine.py +73 -40
  86. moai_adk/core/template_variable_synchronizer.py +417 -0
  87. moai_adk/core/unified_permission_manager.py +745 -0
  88. moai_adk/core/user_behavior_analytics.py +851 -0
  89. moai_adk/core/version_sync.py +429 -0
  90. moai_adk/foundation/__init__.py +56 -0
  91. moai_adk/foundation/backend.py +1027 -0
  92. moai_adk/foundation/database.py +1115 -0
  93. moai_adk/foundation/devops.py +1585 -0
  94. moai_adk/foundation/ears.py +431 -0
  95. moai_adk/foundation/frontend.py +870 -0
  96. moai_adk/foundation/git/commit_templates.py +4 -12
  97. moai_adk/foundation/git.py +376 -0
  98. moai_adk/foundation/langs.py +484 -0
  99. moai_adk/foundation/ml_ops.py +1162 -0
  100. moai_adk/foundation/testing.py +1524 -0
  101. moai_adk/foundation/trust/trust_principles.py +23 -72
  102. moai_adk/foundation/trust/validation_checklist.py +57 -162
  103. moai_adk/project/__init__.py +0 -0
  104. moai_adk/project/configuration.py +1084 -0
  105. moai_adk/project/documentation.py +566 -0
  106. moai_adk/project/schema.py +447 -0
  107. moai_adk/statusline/alfred_detector.py +1 -3
  108. moai_adk/statusline/config.py +13 -4
  109. moai_adk/statusline/enhanced_output_style_detector.py +23 -15
  110. moai_adk/statusline/main.py +51 -15
  111. moai_adk/statusline/renderer.py +104 -48
  112. moai_adk/statusline/update_checker.py +3 -9
  113. moai_adk/statusline/version_reader.py +140 -46
  114. moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +549 -0
  115. moai_adk/templates/.claude/agents/moai/builder-agent.md +445 -0
  116. moai_adk/templates/.claude/agents/moai/builder-command.md +1132 -0
  117. moai_adk/templates/.claude/agents/moai/builder-skill.md +601 -0
  118. moai_adk/templates/.claude/agents/moai/expert-backend.md +831 -0
  119. moai_adk/templates/.claude/agents/moai/expert-database.md +774 -0
  120. moai_adk/templates/.claude/agents/moai/expert-debug.md +396 -0
  121. moai_adk/templates/.claude/agents/moai/expert-devops.md +711 -0
  122. moai_adk/templates/.claude/agents/moai/expert-frontend.md +666 -0
  123. moai_adk/templates/.claude/agents/moai/expert-security.md +474 -0
  124. moai_adk/templates/.claude/agents/moai/expert-uiux.md +1038 -0
  125. moai_adk/templates/.claude/agents/moai/manager-claude-code.md +429 -0
  126. moai_adk/templates/.claude/agents/moai/manager-docs.md +570 -0
  127. moai_adk/templates/.claude/agents/moai/manager-git.md +937 -0
  128. moai_adk/templates/.claude/agents/moai/manager-project.md +891 -0
  129. moai_adk/templates/.claude/agents/moai/manager-quality.md +598 -0
  130. moai_adk/templates/.claude/agents/moai/manager-spec.md +713 -0
  131. moai_adk/templates/.claude/agents/moai/manager-strategy.md +600 -0
  132. moai_adk/templates/.claude/agents/moai/manager-tdd.md +603 -0
  133. moai_adk/templates/.claude/agents/moai/mcp-context7.md +369 -0
  134. moai_adk/templates/.claude/agents/moai/mcp-figma.md +1567 -0
  135. moai_adk/templates/.claude/agents/moai/mcp-notion.md +749 -0
  136. moai_adk/templates/.claude/agents/moai/mcp-playwright.md +427 -0
  137. moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +994 -0
  138. moai_adk/templates/.claude/commands/moai/0-project.md +1143 -0
  139. moai_adk/templates/.claude/commands/moai/1-plan.md +1435 -0
  140. moai_adk/templates/.claude/commands/moai/2-run.md +883 -0
  141. moai_adk/templates/.claude/commands/moai/3-sync.md +993 -0
  142. moai_adk/templates/.claude/commands/moai/9-feedback.md +314 -0
  143. moai_adk/templates/.claude/hooks/__init__.py +8 -0
  144. moai_adk/templates/.claude/hooks/moai/__init__.py +8 -0
  145. moai_adk/templates/.claude/hooks/moai/lib/__init__.py +85 -0
  146. moai_adk/templates/.claude/hooks/moai/lib/checkpoint.py +244 -0
  147. moai_adk/templates/.claude/hooks/moai/lib/common.py +131 -0
  148. moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +446 -0
  149. moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +639 -0
  150. moai_adk/templates/.claude/hooks/moai/lib/example_config.json +104 -0
  151. moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +590 -0
  152. moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +317 -0
  153. moai_adk/templates/.claude/hooks/moai/lib/models.py +102 -0
  154. moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +28 -0
  155. moai_adk/templates/.claude/hooks/moai/lib/project.py +768 -0
  156. moai_adk/templates/.claude/hooks/moai/lib/test_hooks_improvements.py +443 -0
  157. moai_adk/templates/.claude/hooks/moai/lib/timeout.py +160 -0
  158. moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +530 -0
  159. moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +862 -0
  160. moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +921 -0
  161. moai_adk/templates/.claude/output-styles/moai/r2d2.md +380 -0
  162. moai_adk/templates/.claude/output-styles/moai/yoda.md +338 -0
  163. moai_adk/templates/.claude/settings.json +172 -0
  164. moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +247 -0
  165. moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +44 -0
  166. moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +130 -0
  167. moai_adk/templates/.claude/skills/moai-docs-generation/modules/code-documentation.md +152 -0
  168. moai_adk/templates/.claude/skills/moai-docs-generation/modules/multi-format-output.md +178 -0
  169. moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +147 -0
  170. moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +319 -0
  171. moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +320 -0
  172. moai_adk/templates/.claude/skills/moai-domain-database/modules/README.md +53 -0
  173. moai_adk/templates/.claude/skills/moai-domain-database/modules/mongodb.md +231 -0
  174. moai_adk/templates/.claude/skills/moai-domain-database/modules/postgresql.md +169 -0
  175. moai_adk/templates/.claude/skills/moai-domain-database/modules/redis.md +262 -0
  176. moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +496 -0
  177. moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +453 -0
  178. moai_adk/templates/.claude/skills/moai-domain-uiux/examples.md +560 -0
  179. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/accessibility-wcag.md +260 -0
  180. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/component-architecture.md +228 -0
  181. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/design-system-tokens.md +405 -0
  182. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/icon-libraries.md +401 -0
  183. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/theming-system.md +373 -0
  184. moai_adk/templates/.claude/skills/moai-domain-uiux/reference.md +243 -0
  185. moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +491 -0
  186. moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +98 -0
  187. moai_adk/templates/.claude/skills/moai-formats-data/modules/SKILL-MODULARIZATION-TEMPLATE.md +278 -0
  188. moai_adk/templates/.claude/skills/moai-formats-data/modules/caching-performance.md +459 -0
  189. moai_adk/templates/.claude/skills/moai-formats-data/modules/data-validation.md +485 -0
  190. moai_adk/templates/.claude/skills/moai-formats-data/modules/json-optimization.md +374 -0
  191. moai_adk/templates/.claude/skills/moai-formats-data/modules/toon-encoding.md +308 -0
  192. moai_adk/templates/.claude/skills/moai-foundation-claude/SKILL.md +201 -0
  193. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/best-practices-checklist.md +616 -0
  194. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +729 -0
  195. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +560 -0
  196. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-iam-official.md +635 -0
  197. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-memory-official.md +543 -0
  198. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-settings-official.md +663 -0
  199. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-skills-official.md +113 -0
  200. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +238 -0
  201. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/complete-configuration-guide.md +175 -0
  202. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-examples.md +1674 -0
  203. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-formatting-guide.md +729 -0
  204. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-examples.md +1513 -0
  205. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-formatting-guide.md +1086 -0
  206. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-integration-patterns.md +1100 -0
  207. moai_adk/templates/.claude/skills/moai-foundation-context/SKILL.md +438 -0
  208. moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +515 -0
  209. moai_adk/templates/.claude/skills/moai-foundation-core/modules/README.md +296 -0
  210. moai_adk/templates/.claude/skills/moai-foundation-core/modules/agents-reference.md +346 -0
  211. moai_adk/templates/.claude/skills/moai-foundation-core/modules/commands-reference.md +432 -0
  212. moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +757 -0
  213. moai_adk/templates/.claude/skills/moai-foundation-core/modules/execution-rules.md +687 -0
  214. moai_adk/templates/.claude/skills/moai-foundation-core/modules/modular-system.md +665 -0
  215. moai_adk/templates/.claude/skills/moai-foundation-core/modules/progressive-disclosure.md +649 -0
  216. moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +864 -0
  217. moai_adk/templates/.claude/skills/moai-foundation-core/modules/token-optimization.md +708 -0
  218. moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-framework.md +981 -0
  219. moai_adk/templates/.claude/skills/moai-foundation-quality/SKILL.md +362 -0
  220. moai_adk/templates/.claude/skills/moai-foundation-quality/examples.md +1232 -0
  221. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/best-practices.md +261 -0
  222. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/integration-patterns.md +194 -0
  223. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/proactive-analysis.md +229 -0
  224. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/trust5-validation.md +169 -0
  225. moai_adk/templates/.claude/skills/moai-foundation-quality/reference.md +1266 -0
  226. moai_adk/templates/.claude/skills/moai-foundation-quality/scripts/quality-gate.sh +668 -0
  227. moai_adk/templates/.claude/skills/moai-foundation-quality/templates/github-actions-quality.yml +481 -0
  228. moai_adk/templates/.claude/skills/moai-foundation-quality/templates/quality-config.yaml +519 -0
  229. moai_adk/templates/.claude/skills/moai-integration-mcp/SKILL.md +352 -0
  230. moai_adk/templates/.claude/skills/moai-integration-mcp/modules/README.md +52 -0
  231. moai_adk/templates/.claude/skills/moai-integration-mcp/modules/error-handling.md +334 -0
  232. moai_adk/templates/.claude/skills/moai-integration-mcp/modules/integration-patterns.md +310 -0
  233. moai_adk/templates/.claude/skills/moai-integration-mcp/modules/security-authentication.md +256 -0
  234. moai_adk/templates/.claude/skills/moai-integration-mcp/modules/server-architecture.md +253 -0
  235. moai_adk/templates/.claude/skills/moai-lang-unified/README.md +133 -0
  236. moai_adk/templates/.claude/skills/moai-lang-unified/SKILL.md +296 -0
  237. moai_adk/templates/.claude/skills/moai-lang-unified/examples.md +1269 -0
  238. moai_adk/templates/.claude/skills/moai-lang-unified/reference.md +331 -0
  239. moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +298 -0
  240. moai_adk/templates/.claude/skills/moai-library-mermaid/advanced-patterns.md +465 -0
  241. moai_adk/templates/.claude/skills/moai-library-mermaid/examples.md +270 -0
  242. moai_adk/templates/.claude/skills/moai-library-mermaid/optimization.md +440 -0
  243. moai_adk/templates/.claude/skills/moai-library-mermaid/reference.md +228 -0
  244. moai_adk/templates/.claude/skills/moai-library-nextra/SKILL.md +316 -0
  245. moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +336 -0
  246. moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-deployment-patterns.md +182 -0
  247. moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-patterns.md +17 -0
  248. moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +57 -0
  249. moai_adk/templates/.claude/skills/moai-library-nextra/modules/content-architecture-optimization.md +162 -0
  250. moai_adk/templates/.claude/skills/moai-library-nextra/modules/deployment.md +52 -0
  251. moai_adk/templates/.claude/skills/moai-library-nextra/modules/framework-core-configuration.md +186 -0
  252. moai_adk/templates/.claude/skills/moai-library-nextra/modules/i18n-setup.md +55 -0
  253. moai_adk/templates/.claude/skills/moai-library-nextra/modules/mdx-components.md +52 -0
  254. moai_adk/templates/.claude/skills/moai-library-nextra/optimization.md +303 -0
  255. moai_adk/templates/.claude/skills/moai-library-shadcn/SKILL.md +370 -0
  256. moai_adk/templates/.claude/skills/moai-library-shadcn/examples.md +575 -0
  257. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/advanced-patterns.md +394 -0
  258. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/optimization.md +278 -0
  259. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-components.md +457 -0
  260. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-theming.md +373 -0
  261. moai_adk/templates/.claude/skills/moai-library-shadcn/reference.md +74 -0
  262. moai_adk/templates/.claude/skills/moai-platform-baas/README.md +186 -0
  263. moai_adk/templates/.claude/skills/moai-platform-baas/SKILL.md +290 -0
  264. moai_adk/templates/.claude/skills/moai-platform-baas/examples.md +1225 -0
  265. moai_adk/templates/.claude/skills/moai-platform-baas/reference.md +567 -0
  266. moai_adk/templates/.claude/skills/moai-platform-baas/scripts/provider-selector.py +323 -0
  267. moai_adk/templates/.claude/skills/moai-platform-baas/templates/stack-config.yaml +204 -0
  268. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +446 -0
  269. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/advanced-patterns.md +379 -0
  270. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/optimization.md +286 -0
  271. moai_adk/templates/.claude/skills/moai-workflow-project/README.md +190 -0
  272. moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +387 -0
  273. moai_adk/templates/.claude/skills/moai-workflow-project/__init__.py +520 -0
  274. moai_adk/templates/.claude/skills/moai-workflow-project/complete_workflow_demo_fixed.py +574 -0
  275. moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_project_setup.py +317 -0
  276. moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_workflow_demo.py +663 -0
  277. moai_adk/templates/.claude/skills/moai-workflow-project/examples/config-migration-example.json +190 -0
  278. moai_adk/templates/.claude/skills/moai-workflow-project/examples/question-examples.json +135 -0
  279. moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +196 -0
  280. moai_adk/templates/.claude/skills/moai-workflow-project/modules/__init__.py +17 -0
  281. moai_adk/templates/.claude/skills/moai-workflow-project/modules/advanced-patterns.md +158 -0
  282. moai_adk/templates/.claude/skills/moai-workflow-project/modules/ask_user_integration.py +340 -0
  283. moai_adk/templates/.claude/skills/moai-workflow-project/modules/batch_questions.py +713 -0
  284. moai_adk/templates/.claude/skills/moai-workflow-project/modules/config_manager.py +538 -0
  285. moai_adk/templates/.claude/skills/moai-workflow-project/modules/documentation_manager.py +1336 -0
  286. moai_adk/templates/.claude/skills/moai-workflow-project/modules/language_initializer.py +730 -0
  287. moai_adk/templates/.claude/skills/moai-workflow-project/modules/migration_manager.py +608 -0
  288. moai_adk/templates/.claude/skills/moai-workflow-project/modules/template_optimizer.py +1005 -0
  289. moai_adk/templates/.claude/skills/moai-workflow-project/schemas/config-schema.json +316 -0
  290. moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +1362 -0
  291. moai_adk/templates/.claude/skills/moai-workflow-project/templates/config-template.json +71 -0
  292. moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/product-template.md +44 -0
  293. moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/structure-template.md +48 -0
  294. moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/tech-template.md +71 -0
  295. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/config-manager-setup.json +109 -0
  296. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/language-initializer.json +228 -0
  297. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/menu-project-config.json +130 -0
  298. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/project-batch-questions.json +97 -0
  299. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/spec-workflow-setup.json +150 -0
  300. moai_adk/templates/.claude/skills/moai-workflow-project/test_integration_simple.py +436 -0
  301. moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +374 -0
  302. moai_adk/templates/.claude/skills/moai-workflow-templates/modules/code-templates.md +124 -0
  303. moai_adk/templates/.claude/skills/moai-workflow-templates/modules/feedback-templates.md +100 -0
  304. moai_adk/templates/.claude/skills/moai-workflow-templates/modules/template-optimizer.md +138 -0
  305. moai_adk/templates/.claude/skills/moai-workflow-testing/LICENSE.txt +202 -0
  306. moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +453 -0
  307. moai_adk/templates/.claude/skills/moai-workflow-testing/advanced-patterns.md +576 -0
  308. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/ai-powered-testing.py +294 -0
  309. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/console_logging.py +35 -0
  310. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/element_discovery.py +40 -0
  311. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/static_html_automation.py +34 -0
  312. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/README.md +220 -0
  313. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +845 -0
  314. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +1416 -0
  315. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +1234 -0
  316. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +1243 -0
  317. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +1260 -0
  318. moai_adk/templates/.claude/skills/moai-workflow-testing/optimization.md +505 -0
  319. moai_adk/templates/.claude/skills/moai-workflow-testing/reference/playwright-best-practices.md +57 -0
  320. moai_adk/templates/.claude/skills/moai-workflow-testing/scripts/with_server.py +218 -0
  321. moai_adk/templates/.claude/skills/moai-workflow-testing/templates/alfred-integration.md +376 -0
  322. moai_adk/templates/.claude/skills/moai-workflow-testing/workflows/enterprise-testing-workflow.py +571 -0
  323. moai_adk/templates/.claude/skills/moai-worktree/SKILL.md +410 -0
  324. moai_adk/templates/.claude/skills/moai-worktree/examples.md +606 -0
  325. moai_adk/templates/.claude/skills/moai-worktree/modules/integration-patterns.md +982 -0
  326. moai_adk/templates/.claude/skills/moai-worktree/modules/parallel-development.md +778 -0
  327. moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-commands.md +646 -0
  328. moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-management.md +782 -0
  329. moai_adk/templates/.claude/skills/moai-worktree/reference.md +357 -0
  330. moai_adk/templates/.git-hooks/pre-commit +103 -41
  331. moai_adk/templates/.git-hooks/pre-push +116 -21
  332. moai_adk/templates/.github/workflows/ci-universal.yml +513 -0
  333. moai_adk/templates/.github/workflows/security-secrets-check.yml +179 -0
  334. moai_adk/templates/.gitignore +184 -44
  335. moai_adk/templates/.mcp.json +7 -9
  336. moai_adk/templates/.moai/cache/personalization.json +10 -0
  337. moai_adk/templates/.moai/config/config.yaml +344 -0
  338. moai_adk/templates/.moai/config/presets/manual.yaml +28 -0
  339. moai_adk/templates/.moai/config/presets/personal.yaml +30 -0
  340. moai_adk/templates/.moai/config/presets/team.yaml +33 -0
  341. moai_adk/templates/.moai/config/questions/_schema.yaml +79 -0
  342. moai_adk/templates/.moai/config/questions/tab1-user.yaml +108 -0
  343. moai_adk/templates/.moai/config/questions/tab2-project.yaml +122 -0
  344. moai_adk/templates/.moai/config/questions/tab3-git.yaml +542 -0
  345. moai_adk/templates/.moai/config/questions/tab4-quality.yaml +167 -0
  346. moai_adk/templates/.moai/config/questions/tab5-system.yaml +152 -0
  347. moai_adk/templates/.moai/config/sections/git-strategy.yaml +40 -0
  348. moai_adk/templates/.moai/config/sections/language.yaml +11 -0
  349. moai_adk/templates/.moai/config/sections/project.yaml +13 -0
  350. moai_adk/templates/.moai/config/sections/quality.yaml +15 -0
  351. moai_adk/templates/.moai/config/sections/system.yaml +14 -0
  352. moai_adk/templates/.moai/config/sections/user.yaml +5 -0
  353. moai_adk/templates/.moai/config/statusline-config.yaml +86 -0
  354. moai_adk/templates/.moai/scripts/setup-glm.py +136 -0
  355. moai_adk/templates/CLAUDE.md +382 -501
  356. moai_adk/utils/__init__.py +24 -1
  357. moai_adk/utils/banner.py +7 -10
  358. moai_adk/utils/common.py +16 -30
  359. moai_adk/utils/link_validator.py +4 -12
  360. moai_adk/utils/safe_file_reader.py +2 -6
  361. moai_adk/utils/timeout.py +160 -0
  362. moai_adk/utils/toon_utils.py +256 -0
  363. moai_adk/version.py +22 -0
  364. moai_adk-0.32.8.dist-info/METADATA +2478 -0
  365. moai_adk-0.32.8.dist-info/RECORD +396 -0
  366. {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/WHEEL +1 -1
  367. {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/entry_points.txt +1 -0
  368. moai_adk/cli/commands/backup.py +0 -82
  369. moai_adk/cli/commands/improve_user_experience.py +0 -348
  370. moai_adk/cli/commands/migrate.py +0 -158
  371. moai_adk/cli/commands/validate_links.py +0 -118
  372. moai_adk/templates/.github/workflows/moai-gitflow.yml +0 -413
  373. moai_adk/templates/.github/workflows/moai-release-create.yml +0 -100
  374. moai_adk/templates/.github/workflows/moai-release-pipeline.yml +0 -188
  375. moai_adk/utils/user_experience.py +0 -531
  376. moai_adk-0.25.4.dist-info/METADATA +0 -2279
  377. moai_adk-0.25.4.dist-info/RECORD +0 -112
  378. {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,1183 @@
1
+ """
2
+ Comprehensive Monitoring System
3
+
4
+ Real-time monitoring, analytics, and predictive analysis for MoAI-ADK
5
+ with automated alerting and optimization capabilities.
6
+
7
+ Key Features:
8
+ - Real-time metrics collection and analysis
9
+ - User behavior analytics and pattern recognition
10
+ - Predictive analytics and trend analysis
11
+ - Automated alerting system
12
+ - System health monitoring
13
+ - Performance optimization recommendations
14
+ - Real-time dashboard interface
15
+ """
16
+
17
+ import json
18
+ import logging
19
+ import statistics
20
+ import threading
21
+ import time
22
+ from collections import defaultdict, deque
23
+ from dataclasses import dataclass, field
24
+ from datetime import datetime, timedelta
25
+ from enum import Enum
26
+ from pathlib import Path
27
+ from typing import Any, Callable, Dict, List, Optional, Union
28
+
29
+ import psutil
30
+
31
+ # Set up logging
32
+ logging.basicConfig(level=logging.INFO)
33
+ logger = logging.getLogger(__name__)
34
+
35
+
36
+ class MetricType(Enum):
37
+ """Types of metrics collected by the monitoring system"""
38
+
39
+ SYSTEM_PERFORMANCE = "system_performance"
40
+ USER_BEHAVIOR = "user_behavior"
41
+ TOKEN_USAGE = "token_usage"
42
+ ERROR_RATE = "error_rate"
43
+ RESPONSE_TIME = "response_time"
44
+ MEMORY_USAGE = "memory_usage"
45
+ CPU_USAGE = "cpu_usage"
46
+ THROUGHPUT = "throughput"
47
+ AVAILABILITY = "availability"
48
+
49
+
50
+ class AlertSeverity(Enum):
51
+ """Alert severity levels"""
52
+
53
+ LOW = 1
54
+ MEDIUM = 2
55
+ HIGH = 3
56
+ CRITICAL = 4
57
+ EMERGENCY = 5
58
+
59
+
60
+ class HealthStatus(Enum):
61
+ """System health status"""
62
+
63
+ HEALTHY = "healthy"
64
+ WARNING = "warning"
65
+ DEGRADED = "degraded"
66
+ CRITICAL = "critical"
67
+ DOWN = "down"
68
+
69
+
70
+ @dataclass
71
+ class MetricData:
72
+ """Single metric data point"""
73
+
74
+ timestamp: datetime
75
+ metric_type: MetricType
76
+ value: Union[int, float, str, bool]
77
+ tags: Dict[str, str] = field(default_factory=dict)
78
+ source: str = ""
79
+ metadata: Dict[str, Any] = field(default_factory=dict)
80
+
81
+ def to_dict(self) -> Dict[str, Any]:
82
+ """Convert to dictionary for serialization"""
83
+ return {
84
+ "timestamp": self.timestamp.isoformat(),
85
+ "metric_type": self.metric_type.value,
86
+ "value": self.value,
87
+ "tags": self.tags,
88
+ "source": self.source,
89
+ "metadata": self.metadata,
90
+ }
91
+
92
+
93
+ @dataclass
94
+ class Alert:
95
+ """Alert definition and data"""
96
+
97
+ alert_id: str
98
+ severity: AlertSeverity
99
+ title: str
100
+ description: str
101
+ timestamp: datetime
102
+ metric_type: MetricType
103
+ threshold: float
104
+ current_value: float
105
+ source: str
106
+ tags: Dict[str, str] = field(default_factory=dict)
107
+ resolved: bool = False
108
+ resolved_at: Optional[datetime] = None
109
+ acknowledged: bool = False
110
+ acknowledged_at: Optional[datetime] = None
111
+
112
+ def to_dict(self) -> Dict[str, Any]:
113
+ """Convert to dictionary for serialization"""
114
+ return {
115
+ "alert_id": self.alert_id,
116
+ "severity": self.severity.value,
117
+ "title": self.title,
118
+ "description": self.description,
119
+ "timestamp": self.timestamp.isoformat(),
120
+ "metric_type": self.metric_type.value,
121
+ "threshold": self.threshold,
122
+ "current_value": self.current_value,
123
+ "source": self.source,
124
+ "tags": self.tags,
125
+ "resolved": self.resolved,
126
+ "resolved_at": self.resolved_at.isoformat() if self.resolved_at else None,
127
+ "acknowledged": self.acknowledged,
128
+ "acknowledged_at": (self.acknowledged_at.isoformat() if self.acknowledged_at else None),
129
+ }
130
+
131
+
132
+ @dataclass
133
+ class SystemHealth:
134
+ """System health status information"""
135
+
136
+ status: HealthStatus
137
+ timestamp: datetime
138
+ overall_score: float # 0-100
139
+ component_scores: Dict[str, float] = field(default_factory=dict)
140
+ active_alerts: List[str] = field(default_factory=list)
141
+ recent_metrics: Dict[str, float] = field(default_factory=dict)
142
+ uptime_percentage: float = 100.0
143
+ last_check: Optional[datetime] = None
144
+
145
+ def to_dict(self) -> Dict[str, Any]:
146
+ """Convert to dictionary for serialization"""
147
+ return {
148
+ "status": self.status.value,
149
+ "timestamp": self.timestamp.isoformat(),
150
+ "overall_score": self.overall_score,
151
+ "component_scores": self.component_scores,
152
+ "active_alerts": self.active_alerts,
153
+ "recent_metrics": self.recent_metrics,
154
+ "uptime_percentage": self.uptime_percentage,
155
+ "last_check": self.last_check.isoformat() if self.last_check else None,
156
+ }
157
+
158
+
159
+ class MetricsCollector:
160
+ """Collects and manages system metrics"""
161
+
162
+ def __init__(self, buffer_size: int = 10000, retention_hours: int = 24):
163
+ self.buffer_size = buffer_size
164
+ self.retention_hours = retention_hours
165
+ self.metrics_buffer: Dict[MetricType, deque] = defaultdict(lambda: deque(maxlen=buffer_size))
166
+ self.aggregated_metrics: Dict[MetricType, Dict[str, Any]] = defaultdict(dict)
167
+ self._lock = threading.Lock()
168
+ self._last_cleanup = datetime.now()
169
+
170
+ def add_metric(self, metric: MetricData) -> None:
171
+ """Add a metric to the collection"""
172
+ with self._lock:
173
+ self.metrics_buffer[metric.metric_type].append(metric)
174
+ self._update_aggregated_metrics(metric)
175
+ self._cleanup_old_metrics()
176
+
177
+ def _update_aggregated_metrics(self, metric: MetricData) -> None:
178
+ """Update aggregated statistics for a metric type"""
179
+ if metric.metric_type not in self.aggregated_metrics:
180
+ self.aggregated_metrics[metric.metric_type] = {
181
+ "count": 0,
182
+ "sum": 0,
183
+ "min": float("inf"),
184
+ "max": float("-inf"),
185
+ "values": [],
186
+ }
187
+
188
+ agg = self.aggregated_metrics[metric.metric_type]
189
+
190
+ if isinstance(metric.value, (int, float)):
191
+ agg["count"] += 1
192
+ agg["sum"] += metric.value
193
+ agg["min"] = min(agg["min"], metric.value)
194
+ agg["max"] = max(agg["max"], metric.value)
195
+ agg["values"].append(metric.value)
196
+
197
+ # Keep only recent values for statistics
198
+ if len(agg["values"]) > 1000:
199
+ agg["values"] = agg["values"][-1000:]
200
+
201
+ def _cleanup_old_metrics(self) -> None:
202
+ """Remove metrics older than retention period"""
203
+ now = datetime.now()
204
+ if (now - self._last_cleanup).seconds < 300: # Cleanup every 5 minutes
205
+ return
206
+
207
+ cutoff_time = now - timedelta(hours=self.retention_hours)
208
+
209
+ for metric_type in self.metrics_buffer:
210
+ while self.metrics_buffer[metric_type] and self.metrics_buffer[metric_type][0].timestamp < cutoff_time:
211
+ self.metrics_buffer[metric_type].popleft()
212
+
213
+ self._last_cleanup = now
214
+
215
+ def get_metrics(
216
+ self,
217
+ metric_type: Optional[MetricType] = None,
218
+ start_time: Optional[datetime] = None,
219
+ end_time: Optional[datetime] = None,
220
+ limit: Optional[int] = None,
221
+ ) -> List[MetricData]:
222
+ """Get metrics with optional filtering"""
223
+ with self._lock:
224
+ if metric_type:
225
+ metrics = list(self.metrics_buffer[metric_type])
226
+ else:
227
+ metrics = []
228
+ for mlist in self.metrics_buffer.values():
229
+ metrics.extend(mlist)
230
+
231
+ # Filter by time range
232
+ if start_time:
233
+ metrics = [m for m in metrics if m.timestamp >= start_time]
234
+ if end_time:
235
+ metrics = [m for m in metrics if m.timestamp <= end_time]
236
+
237
+ # Sort by timestamp (newest first)
238
+ metrics.sort(key=lambda m: m.timestamp, reverse=True)
239
+
240
+ # Apply limit
241
+ if limit:
242
+ metrics = metrics[:limit]
243
+
244
+ return metrics
245
+
246
+ def get_statistics(self, metric_type: MetricType, minutes: int = 60) -> Dict[str, Any]:
247
+ """Get statistical summary for a metric type"""
248
+ with self._lock:
249
+ agg = self.aggregated_metrics.get(metric_type, {})
250
+
251
+ if not agg or agg["count"] == 0:
252
+ return {
253
+ "count": 0,
254
+ "average": None,
255
+ "min": None,
256
+ "max": None,
257
+ "median": None,
258
+ "std_dev": None,
259
+ }
260
+
261
+ values = agg["values"]
262
+ if not values:
263
+ return {
264
+ "count": agg["count"],
265
+ "average": agg["sum"] / agg["count"],
266
+ "min": agg["min"],
267
+ "max": agg["max"],
268
+ "median": None,
269
+ "std_dev": None,
270
+ }
271
+
272
+ try:
273
+ return {
274
+ "count": len(values),
275
+ "average": statistics.mean(values),
276
+ "median": statistics.median(values),
277
+ "min": min(values),
278
+ "max": max(values),
279
+ "std_dev": statistics.stdev(values) if len(values) > 1 else 0,
280
+ "p95": (statistics.quantiles(values, n=20)[18] if len(values) > 20 else max(values)),
281
+ "p99": (statistics.quantiles(values, n=100)[98] if len(values) > 100 else max(values)),
282
+ }
283
+ except (statistics.StatisticsError, IndexError):
284
+ return {
285
+ "count": len(values),
286
+ "average": statistics.mean(values),
287
+ "median": statistics.median(values),
288
+ "min": min(values),
289
+ "max": max(values),
290
+ "std_dev": 0,
291
+ "p95": max(values),
292
+ "p99": max(values),
293
+ }
294
+
295
+
296
+ class AlertManager:
297
+ """Manages alert rules, detection, and notification"""
298
+
299
+ def __init__(self, metrics_collector: MetricsCollector):
300
+ self.metrics_collector = metrics_collector
301
+ self.alert_rules: List[Dict[str, Any]] = []
302
+ self.active_alerts: Dict[str, Alert] = {}
303
+ self.alert_history: List[Alert] = []
304
+ self.alert_callbacks: List[Callable[[Alert], None]] = []
305
+ self._lock = threading.Lock()
306
+
307
+ def add_alert_rule(
308
+ self,
309
+ name: str,
310
+ metric_type: MetricType,
311
+ threshold: float,
312
+ operator: str = "gt", # gt, lt, eq, ne
313
+ severity: AlertSeverity = AlertSeverity.MEDIUM,
314
+ window_minutes: int = 5,
315
+ consecutive_violations: int = 1,
316
+ tags: Optional[Dict[str, str]] = None,
317
+ description: Optional[str] = None,
318
+ ) -> None:
319
+ """Add an alert rule"""
320
+ rule = {
321
+ "name": name,
322
+ "metric_type": metric_type,
323
+ "threshold": threshold,
324
+ "operator": operator,
325
+ "severity": severity,
326
+ "window_minutes": window_minutes,
327
+ "consecutive_violations": consecutive_violations,
328
+ "tags": tags or {},
329
+ "description": description or f"Alert when {metric_type.value} {operator} {threshold}",
330
+ "violation_count": 0,
331
+ "last_check": None,
332
+ "enabled": True,
333
+ }
334
+
335
+ with self._lock:
336
+ self.alert_rules.append(rule)
337
+
338
+ def check_alerts(self) -> List[Alert]:
339
+ """Check all alert rules and generate alerts for violations"""
340
+ triggered_alerts = []
341
+
342
+ with self._lock:
343
+ for rule in self.alert_rules:
344
+ if not rule["enabled"]:
345
+ continue
346
+
347
+ # Get recent metrics for this rule
348
+ recent_metrics = self.metrics_collector.get_metrics(
349
+ metric_type=rule["metric_type"],
350
+ start_time=datetime.now() - timedelta(minutes=rule["window_minutes"]),
351
+ )
352
+
353
+ if not recent_metrics:
354
+ continue
355
+
356
+ # Check for violations
357
+ violations = 0
358
+ latest_value = None
359
+
360
+ for metric in recent_metrics:
361
+ if isinstance(metric.value, (int, float)):
362
+ if self._evaluate_condition(metric.value, rule["threshold"], rule["operator"]):
363
+ violations += 1
364
+ latest_value = metric.value
365
+
366
+ # Trigger alert if threshold exceeded
367
+ if violations >= rule["consecutive_violations"]:
368
+ alert_id = f"{rule['name']}_{int(time.time())}"
369
+
370
+ alert = Alert(
371
+ alert_id=alert_id,
372
+ severity=rule["severity"],
373
+ title=f"{rule['name']} Alert Triggered",
374
+ description=rule["description"],
375
+ timestamp=datetime.now(),
376
+ metric_type=rule["metric_type"],
377
+ threshold=rule["threshold"],
378
+ current_value=latest_value or 0,
379
+ source="monitoring_system",
380
+ tags=rule["tags"],
381
+ )
382
+
383
+ self.active_alerts[alert_id] = alert
384
+ self.alert_history.append(alert)
385
+ triggered_alerts.append(alert)
386
+
387
+ # Trigger callbacks
388
+ for callback in self.alert_callbacks:
389
+ try:
390
+ callback(alert)
391
+ except Exception as e:
392
+ logger.error(f"Error in alert callback: {e}")
393
+
394
+ rule["violation_count"] = violations
395
+ rule["last_check"] = datetime.now()
396
+
397
+ # Check for resolved alerts
398
+ resolved_alerts = []
399
+ for alert_id, alert in list(self.active_alerts.items()):
400
+ # Check if alert condition is no longer met
401
+ rule = next((r for r in self.alert_rules if r["name"] in alert_id), None)
402
+ if rule:
403
+ recent_metrics = self.metrics_collector.get_metrics(
404
+ metric_type=rule["metric_type"],
405
+ start_time=datetime.now() - timedelta(minutes=1), # Check last minute
406
+ )
407
+
408
+ if recent_metrics:
409
+ latest_value = None
410
+ for metric in recent_metrics:
411
+ if isinstance(metric.value, (int, float)):
412
+ if not self._evaluate_condition(metric.value, rule["threshold"], rule["operator"]):
413
+ latest_value = metric.value
414
+ break
415
+
416
+ if latest_value is not None:
417
+ # Alert is resolved
418
+ alert.resolved = True
419
+ alert.resolved_at = datetime.now()
420
+ resolved_alerts.append(alert)
421
+ del self.active_alerts[alert_id]
422
+
423
+ return triggered_alerts
424
+
425
+ def _evaluate_condition(self, value: float, threshold: float, operator: str) -> bool:
426
+ """Evaluate alert condition"""
427
+ if operator == "gt":
428
+ return value > threshold
429
+ elif operator == "lt":
430
+ return value < threshold
431
+ elif operator == "eq":
432
+ return value == threshold
433
+ elif operator == "ne":
434
+ return value != threshold
435
+ elif operator == "gte":
436
+ return value >= threshold
437
+ elif operator == "lte":
438
+ return value <= threshold
439
+ else:
440
+ return False
441
+
442
+ def add_alert_callback(self, callback: Callable[[Alert], None]) -> None:
443
+ """Add a callback function to be triggered when alerts fire"""
444
+ self.alert_callbacks.append(callback)
445
+
446
+ def acknowledge_alert(self, alert_id: str) -> bool:
447
+ """Acknowledge an alert"""
448
+ with self._lock:
449
+ if alert_id in self.active_alerts:
450
+ self.active_alerts[alert_id].acknowledged = True
451
+ self.active_alerts[alert_id].acknowledged_at = datetime.now()
452
+ return True
453
+ return False
454
+
455
+ def get_active_alerts(self, severity: Optional[AlertSeverity] = None) -> List[Alert]:
456
+ """Get currently active alerts"""
457
+ alerts = list(self.active_alerts.values())
458
+ if severity:
459
+ alerts = [a for a in alerts if a.severity == severity]
460
+ return sorted(alerts, key=lambda a: (a.severity.value, a.timestamp), reverse=True)
461
+
462
+ def get_alert_history(self, hours: int = 24) -> List[Alert]:
463
+ """Get alert history"""
464
+ cutoff_time = datetime.now() - timedelta(hours=hours)
465
+ return [a for a in self.alert_history if a.timestamp >= cutoff_time]
466
+
467
+
468
+ class PredictiveAnalytics:
469
+ """Predictive analytics for system performance and user behavior"""
470
+
471
+ def __init__(self, metrics_collector: MetricsCollector):
472
+ self.metrics_collector = metrics_collector
473
+ self.models: Dict[str, Dict[str, Any]] = {}
474
+ self.predictions: Dict[str, Dict[str, Any]] = {}
475
+
476
+ def predict_metric_trend(
477
+ self,
478
+ metric_type: MetricType,
479
+ hours_ahead: int = 1,
480
+ confidence_threshold: float = 0.7,
481
+ ) -> Dict[str, Any]:
482
+ """Predict metric values for specified hours ahead"""
483
+ try:
484
+ # Get historical data
485
+ historical_metrics = self.metrics_collector.get_metrics(
486
+ metric_type=metric_type, start_time=datetime.now() - timedelta(hours=24)
487
+ )
488
+
489
+ if len(historical_metrics) < 10:
490
+ return {
491
+ "prediction": None,
492
+ "confidence": 0.0,
493
+ "reason": "Insufficient historical data",
494
+ }
495
+
496
+ # Extract numeric values
497
+ values = []
498
+ timestamps = []
499
+ for metric in historical_metrics:
500
+ if isinstance(metric.value, (int, float)):
501
+ values.append(metric.value)
502
+ timestamps.append(metric.timestamp)
503
+
504
+ if len(values) < 10:
505
+ return {
506
+ "prediction": None,
507
+ "confidence": 0.0,
508
+ "reason": "Insufficient numeric data points",
509
+ }
510
+
511
+ # Simple linear regression for prediction
512
+ import numpy as np
513
+
514
+ # Convert timestamps to numeric values (hours ago)
515
+ now = datetime.now()
516
+ x = np.array([(now - ts).total_seconds() / 3600 for ts in timestamps])
517
+ y = np.array(values)
518
+
519
+ # Fit linear model
520
+ coeffs = np.polyfit(x, y, 1)
521
+
522
+ # Predict future values
523
+ future_x = np.array([-h for h in range(1, hours_ahead + 1)])
524
+ future_y = np.polyval(coeffs, future_x)
525
+
526
+ # Calculate confidence based on R-squared
527
+ y_pred = np.polyval(coeffs, x)
528
+ ss_res = np.sum((y - y_pred) ** 2)
529
+ ss_tot = np.sum((y - np.mean(y)) ** 2)
530
+ r_squared = 1 - (ss_res / ss_tot) if ss_tot != 0 else 0
531
+
532
+ confidence = max(0, r_squared)
533
+
534
+ return {
535
+ "prediction": {
536
+ "future_values": future_y.tolist(),
537
+ "trend": ("increasing" if coeffs[0] > 0 else "decreasing" if coeffs[0] < 0 else "stable"),
538
+ "slope": coeffs[0],
539
+ },
540
+ "confidence": confidence,
541
+ "data_points": len(values),
542
+ "model_type": "linear_regression",
543
+ "reason": f"Linear regression on {len(values)} data points with R²={r_squared:.3f}",
544
+ }
545
+
546
+ except Exception as e:
547
+ logger.error(f"Error in predictive analytics: {e}")
548
+ return {
549
+ "prediction": None,
550
+ "confidence": 0.0,
551
+ "reason": f"Analysis error: {str(e)}",
552
+ }
553
+
554
+ def detect_anomalies(
555
+ self,
556
+ metric_type: MetricType,
557
+ z_score_threshold: float = 2.0,
558
+ window_minutes: int = 60,
559
+ ) -> Dict[str, Any]:
560
+ """Detect anomalies in metric data using statistical methods"""
561
+ try:
562
+ recent_metrics = self.metrics_collector.get_metrics(
563
+ metric_type=metric_type,
564
+ start_time=datetime.now() - timedelta(minutes=window_minutes),
565
+ )
566
+
567
+ values = []
568
+ for metric in recent_metrics:
569
+ if isinstance(metric.value, (int, float)):
570
+ values.append(metric.value)
571
+
572
+ if len(values) < 5:
573
+ return {
574
+ "anomalies": [],
575
+ "statistics": {},
576
+ "reason": "Insufficient data for anomaly detection",
577
+ }
578
+
579
+ import numpy as np
580
+
581
+ values_array = np.array(values)
582
+ mean = np.mean(values_array)
583
+ std = np.std(values_array)
584
+
585
+ if std == 0:
586
+ return {
587
+ "anomalies": [],
588
+ "statistics": {"mean": mean, "std": std},
589
+ "reason": "No variance in data",
590
+ }
591
+
592
+ # Detect anomalies using Z-score
593
+ z_scores = np.abs((values_array - mean) / std)
594
+ anomaly_indices = np.where(z_scores > z_score_threshold)[0]
595
+
596
+ anomalies = []
597
+ for i, idx in enumerate(anomaly_indices):
598
+ metric = recent_metrics[idx]
599
+ anomalies.append(
600
+ {
601
+ "timestamp": metric.timestamp.isoformat(),
602
+ "value": metric.value,
603
+ "z_score": float(z_scores[idx]),
604
+ "deviation": float(values[idx] - mean),
605
+ }
606
+ )
607
+
608
+ return {
609
+ "anomalies": anomalies,
610
+ "statistics": {
611
+ "mean": float(mean),
612
+ "std": float(std),
613
+ "min": float(np.min(values_array)),
614
+ "max": float(np.max(values_array)),
615
+ "count": len(values),
616
+ },
617
+ "threshold": z_score_threshold,
618
+ "reason": f"Found {len(anomalies)} anomalies using Z-score > {z_score_threshold}",
619
+ }
620
+
621
+ except Exception as e:
622
+ logger.error(f"Error in anomaly detection: {e}")
623
+ return {
624
+ "anomalies": [],
625
+ "statistics": {},
626
+ "reason": f"Analysis error: {str(e)}",
627
+ }
628
+
629
+
630
+ class PerformanceMonitor:
631
+ """System performance monitoring"""
632
+
633
+ def __init__(self):
634
+ self.start_time = datetime.now()
635
+ self.metrics_collector = MetricsCollector()
636
+ self.alert_manager = AlertManager(self.metrics_collector)
637
+ self.predictive_analytics = PredictiveAnalytics(self.metrics_collector)
638
+ self._running = False
639
+ self._monitor_thread: Optional[threading.Thread] = None
640
+ self._monitor_interval = 30 # seconds
641
+
642
+ def start(self) -> None:
643
+ """Start performance monitoring"""
644
+ if self._running:
645
+ return
646
+
647
+ self._running = True
648
+ self._monitor_thread = threading.Thread(target=self._monitor_loop, daemon=True)
649
+ self._monitor_thread.start()
650
+ logger.info("Performance monitoring started")
651
+
652
+ def stop(self) -> None:
653
+ """Stop performance monitoring"""
654
+ self._running = False
655
+ if self._monitor_thread:
656
+ self._monitor_thread.join(timeout=5)
657
+ logger.info("Performance monitoring stopped")
658
+
659
+ def _monitor_loop(self) -> None:
660
+ """Main monitoring loop"""
661
+ while self._running:
662
+ try:
663
+ self._collect_system_metrics()
664
+ self._check_alerts()
665
+ time.sleep(self._monitor_interval)
666
+ except Exception as e:
667
+ logger.error(f"Error in monitoring loop: {e}")
668
+ time.sleep(self._monitor_interval)
669
+
670
+ def _collect_system_metrics(self) -> None:
671
+ """Collect system performance metrics"""
672
+ try:
673
+ # CPU Usage
674
+ cpu_percent = psutil.cpu_percent(interval=1)
675
+ self.metrics_collector.add_metric(
676
+ MetricData(
677
+ timestamp=datetime.now(),
678
+ metric_type=MetricType.CPU_USAGE,
679
+ value=cpu_percent,
680
+ tags={"component": "system"},
681
+ source="psutil",
682
+ )
683
+ )
684
+
685
+ # Memory Usage
686
+ memory = psutil.virtual_memory()
687
+ self.metrics_collector.add_metric(
688
+ MetricData(
689
+ timestamp=datetime.now(),
690
+ metric_type=MetricType.MEMORY_USAGE,
691
+ value=memory.percent,
692
+ tags={"component": "system", "total_gb": memory.total / (1024**3)},
693
+ source="psutil",
694
+ )
695
+ )
696
+
697
+ # Python process memory
698
+ process = psutil.Process()
699
+ process_memory = process.memory_info()
700
+ self.metrics_collector.add_metric(
701
+ MetricData(
702
+ timestamp=datetime.now(),
703
+ metric_type=MetricType.MEMORY_USAGE,
704
+ value=process_memory.rss / (1024**2), # MB
705
+ tags={"component": "python_process"},
706
+ source="psutil",
707
+ )
708
+ )
709
+
710
+ # System load
711
+ load_avg = psutil.getloadavg()
712
+ self.metrics_collector.add_metric(
713
+ MetricData(
714
+ timestamp=datetime.now(),
715
+ metric_type=MetricType.SYSTEM_PERFORMANCE,
716
+ value=load_avg[0], # 1-minute load average
717
+ tags={"component": "system", "metric": "load_1min"},
718
+ source="psutil",
719
+ )
720
+ )
721
+
722
+ except Exception as e:
723
+ logger.error(f"Error collecting system metrics: {e}")
724
+
725
+ def _check_alerts(self) -> None:
726
+ """Check for alerts"""
727
+ try:
728
+ alerts = self.alert_manager.check_alerts()
729
+ if alerts:
730
+ for alert in alerts:
731
+ logger.warning(f"Alert triggered: {alert.title} - {alert.current_value}")
732
+
733
+ except Exception as e:
734
+ logger.error(f"Error checking alerts: {e}")
735
+
736
+ def add_custom_metric(
737
+ self,
738
+ metric_type: MetricType,
739
+ value: Union[int, float],
740
+ tags: Optional[Dict[str, str]] = None,
741
+ source: str = "custom",
742
+ ) -> None:
743
+ """Add a custom metric"""
744
+ self.metrics_collector.add_metric(
745
+ MetricData(
746
+ timestamp=datetime.now(),
747
+ metric_type=metric_type,
748
+ value=value,
749
+ tags=tags or {},
750
+ source=source,
751
+ )
752
+ )
753
+
754
+ def get_system_health(self) -> SystemHealth:
755
+ """Get overall system health status"""
756
+ try:
757
+ # Calculate component scores
758
+ component_scores = {}
759
+
760
+ # CPU health
761
+ cpu_metrics = self.metrics_collector.get_metrics(
762
+ MetricType.CPU_USAGE, start_time=datetime.now() - timedelta(minutes=5)
763
+ )
764
+ if cpu_metrics:
765
+ cpu_values = [m.value for m in cpu_metrics if isinstance(m.value, (int, float))]
766
+ if cpu_values:
767
+ avg_cpu = statistics.mean(cpu_values)
768
+ cpu_score = max(0, 100 - avg_cpu) # Lower CPU usage = higher score
769
+ component_scores["cpu"] = cpu_score
770
+
771
+ # Memory health
772
+ memory_metrics = self.metrics_collector.get_metrics(
773
+ MetricType.MEMORY_USAGE,
774
+ start_time=datetime.now() - timedelta(minutes=5),
775
+ )
776
+ if memory_metrics:
777
+ memory_values = [m.value for m in memory_metrics if isinstance(m.value, (int, float))]
778
+ if memory_values:
779
+ avg_memory = statistics.mean(memory_values)
780
+ memory_score = max(0, 100 - avg_memory) # Lower memory usage = higher score
781
+ component_scores["memory"] = memory_score
782
+
783
+ # Error rate health
784
+ error_metrics = self.metrics_collector.get_metrics(
785
+ MetricType.ERROR_RATE, start_time=datetime.now() - timedelta(minutes=10)
786
+ )
787
+ if error_metrics:
788
+ error_values = [m.value for m in error_metrics if isinstance(m.value, (int, float))]
789
+ if error_values:
790
+ avg_error = statistics.mean(error_values)
791
+ error_score = max(0, 100 - avg_error * 10) # Lower error rate = higher score
792
+ component_scores["error_rate"] = error_score
793
+
794
+ # Calculate overall score
795
+ if component_scores:
796
+ overall_score = statistics.mean(component_scores.values())
797
+ else:
798
+ overall_score = 100.0
799
+
800
+ # Determine health status
801
+ if overall_score >= 90:
802
+ status = HealthStatus.HEALTHY
803
+ elif overall_score >= 70:
804
+ status = HealthStatus.WARNING
805
+ elif overall_score >= 50:
806
+ status = HealthStatus.DEGRADED
807
+ elif overall_score >= 30:
808
+ status = HealthStatus.CRITICAL
809
+ else:
810
+ status = HealthStatus.DOWN
811
+
812
+ # Get active alerts
813
+ active_alerts = list(self.alert_manager.active_alerts.keys())
814
+
815
+ # Get recent metrics summary
816
+ recent_metrics = {}
817
+ for metric_type in [
818
+ MetricType.CPU_USAGE,
819
+ MetricType.MEMORY_USAGE,
820
+ MetricType.ERROR_RATE,
821
+ ]:
822
+ recent_metric = self.metrics_collector.get_metrics(metric_type, limit=1)
823
+ if recent_metric and isinstance(recent_metric[0].value, (int, float)):
824
+ recent_metrics[metric_type.value] = recent_metric[0].value
825
+
826
+ return SystemHealth(
827
+ status=status,
828
+ timestamp=datetime.now(),
829
+ overall_score=overall_score,
830
+ component_scores=component_scores,
831
+ active_alerts=active_alerts,
832
+ recent_metrics=recent_metrics,
833
+ last_check=datetime.now(),
834
+ )
835
+
836
+ except Exception as e:
837
+ logger.error(f"Error calculating system health: {e}")
838
+ return SystemHealth(
839
+ status=HealthStatus.DOWN,
840
+ timestamp=datetime.now(),
841
+ overall_score=0.0,
842
+ last_check=datetime.now(),
843
+ )
844
+
845
+ def setup_default_alerts(self) -> None:
846
+ """Setup default alert rules"""
847
+ # CPU usage alert
848
+ self.alert_manager.add_alert_rule(
849
+ name="High CPU Usage",
850
+ metric_type=MetricType.CPU_USAGE,
851
+ threshold=80.0,
852
+ operator="gt",
853
+ severity=AlertSeverity.HIGH,
854
+ window_minutes=5,
855
+ consecutive_violations=2,
856
+ tags={"component": "cpu"},
857
+ )
858
+
859
+ # Memory usage alert
860
+ self.alert_manager.add_alert_rule(
861
+ name="High Memory Usage",
862
+ metric_type=MetricType.MEMORY_USAGE,
863
+ threshold=85.0,
864
+ operator="gt",
865
+ severity=AlertSeverity.HIGH,
866
+ window_minutes=5,
867
+ consecutive_violations=2,
868
+ tags={"component": "memory"},
869
+ )
870
+
871
+ # Error rate alert
872
+ self.alert_manager.add_alert_rule(
873
+ name="High Error Rate",
874
+ metric_type=MetricType.ERROR_RATE,
875
+ threshold=5.0,
876
+ operator="gt",
877
+ severity=AlertSeverity.CRITICAL,
878
+ window_minutes=2,
879
+ consecutive_violations=1,
880
+ tags={"component": "errors"},
881
+ )
882
+
883
+ logger.info("Default alert rules configured")
884
+
885
+
886
+ class ComprehensiveMonitoringSystem:
887
+ """Main monitoring system orchestrator"""
888
+
889
+ def __init__(self, config_file: Optional[Path] = None):
890
+ self.config_file = config_file or Path.cwd() / ".moai" / "config" / "monitoring.json"
891
+ self.config = self._load_config()
892
+
893
+ # Initialize components
894
+ self.metrics_collector = MetricsCollector(
895
+ buffer_size=self.config.get("buffer_size", 10000),
896
+ retention_hours=self.config.get("retention_hours", 24),
897
+ )
898
+
899
+ self.alert_manager = AlertManager(self.metrics_collector)
900
+ self.predictive_analytics = PredictiveAnalytics(self.metrics_collector)
901
+ self.performance_monitor = PerformanceMonitor()
902
+
903
+ # Initialize monitoring status
904
+ self._running = False
905
+ self._startup_time = datetime.now()
906
+
907
+ def _load_config(self) -> Dict[str, Any]:
908
+ """Load monitoring configuration"""
909
+ default_config = {
910
+ "buffer_size": 10000,
911
+ "retention_hours": 24,
912
+ "monitor_interval": 30,
913
+ "alert_check_interval": 60,
914
+ "predictive_analysis_hours": 24,
915
+ "health_check_interval": 300,
916
+ "enable_predictions": True,
917
+ "enable_anomaly_detection": True,
918
+ "auto_optimization": False,
919
+ }
920
+
921
+ if self.config_file.exists():
922
+ try:
923
+ with open(self.config_file, "r") as f:
924
+ config = json.load(f)
925
+ default_config.update(config)
926
+ except Exception as e:
927
+ logger.error(f"Error loading monitoring config: {e}")
928
+
929
+ return default_config
930
+
931
+ def start(self) -> None:
932
+ """Start the monitoring system"""
933
+ if self._running:
934
+ return
935
+
936
+ logger.info("Starting Comprehensive Monitoring System")
937
+
938
+ # Start performance monitoring
939
+ self.performance_monitor.start()
940
+
941
+ # Setup default alerts
942
+ self.performance_monitor.setup_default_alerts()
943
+
944
+ # Setup alert callbacks
945
+ self.alert_manager.add_alert_callback(self._handle_alert)
946
+
947
+ self._running = True
948
+ logger.info("Comprehensive Monitoring System started successfully")
949
+
950
+ def stop(self) -> None:
951
+ """Stop the monitoring system"""
952
+ if not self._running:
953
+ return
954
+
955
+ logger.info("Stopping Comprehensive Monitoring System")
956
+
957
+ self.performance_monitor.stop()
958
+ self._running = False
959
+
960
+ logger.info("Comprehensive Monitoring System stopped")
961
+
962
+ def _handle_alert(self, alert: Alert) -> None:
963
+ """Handle triggered alerts"""
964
+ logger.warning(f"ALERT: {alert.title} - {alert.description}")
965
+
966
+ # Here you could add additional alert handling:
967
+ # - Send notifications
968
+ # - Trigger automated responses
969
+ # - Log to external systems
970
+ # - Send to monitoring dashboard
971
+
972
+ def add_metric(
973
+ self,
974
+ metric_type: MetricType,
975
+ value: Union[int, float],
976
+ tags: Optional[Dict[str, str]] = None,
977
+ source: str = "user",
978
+ ) -> None:
979
+ """Add a custom metric"""
980
+ self.performance_monitor.add_custom_metric(metric_type, value, tags, source)
981
+
982
+ def get_dashboard_data(self) -> Dict[str, Any]:
983
+ """Get data for monitoring dashboard"""
984
+ try:
985
+ # System health
986
+ health = self.performance_monitor.get_system_health()
987
+
988
+ # Active alerts
989
+ active_alerts = self.alert_manager.get_active_alerts()
990
+
991
+ # Recent metrics summary
992
+ recent_metrics = {}
993
+ for metric_type in [
994
+ MetricType.CPU_USAGE,
995
+ MetricType.MEMORY_USAGE,
996
+ MetricType.ERROR_RATE,
997
+ MetricType.RESPONSE_TIME,
998
+ ]:
999
+ stats = self.metrics_collector.get_statistics(metric_type, minutes=60)
1000
+ if stats["count"] > 0:
1001
+ recent_metrics[metric_type.value] = stats
1002
+
1003
+ # Predictions
1004
+ predictions = {}
1005
+ if self.config.get("enable_predictions", True):
1006
+ for metric_type in [MetricType.CPU_USAGE, MetricType.MEMORY_USAGE]:
1007
+ pred = self.predictive_analytics.predict_metric_trend(metric_type, hours_ahead=1)
1008
+ if pred["confidence"] > 0.5:
1009
+ predictions[metric_type.value] = pred
1010
+
1011
+ return {
1012
+ "health": health.to_dict(),
1013
+ "active_alerts": [alert.to_dict() for alert in active_alerts],
1014
+ "recent_metrics": recent_metrics,
1015
+ "predictions": predictions,
1016
+ "uptime_seconds": (datetime.now() - self._startup_time).total_seconds(),
1017
+ "last_update": datetime.now().isoformat(),
1018
+ }
1019
+
1020
+ except Exception as e:
1021
+ logger.error(f"Error getting dashboard data: {e}")
1022
+ return {"error": str(e), "last_update": datetime.now().isoformat()}
1023
+
1024
+ def get_analytics_report(self, hours: int = 24) -> Dict[str, Any]:
1025
+ """Generate comprehensive analytics report"""
1026
+ try:
1027
+ # Overall metrics summary
1028
+ summary = {}
1029
+ for metric_type in MetricType:
1030
+ stats = self.metrics_collector.get_statistics(metric_type, minutes=hours * 60)
1031
+ if stats["count"] > 0:
1032
+ summary[metric_type.value] = stats
1033
+
1034
+ # Anomaly detection
1035
+ anomalies = {}
1036
+ if self.config.get("enable_anomaly_detection", True):
1037
+ for metric_type in [
1038
+ MetricType.CPU_USAGE,
1039
+ MetricType.MEMORY_USAGE,
1040
+ MetricType.ERROR_RATE,
1041
+ ]:
1042
+ anomaly_result = self.predictive_analytics.detect_anomalies(metric_type)
1043
+ if anomaly_result["anomalies"]:
1044
+ anomalies[metric_type.value] = anomaly_result
1045
+
1046
+ # Alert summary
1047
+ alert_history = self.alert_manager.get_alert_history(hours=hours)
1048
+ by_severity: Dict[str, int] = {}
1049
+ by_metric_type: Dict[str, int] = {}
1050
+
1051
+ for alert in alert_history:
1052
+ severity_key = alert.severity.name
1053
+ by_severity[severity_key] = by_severity.get(severity_key, 0) + 1
1054
+
1055
+ metric_key = alert.metric_type.value
1056
+ by_metric_type[metric_key] = by_metric_type.get(metric_key, 0) + 1
1057
+
1058
+ alert_summary = {
1059
+ "total_alerts": len(alert_history),
1060
+ "by_severity": by_severity,
1061
+ "by_metric_type": by_metric_type,
1062
+ "resolved_count": sum(1 for a in alert_history if a.resolved),
1063
+ "acknowledged_count": sum(1 for a in alert_history if a.acknowledged),
1064
+ }
1065
+
1066
+ return {
1067
+ "report_period_hours": hours,
1068
+ "generated_at": datetime.now().isoformat(),
1069
+ "metrics_summary": summary,
1070
+ "anomalies": anomalies,
1071
+ "alert_summary": alert_summary,
1072
+ "system_health": self.performance_monitor.get_system_health().to_dict(),
1073
+ "recommendations": self._generate_recommendations(summary, anomalies),
1074
+ }
1075
+
1076
+ except Exception as e:
1077
+ logger.error(f"Error generating analytics report: {e}")
1078
+ return {"error": str(e), "generated_at": datetime.now().isoformat()}
1079
+
1080
+ def _generate_recommendations(self, metrics_summary: Dict[str, Any], anomalies: Dict[str, Any]) -> List[str]:
1081
+ """Generate optimization recommendations based on metrics and anomalies"""
1082
+ recommendations = []
1083
+
1084
+ # CPU recommendations
1085
+ if MetricType.CPU_USAGE.value in metrics_summary:
1086
+ cpu_stats = metrics_summary[MetricType.CPU_USAGE.value]
1087
+ if cpu_stats["average"] > 70:
1088
+ recommendations.append("High CPU usage detected. Consider optimizing code or scaling resources.")
1089
+
1090
+ # Memory recommendations
1091
+ if MetricType.MEMORY_USAGE.value in metrics_summary:
1092
+ memory_stats = metrics_summary[MetricType.MEMORY_USAGE.value]
1093
+ if memory_stats["average"] > 80:
1094
+ recommendations.append(
1095
+ "High memory usage detected. Consider memory optimization or increasing available memory."
1096
+ )
1097
+
1098
+ # Error rate recommendations
1099
+ if MetricType.ERROR_RATE.value in metrics_summary:
1100
+ error_stats = metrics_summary[MetricType.ERROR_RATE.value]
1101
+ if error_stats["average"] > 5:
1102
+ recommendations.append(
1103
+ "High error rate detected. Review error logs and implement better error handling."
1104
+ )
1105
+
1106
+ # Anomaly recommendations
1107
+ if anomalies:
1108
+ recommendations.append(
1109
+ "Anomalies detected in system metrics. Review the detailed anomaly report for specific issues."
1110
+ )
1111
+
1112
+ return recommendations
1113
+
1114
+
1115
+ # Global instance for easy access
1116
+ _monitoring_system: Optional[ComprehensiveMonitoringSystem] = None
1117
+
1118
+
1119
+ def get_monitoring_system() -> ComprehensiveMonitoringSystem:
1120
+ """Get or create global monitoring system instance"""
1121
+ global _monitoring_system
1122
+ if _monitoring_system is None:
1123
+ _monitoring_system = ComprehensiveMonitoringSystem()
1124
+ return _monitoring_system
1125
+
1126
+
1127
+ # Convenience functions
1128
+ def start_monitoring() -> None:
1129
+ """Start the monitoring system"""
1130
+ system = get_monitoring_system()
1131
+ system.start()
1132
+
1133
+
1134
+ def stop_monitoring() -> None:
1135
+ """Stop the monitoring system"""
1136
+ system = get_monitoring_system()
1137
+ system.stop()
1138
+
1139
+
1140
+ def add_metric(
1141
+ metric_type: MetricType,
1142
+ value: Union[int, float],
1143
+ tags: Optional[Dict[str, str]] = None,
1144
+ source: str = "user",
1145
+ ) -> None:
1146
+ """Add a custom metric"""
1147
+ system = get_monitoring_system()
1148
+ system.add_metric(metric_type, value, tags, source)
1149
+
1150
+
1151
+ def get_dashboard_data() -> Dict[str, Any]:
1152
+ """Get monitoring dashboard data"""
1153
+ system = get_monitoring_system()
1154
+ return system.get_dashboard_data()
1155
+
1156
+
1157
+ if __name__ == "__main__":
1158
+ # Example usage
1159
+ print("Starting Comprehensive Monitoring System...")
1160
+
1161
+ monitoring = ComprehensiveMonitoringSystem()
1162
+ monitoring.start()
1163
+
1164
+ try:
1165
+ # Simulate some metrics
1166
+ for i in range(10):
1167
+ monitoring.add_metric(MetricType.CPU_USAGE, 50 + i * 3)
1168
+ monitoring.add_metric(MetricType.MEMORY_USAGE, 60 + i * 2)
1169
+ time.sleep(1)
1170
+
1171
+ # Get dashboard data
1172
+ dashboard_data = monitoring.get_dashboard_data()
1173
+ print(f"System Health: {dashboard_data['health']['status']}")
1174
+ print(f"Overall Score: {dashboard_data['health']['overall_score']}")
1175
+ print(f"Active Alerts: {len(dashboard_data['active_alerts'])}")
1176
+
1177
+ # Generate analytics report
1178
+ report = monitoring.get_analytics_report(hours=1)
1179
+ print(f"Analytics Report: {len(report['metrics_summary'])} metric types tracked")
1180
+
1181
+ finally:
1182
+ monitoring.stop()
1183
+ print("Monitoring stopped.")