claude-mpm 3.9.11__py3-none-any.whl → 4.0.4__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 (434) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +2 -2
  3. claude_mpm/__main__.py +3 -2
  4. claude_mpm/agents/__init__.py +85 -79
  5. claude_mpm/agents/agent_loader.py +464 -1003
  6. claude_mpm/agents/agent_loader_integration.py +45 -45
  7. claude_mpm/agents/agents_metadata.py +29 -30
  8. claude_mpm/agents/async_agent_loader.py +156 -138
  9. claude_mpm/agents/base_agent.json +1 -1
  10. claude_mpm/agents/base_agent_loader.py +179 -151
  11. claude_mpm/agents/frontmatter_validator.py +229 -130
  12. claude_mpm/agents/schema/agent_schema.json +1 -1
  13. claude_mpm/agents/system_agent_config.py +213 -147
  14. claude_mpm/agents/templates/__init__.py +13 -13
  15. claude_mpm/agents/templates/code_analyzer.json +2 -2
  16. claude_mpm/agents/templates/data_engineer.json +1 -1
  17. claude_mpm/agents/templates/documentation.json +23 -11
  18. claude_mpm/agents/templates/engineer.json +22 -6
  19. claude_mpm/agents/templates/memory_manager.json +1 -1
  20. claude_mpm/agents/templates/ops.json +2 -2
  21. claude_mpm/agents/templates/project_organizer.json +1 -1
  22. claude_mpm/agents/templates/qa.json +1 -1
  23. claude_mpm/agents/templates/refactoring_engineer.json +222 -0
  24. claude_mpm/agents/templates/research.json +20 -14
  25. claude_mpm/agents/templates/security.json +1 -1
  26. claude_mpm/agents/templates/ticketing.json +2 -2
  27. claude_mpm/agents/templates/version_control.json +1 -1
  28. claude_mpm/agents/templates/web_qa.json +3 -1
  29. claude_mpm/agents/templates/web_ui.json +2 -2
  30. claude_mpm/cli/__init__.py +79 -51
  31. claude_mpm/cli/__main__.py +3 -2
  32. claude_mpm/cli/commands/__init__.py +20 -20
  33. claude_mpm/cli/commands/agents.py +279 -247
  34. claude_mpm/cli/commands/aggregate.py +138 -157
  35. claude_mpm/cli/commands/cleanup.py +147 -147
  36. claude_mpm/cli/commands/config.py +93 -76
  37. claude_mpm/cli/commands/info.py +17 -16
  38. claude_mpm/cli/commands/mcp.py +140 -905
  39. claude_mpm/cli/commands/mcp_command_router.py +139 -0
  40. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  41. claude_mpm/cli/commands/mcp_install_commands.py +20 -0
  42. claude_mpm/cli/commands/mcp_server_commands.py +175 -0
  43. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  44. claude_mpm/cli/commands/memory.py +239 -203
  45. claude_mpm/cli/commands/monitor.py +330 -86
  46. claude_mpm/cli/commands/run.py +380 -429
  47. claude_mpm/cli/commands/run_config_checker.py +160 -0
  48. claude_mpm/cli/commands/socketio_monitor.py +235 -0
  49. claude_mpm/cli/commands/tickets.py +363 -220
  50. claude_mpm/cli/parser.py +24 -1156
  51. claude_mpm/cli/parsers/__init__.py +29 -0
  52. claude_mpm/cli/parsers/agents_parser.py +136 -0
  53. claude_mpm/cli/parsers/base_parser.py +331 -0
  54. claude_mpm/cli/parsers/config_parser.py +85 -0
  55. claude_mpm/cli/parsers/mcp_parser.py +152 -0
  56. claude_mpm/cli/parsers/memory_parser.py +138 -0
  57. claude_mpm/cli/parsers/monitor_parser.py +124 -0
  58. claude_mpm/cli/parsers/run_parser.py +147 -0
  59. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  60. claude_mpm/cli/ticket_cli.py +7 -3
  61. claude_mpm/cli/utils.py +55 -37
  62. claude_mpm/cli_module/__init__.py +6 -6
  63. claude_mpm/cli_module/args.py +188 -140
  64. claude_mpm/cli_module/commands.py +79 -70
  65. claude_mpm/cli_module/migration_example.py +38 -60
  66. claude_mpm/config/__init__.py +32 -25
  67. claude_mpm/config/agent_config.py +151 -119
  68. claude_mpm/config/experimental_features.py +71 -73
  69. claude_mpm/config/paths.py +94 -208
  70. claude_mpm/config/socketio_config.py +84 -73
  71. claude_mpm/constants.py +35 -18
  72. claude_mpm/core/__init__.py +9 -6
  73. claude_mpm/core/agent_name_normalizer.py +68 -71
  74. claude_mpm/core/agent_registry.py +372 -521
  75. claude_mpm/core/agent_session_manager.py +74 -63
  76. claude_mpm/core/base_service.py +116 -87
  77. claude_mpm/core/cache.py +119 -153
  78. claude_mpm/core/claude_runner.py +425 -1120
  79. claude_mpm/core/config.py +263 -168
  80. claude_mpm/core/config_aliases.py +69 -61
  81. claude_mpm/core/config_constants.py +292 -0
  82. claude_mpm/core/constants.py +57 -99
  83. claude_mpm/core/container.py +211 -178
  84. claude_mpm/core/exceptions.py +233 -89
  85. claude_mpm/core/factories.py +92 -54
  86. claude_mpm/core/framework_loader.py +378 -220
  87. claude_mpm/core/hook_manager.py +198 -83
  88. claude_mpm/core/hook_performance_config.py +136 -0
  89. claude_mpm/core/injectable_service.py +61 -55
  90. claude_mpm/core/interactive_session.py +165 -155
  91. claude_mpm/core/interfaces.py +221 -195
  92. claude_mpm/core/lazy.py +96 -96
  93. claude_mpm/core/logger.py +133 -107
  94. claude_mpm/core/logging_config.py +185 -157
  95. claude_mpm/core/minimal_framework_loader.py +20 -15
  96. claude_mpm/core/mixins.py +30 -29
  97. claude_mpm/core/oneshot_session.py +215 -181
  98. claude_mpm/core/optimized_agent_loader.py +134 -138
  99. claude_mpm/core/optimized_startup.py +159 -157
  100. claude_mpm/core/pm_hook_interceptor.py +85 -72
  101. claude_mpm/core/service_registry.py +103 -101
  102. claude_mpm/core/session_manager.py +97 -87
  103. claude_mpm/core/socketio_pool.py +212 -158
  104. claude_mpm/core/tool_access_control.py +58 -51
  105. claude_mpm/core/types.py +46 -24
  106. claude_mpm/core/typing_utils.py +166 -82
  107. claude_mpm/core/unified_agent_registry.py +721 -0
  108. claude_mpm/core/unified_config.py +550 -0
  109. claude_mpm/core/unified_paths.py +549 -0
  110. claude_mpm/dashboard/index.html +1 -1
  111. claude_mpm/dashboard/open_dashboard.py +51 -17
  112. claude_mpm/dashboard/static/built/components/agent-inference.js +2 -0
  113. claude_mpm/dashboard/static/built/components/event-processor.js +2 -0
  114. claude_mpm/dashboard/static/built/components/event-viewer.js +2 -0
  115. claude_mpm/dashboard/static/built/components/export-manager.js +2 -0
  116. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +2 -0
  117. claude_mpm/dashboard/static/built/components/hud-library-loader.js +2 -0
  118. claude_mpm/dashboard/static/built/components/hud-manager.js +2 -0
  119. claude_mpm/dashboard/static/built/components/hud-visualizer.js +2 -0
  120. claude_mpm/dashboard/static/built/components/module-viewer.js +2 -0
  121. claude_mpm/dashboard/static/built/components/session-manager.js +2 -0
  122. claude_mpm/dashboard/static/built/components/socket-manager.js +2 -0
  123. claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -0
  124. claude_mpm/dashboard/static/built/components/working-directory.js +2 -0
  125. claude_mpm/dashboard/static/built/dashboard.js +2 -0
  126. claude_mpm/dashboard/static/built/socket-client.js +2 -0
  127. claude_mpm/dashboard/static/css/dashboard.css +27 -8
  128. claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
  129. claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
  130. claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
  131. claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
  132. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
  133. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
  134. claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
  135. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
  136. claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
  137. claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
  138. claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
  139. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
  140. claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
  141. claude_mpm/dashboard/static/dist/dashboard.js +2 -0
  142. claude_mpm/dashboard/static/dist/socket-client.js +2 -0
  143. claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
  144. claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
  145. claude_mpm/dashboard/static/js/components/event-viewer.js +93 -72
  146. claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
  147. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +110 -96
  148. claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
  149. claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
  150. claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
  151. claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
  152. claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
  153. claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
  154. claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
  155. claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
  156. claude_mpm/dashboard/static/js/dashboard.js +178 -453
  157. claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
  158. claude_mpm/dashboard/static/js/socket-client.js +133 -53
  159. claude_mpm/dashboard/templates/index.html +40 -50
  160. claude_mpm/experimental/cli_enhancements.py +60 -58
  161. claude_mpm/generators/__init__.py +1 -1
  162. claude_mpm/generators/agent_profile_generator.py +75 -65
  163. claude_mpm/hooks/__init__.py +1 -1
  164. claude_mpm/hooks/base_hook.py +33 -28
  165. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  166. claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
  167. claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
  168. claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
  169. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
  170. claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
  171. claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
  172. claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
  173. claude_mpm/hooks/memory_integration_hook.py +140 -100
  174. claude_mpm/hooks/tool_call_interceptor.py +89 -76
  175. claude_mpm/hooks/validation_hooks.py +57 -49
  176. claude_mpm/init.py +145 -121
  177. claude_mpm/models/__init__.py +9 -9
  178. claude_mpm/models/agent_definition.py +33 -23
  179. claude_mpm/models/agent_session.py +228 -200
  180. claude_mpm/scripts/__init__.py +1 -1
  181. claude_mpm/scripts/socketio_daemon.py +192 -75
  182. claude_mpm/scripts/socketio_server_manager.py +328 -0
  183. claude_mpm/scripts/start_activity_logging.py +25 -22
  184. claude_mpm/services/__init__.py +68 -43
  185. claude_mpm/services/agent_capabilities_service.py +271 -0
  186. claude_mpm/services/agents/__init__.py +23 -32
  187. claude_mpm/services/agents/deployment/__init__.py +3 -3
  188. claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
  189. claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
  190. claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
  191. claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
  192. claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
  193. claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
  194. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
  195. claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
  196. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
  197. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
  198. claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
  199. claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
  200. claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
  201. claude_mpm/services/agents/deployment/agent_validator.py +352 -0
  202. claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
  203. claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
  204. claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
  205. claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
  206. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  207. claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
  208. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  209. claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
  210. claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
  211. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  212. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  213. claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
  214. claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
  215. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  216. claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
  217. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  218. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  219. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  220. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  221. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
  222. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  223. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  224. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
  225. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
  226. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
  227. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
  228. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
  229. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  230. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
  231. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  232. claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
  233. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
  234. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  235. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  236. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  237. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  238. claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
  239. claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
  240. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  241. claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
  242. claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
  243. claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
  244. claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
  245. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  246. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  247. claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
  248. claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
  249. claude_mpm/services/agents/loading/__init__.py +2 -2
  250. claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
  251. claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
  252. claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
  253. claude_mpm/services/agents/management/__init__.py +2 -2
  254. claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
  255. claude_mpm/services/agents/management/agent_management_service.py +209 -156
  256. claude_mpm/services/agents/memory/__init__.py +9 -6
  257. claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
  258. claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
  259. claude_mpm/services/agents/memory/analyzer.py +430 -0
  260. claude_mpm/services/agents/memory/content_manager.py +376 -0
  261. claude_mpm/services/agents/memory/template_generator.py +468 -0
  262. claude_mpm/services/agents/registry/__init__.py +7 -10
  263. claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
  264. claude_mpm/services/agents/registry/modification_tracker.py +351 -285
  265. claude_mpm/services/async_session_logger.py +187 -153
  266. claude_mpm/services/claude_session_logger.py +87 -72
  267. claude_mpm/services/command_handler_service.py +217 -0
  268. claude_mpm/services/communication/__init__.py +3 -2
  269. claude_mpm/services/core/__init__.py +50 -97
  270. claude_mpm/services/core/base.py +60 -53
  271. claude_mpm/services/core/interfaces/__init__.py +188 -0
  272. claude_mpm/services/core/interfaces/agent.py +351 -0
  273. claude_mpm/services/core/interfaces/communication.py +343 -0
  274. claude_mpm/services/core/interfaces/infrastructure.py +413 -0
  275. claude_mpm/services/core/interfaces/service.py +434 -0
  276. claude_mpm/services/core/interfaces.py +19 -944
  277. claude_mpm/services/event_aggregator.py +208 -170
  278. claude_mpm/services/exceptions.py +387 -308
  279. claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
  280. claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
  281. claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
  282. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
  283. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
  284. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
  285. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
  286. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
  287. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  288. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  289. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  290. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  291. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
  292. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  293. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  294. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
  295. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
  296. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  297. claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
  298. claude_mpm/services/hook_service.py +106 -114
  299. claude_mpm/services/infrastructure/__init__.py +7 -5
  300. claude_mpm/services/infrastructure/context_preservation.py +233 -199
  301. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  302. claude_mpm/services/infrastructure/logging.py +83 -76
  303. claude_mpm/services/infrastructure/monitoring.py +547 -404
  304. claude_mpm/services/mcp_gateway/__init__.py +30 -13
  305. claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
  306. claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
  307. claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
  308. claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
  309. claude_mpm/services/mcp_gateway/core/__init__.py +13 -20
  310. claude_mpm/services/mcp_gateway/core/base.py +80 -67
  311. claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
  312. claude_mpm/services/mcp_gateway/core/interfaces.py +87 -84
  313. claude_mpm/services/mcp_gateway/main.py +287 -137
  314. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  315. claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
  316. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  317. claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
  318. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
  319. claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
  320. claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
  321. claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
  322. claude_mpm/services/mcp_gateway/tools/base_adapter.py +109 -119
  323. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
  324. claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
  325. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
  326. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
  327. claude_mpm/services/memory/__init__.py +2 -2
  328. claude_mpm/services/memory/builder.py +451 -362
  329. claude_mpm/services/memory/cache/__init__.py +2 -2
  330. claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
  331. claude_mpm/services/memory/cache/simple_cache.py +107 -93
  332. claude_mpm/services/memory/indexed_memory.py +195 -193
  333. claude_mpm/services/memory/optimizer.py +267 -234
  334. claude_mpm/services/memory/router.py +571 -263
  335. claude_mpm/services/memory_hook_service.py +237 -0
  336. claude_mpm/services/port_manager.py +575 -0
  337. claude_mpm/services/project/__init__.py +3 -3
  338. claude_mpm/services/project/analyzer.py +451 -305
  339. claude_mpm/services/project/registry.py +262 -240
  340. claude_mpm/services/recovery_manager.py +287 -231
  341. claude_mpm/services/response_tracker.py +87 -67
  342. claude_mpm/services/runner_configuration_service.py +587 -0
  343. claude_mpm/services/session_management_service.py +304 -0
  344. claude_mpm/services/socketio/__init__.py +4 -4
  345. claude_mpm/services/socketio/client_proxy.py +174 -0
  346. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  347. claude_mpm/services/socketio/handlers/base.py +44 -30
  348. claude_mpm/services/socketio/handlers/connection.py +166 -64
  349. claude_mpm/services/socketio/handlers/file.py +123 -108
  350. claude_mpm/services/socketio/handlers/git.py +607 -373
  351. claude_mpm/services/socketio/handlers/hook.py +185 -0
  352. claude_mpm/services/socketio/handlers/memory.py +4 -4
  353. claude_mpm/services/socketio/handlers/project.py +4 -4
  354. claude_mpm/services/socketio/handlers/registry.py +53 -38
  355. claude_mpm/services/socketio/server/__init__.py +18 -0
  356. claude_mpm/services/socketio/server/broadcaster.py +252 -0
  357. claude_mpm/services/socketio/server/core.py +399 -0
  358. claude_mpm/services/socketio/server/main.py +323 -0
  359. claude_mpm/services/socketio_client_manager.py +160 -133
  360. claude_mpm/services/socketio_server.py +36 -1885
  361. claude_mpm/services/subprocess_launcher_service.py +316 -0
  362. claude_mpm/services/system_instructions_service.py +258 -0
  363. claude_mpm/services/ticket_manager.py +19 -533
  364. claude_mpm/services/utility_service.py +285 -0
  365. claude_mpm/services/version_control/__init__.py +18 -21
  366. claude_mpm/services/version_control/branch_strategy.py +20 -10
  367. claude_mpm/services/version_control/conflict_resolution.py +37 -13
  368. claude_mpm/services/version_control/git_operations.py +52 -21
  369. claude_mpm/services/version_control/semantic_versioning.py +92 -53
  370. claude_mpm/services/version_control/version_parser.py +145 -125
  371. claude_mpm/services/version_service.py +270 -0
  372. claude_mpm/storage/__init__.py +2 -2
  373. claude_mpm/storage/state_storage.py +177 -181
  374. claude_mpm/ticket_wrapper.py +2 -2
  375. claude_mpm/utils/__init__.py +2 -2
  376. claude_mpm/utils/agent_dependency_loader.py +453 -243
  377. claude_mpm/utils/config_manager.py +157 -118
  378. claude_mpm/utils/console.py +1 -1
  379. claude_mpm/utils/dependency_cache.py +102 -107
  380. claude_mpm/utils/dependency_manager.py +52 -47
  381. claude_mpm/utils/dependency_strategies.py +131 -96
  382. claude_mpm/utils/environment_context.py +110 -102
  383. claude_mpm/utils/error_handler.py +75 -55
  384. claude_mpm/utils/file_utils.py +80 -67
  385. claude_mpm/utils/framework_detection.py +12 -11
  386. claude_mpm/utils/import_migration_example.py +12 -60
  387. claude_mpm/utils/imports.py +48 -45
  388. claude_mpm/utils/path_operations.py +100 -93
  389. claude_mpm/utils/robust_installer.py +172 -164
  390. claude_mpm/utils/session_logging.py +30 -23
  391. claude_mpm/utils/subprocess_utils.py +99 -61
  392. claude_mpm/validation/__init__.py +1 -1
  393. claude_mpm/validation/agent_validator.py +151 -111
  394. claude_mpm/validation/frontmatter_validator.py +92 -71
  395. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/METADATA +90 -22
  396. claude_mpm-4.0.4.dist-info/RECORD +417 -0
  397. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/entry_points.txt +1 -0
  398. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/licenses/LICENSE +1 -1
  399. claude_mpm/cli/commands/run_guarded.py +0 -511
  400. claude_mpm/config/memory_guardian_config.py +0 -325
  401. claude_mpm/config/memory_guardian_yaml.py +0 -335
  402. claude_mpm/core/config_paths.py +0 -150
  403. claude_mpm/core/memory_aware_runner.py +0 -353
  404. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  405. claude_mpm/deployment_paths.py +0 -261
  406. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  407. claude_mpm/models/state_models.py +0 -433
  408. claude_mpm/services/agent/__init__.py +0 -24
  409. claude_mpm/services/agent/deployment.py +0 -2548
  410. claude_mpm/services/agent/management.py +0 -598
  411. claude_mpm/services/agent/registry.py +0 -813
  412. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  413. claude_mpm/services/communication/socketio.py +0 -1935
  414. claude_mpm/services/communication/websocket.py +0 -479
  415. claude_mpm/services/framework_claude_md_generator.py +0 -624
  416. claude_mpm/services/health_monitor.py +0 -893
  417. claude_mpm/services/infrastructure/graceful_degradation.py +0 -616
  418. claude_mpm/services/infrastructure/health_monitor.py +0 -775
  419. claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
  420. claude_mpm/services/infrastructure/memory_guardian.py +0 -944
  421. claude_mpm/services/infrastructure/restart_protection.py +0 -642
  422. claude_mpm/services/infrastructure/state_manager.py +0 -774
  423. claude_mpm/services/mcp_gateway/manager.py +0 -334
  424. claude_mpm/services/optimized_hook_service.py +0 -542
  425. claude_mpm/services/project_analyzer.py +0 -864
  426. claude_mpm/services/project_registry.py +0 -608
  427. claude_mpm/services/standalone_socketio_server.py +0 -1300
  428. claude_mpm/services/ticket_manager_di.py +0 -318
  429. claude_mpm/services/ticketing_service_original.py +0 -510
  430. claude_mpm/utils/paths.py +0 -395
  431. claude_mpm/utils/platform_memory.py +0 -524
  432. claude_mpm-3.9.11.dist-info/RECORD +0 -306
  433. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/WHEEL +0 -0
  434. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/top_level.txt +0 -0
@@ -1,325 +0,0 @@
1
- """Memory Guardian configuration for managing Claude Code memory usage.
2
-
3
- This module provides configuration management for the MemoryGuardian service
4
- that monitors and manages Claude Code subprocess memory consumption.
5
-
6
- Design Principles:
7
- - Platform-agnostic configuration with OS-specific overrides
8
- - Environment-based configuration for different deployment scenarios
9
- - Flexible thresholds for memory monitoring
10
- - Support for both psutil and fallback monitoring methods
11
- """
12
-
13
- import os
14
- import platform
15
- from dataclasses import dataclass, field
16
- from pathlib import Path
17
- from typing import Dict, Any, Optional, List
18
-
19
-
20
- @dataclass
21
- class MemoryThresholds:
22
- """Memory threshold configuration in MB."""
23
-
24
- # Memory thresholds in MB (defaults for 24GB system)
25
- warning: int = 12288 # 12GB - Start monitoring closely
26
- critical: int = 15360 # 15GB - Consider restart
27
- emergency: int = 18432 # 18GB - Force restart
28
-
29
- # Percentage-based thresholds (as fallback when system memory is detected)
30
- warning_percent: float = 50.0 # 50% of system memory
31
- critical_percent: float = 65.0 # 65% of system memory
32
- emergency_percent: float = 75.0 # 75% of system memory
33
-
34
- def adjust_for_system_memory(self, total_memory_mb: int) -> None:
35
- """Adjust thresholds based on available system memory."""
36
- if total_memory_mb > 0:
37
- self.warning = int(total_memory_mb * (self.warning_percent / 100))
38
- self.critical = int(total_memory_mb * (self.critical_percent / 100))
39
- self.emergency = int(total_memory_mb * (self.emergency_percent / 100))
40
-
41
- def to_dict(self) -> Dict[str, Any]:
42
- """Convert thresholds to dictionary."""
43
- return {
44
- 'warning_mb': self.warning,
45
- 'critical_mb': self.critical,
46
- 'emergency_mb': self.emergency,
47
- 'warning_percent': self.warning_percent,
48
- 'critical_percent': self.critical_percent,
49
- 'emergency_percent': self.emergency_percent
50
- }
51
-
52
-
53
- @dataclass
54
- class RestartPolicy:
55
- """Configuration for process restart behavior."""
56
-
57
- # Restart attempts
58
- max_attempts: int = 3 # Maximum restart attempts before giving up
59
- attempt_window: int = 3600 # Window in seconds to count attempts (1 hour)
60
-
61
- # Cooldown periods
62
- initial_cooldown: int = 30 # Initial cooldown after restart (seconds)
63
- max_cooldown: int = 300 # Maximum cooldown period (5 minutes)
64
- cooldown_multiplier: float = 2.0 # Multiply cooldown on each retry
65
-
66
- # Graceful shutdown
67
- graceful_timeout: int = 30 # Time to wait for graceful shutdown (seconds)
68
- force_kill_timeout: int = 10 # Time to wait before SIGKILL after SIGTERM
69
-
70
- def get_cooldown(self, attempt: int) -> int:
71
- """Calculate cooldown period for given attempt number."""
72
- cooldown = self.initial_cooldown * (self.cooldown_multiplier ** (attempt - 1))
73
- return min(int(cooldown), self.max_cooldown)
74
-
75
- def to_dict(self) -> Dict[str, Any]:
76
- """Convert restart policy to dictionary."""
77
- return {
78
- 'max_attempts': self.max_attempts,
79
- 'attempt_window': self.attempt_window,
80
- 'initial_cooldown': self.initial_cooldown,
81
- 'max_cooldown': self.max_cooldown,
82
- 'cooldown_multiplier': self.cooldown_multiplier,
83
- 'graceful_timeout': self.graceful_timeout,
84
- 'force_kill_timeout': self.force_kill_timeout
85
- }
86
-
87
-
88
- @dataclass
89
- class MonitoringConfig:
90
- """Configuration for memory monitoring behavior."""
91
-
92
- # Check intervals (seconds)
93
- normal_interval: int = 30 # Normal check interval
94
- warning_interval: int = 15 # Check interval when in warning state
95
- critical_interval: int = 5 # Check interval when in critical state
96
-
97
- # Monitoring method preferences
98
- prefer_psutil: bool = True # Prefer psutil if available
99
- fallback_methods: List[str] = field(default_factory=lambda: [
100
- 'platform_specific', # Use OS-specific commands
101
- 'resource_module', # Use resource module as last resort
102
- ])
103
-
104
- # Logging and reporting
105
- log_memory_stats: bool = True # Log memory statistics
106
- log_interval: int = 300 # Log summary every 5 minutes
107
- detailed_logging: bool = False # Enable detailed debug logging
108
-
109
- def get_check_interval(self, memory_state: str) -> int:
110
- """Get check interval based on current memory state."""
111
- if memory_state == 'critical':
112
- return self.critical_interval
113
- elif memory_state == 'warning':
114
- return self.warning_interval
115
- else:
116
- return self.normal_interval
117
-
118
- def to_dict(self) -> Dict[str, Any]:
119
- """Convert monitoring config to dictionary."""
120
- return {
121
- 'normal_interval': self.normal_interval,
122
- 'warning_interval': self.warning_interval,
123
- 'critical_interval': self.critical_interval,
124
- 'prefer_psutil': self.prefer_psutil,
125
- 'fallback_methods': self.fallback_methods,
126
- 'log_memory_stats': self.log_memory_stats,
127
- 'log_interval': self.log_interval,
128
- 'detailed_logging': self.detailed_logging
129
- }
130
-
131
-
132
- @dataclass
133
- class PlatformOverrides:
134
- """Platform-specific configuration overrides."""
135
-
136
- # macOS specific
137
- macos_use_activity_monitor: bool = False # Use Activity Monitor data if available
138
- macos_memory_pressure_check: bool = True # Check system memory pressure
139
-
140
- # Linux specific
141
- linux_use_proc: bool = True # Use /proc filesystem
142
- linux_check_oom_score: bool = True # Monitor OOM killer score
143
-
144
- # Windows specific
145
- windows_use_wmi: bool = True # Use WMI for monitoring
146
- windows_use_performance_counter: bool = False # Use performance counters
147
-
148
- def to_dict(self) -> Dict[str, Any]:
149
- """Convert platform overrides to dictionary."""
150
- return {
151
- 'macos_use_activity_monitor': self.macos_use_activity_monitor,
152
- 'macos_memory_pressure_check': self.macos_memory_pressure_check,
153
- 'linux_use_proc': self.linux_use_proc,
154
- 'linux_check_oom_score': self.linux_check_oom_score,
155
- 'windows_use_wmi': self.windows_use_wmi,
156
- 'windows_use_performance_counter': self.windows_use_performance_counter
157
- }
158
-
159
-
160
- @dataclass
161
- class MemoryGuardianConfig:
162
- """Complete configuration for MemoryGuardian service."""
163
-
164
- # Core configurations
165
- thresholds: MemoryThresholds = field(default_factory=MemoryThresholds)
166
- restart_policy: RestartPolicy = field(default_factory=RestartPolicy)
167
- monitoring: MonitoringConfig = field(default_factory=MonitoringConfig)
168
- platform_overrides: PlatformOverrides = field(default_factory=PlatformOverrides)
169
-
170
- # Process configuration
171
- process_command: List[str] = field(default_factory=lambda: ['claude-code'])
172
- process_args: List[str] = field(default_factory=list)
173
- process_env: Dict[str, str] = field(default_factory=dict)
174
- working_directory: Optional[str] = None
175
-
176
- # Service configuration
177
- enabled: bool = True # Enable memory guardian
178
- auto_start: bool = True # Auto-start monitored process
179
- persist_state: bool = True # Persist state across restarts
180
- state_file: Optional[str] = None # State file path
181
-
182
- @classmethod
183
- def from_env(cls) -> 'MemoryGuardianConfig':
184
- """Create configuration from environment variables."""
185
- config = cls()
186
-
187
- # Memory thresholds
188
- if warning := os.getenv('CLAUDE_MPM_MEMORY_WARNING_MB'):
189
- config.thresholds.warning = int(warning)
190
- if critical := os.getenv('CLAUDE_MPM_MEMORY_CRITICAL_MB'):
191
- config.thresholds.critical = int(critical)
192
- if emergency := os.getenv('CLAUDE_MPM_MEMORY_EMERGENCY_MB'):
193
- config.thresholds.emergency = int(emergency)
194
-
195
- # Restart policy
196
- if max_attempts := os.getenv('CLAUDE_MPM_RESTART_MAX_ATTEMPTS'):
197
- config.restart_policy.max_attempts = int(max_attempts)
198
- if cooldown := os.getenv('CLAUDE_MPM_RESTART_COOLDOWN'):
199
- config.restart_policy.initial_cooldown = int(cooldown)
200
-
201
- # Monitoring intervals
202
- if interval := os.getenv('CLAUDE_MPM_MONITOR_INTERVAL'):
203
- config.monitoring.normal_interval = int(interval)
204
- if log_interval := os.getenv('CLAUDE_MPM_LOG_INTERVAL'):
205
- config.monitoring.log_interval = int(log_interval)
206
-
207
- # Service settings
208
- config.enabled = os.getenv('CLAUDE_MPM_MEMORY_GUARDIAN_ENABLED', 'true').lower() == 'true'
209
- config.auto_start = os.getenv('CLAUDE_MPM_AUTO_START', 'true').lower() == 'true'
210
-
211
- # Process command
212
- if command := os.getenv('CLAUDE_MPM_PROCESS_COMMAND'):
213
- config.process_command = command.split()
214
-
215
- return config
216
-
217
- @classmethod
218
- def for_development(cls) -> 'MemoryGuardianConfig':
219
- """Configuration optimized for development."""
220
- config = cls()
221
- config.thresholds.warning = 8192 # 8GB for dev machines
222
- config.thresholds.critical = 10240 # 10GB
223
- config.thresholds.emergency = 12288 # 12GB
224
- config.monitoring.normal_interval = 60 # Check less frequently
225
- config.monitoring.detailed_logging = True
226
- return config
227
-
228
- @classmethod
229
- def for_production(cls) -> 'MemoryGuardianConfig':
230
- """Configuration optimized for production."""
231
- config = cls()
232
- config.monitoring.normal_interval = 30
233
- config.monitoring.log_memory_stats = True
234
- config.persist_state = True
235
- config.restart_policy.max_attempts = 5
236
- return config
237
-
238
- @classmethod
239
- def for_platform(cls, platform_name: Optional[str] = None) -> 'MemoryGuardianConfig':
240
- """Get platform-specific configuration."""
241
- if platform_name is None:
242
- platform_name = platform.system().lower()
243
-
244
- config = cls()
245
-
246
- if platform_name == 'darwin': # macOS
247
- config.platform_overrides.macos_memory_pressure_check = True
248
- elif platform_name == 'linux':
249
- config.platform_overrides.linux_use_proc = True
250
- config.platform_overrides.linux_check_oom_score = True
251
- elif platform_name == 'windows':
252
- config.platform_overrides.windows_use_wmi = True
253
-
254
- return config
255
-
256
- def to_dict(self) -> Dict[str, Any]:
257
- """Convert configuration to dictionary."""
258
- return {
259
- 'thresholds': self.thresholds.to_dict(),
260
- 'restart_policy': self.restart_policy.to_dict(),
261
- 'monitoring': self.monitoring.to_dict(),
262
- 'platform_overrides': self.platform_overrides.to_dict(),
263
- 'process_command': self.process_command,
264
- 'process_args': self.process_args,
265
- 'process_env': self.process_env,
266
- 'working_directory': self.working_directory,
267
- 'enabled': self.enabled,
268
- 'auto_start': self.auto_start,
269
- 'persist_state': self.persist_state,
270
- 'state_file': self.state_file
271
- }
272
-
273
- def validate(self) -> List[str]:
274
- """Validate configuration and return list of issues."""
275
- issues = []
276
-
277
- # Validate thresholds are in correct order
278
- if self.thresholds.warning >= self.thresholds.critical:
279
- issues.append("Warning threshold must be less than critical threshold")
280
- if self.thresholds.critical >= self.thresholds.emergency:
281
- issues.append("Critical threshold must be less than emergency threshold")
282
-
283
- # Validate intervals
284
- if self.monitoring.normal_interval <= 0:
285
- issues.append("Normal monitoring interval must be positive")
286
- if self.monitoring.warning_interval <= 0:
287
- issues.append("Warning monitoring interval must be positive")
288
- if self.monitoring.critical_interval <= 0:
289
- issues.append("Critical monitoring interval must be positive")
290
-
291
- # Validate restart policy
292
- if self.restart_policy.max_attempts < 0:
293
- issues.append("Max restart attempts cannot be negative")
294
- if self.restart_policy.initial_cooldown <= 0:
295
- issues.append("Initial cooldown must be positive")
296
-
297
- # Validate process command
298
- if not self.process_command:
299
- issues.append("Process command cannot be empty")
300
-
301
- return issues
302
-
303
-
304
- def get_default_config() -> MemoryGuardianConfig:
305
- """Get default configuration adjusted for current platform."""
306
- config = MemoryGuardianConfig.for_platform()
307
-
308
- # Try to adjust for available system memory
309
- try:
310
- import psutil
311
- total_memory_mb = psutil.virtual_memory().total // (1024 * 1024)
312
- config.thresholds.adjust_for_system_memory(total_memory_mb)
313
- except ImportError:
314
- # psutil not available, use defaults
315
- pass
316
- except Exception:
317
- # Any other error, use defaults
318
- pass
319
-
320
- # Override with environment variables
321
- env_config = MemoryGuardianConfig.from_env()
322
- if env_config.enabled != config.enabled:
323
- config = env_config
324
-
325
- return config
@@ -1,335 +0,0 @@
1
- """YAML configuration support for Memory Guardian.
2
-
3
- This module provides YAML configuration loading and validation for
4
- the Memory Guardian service, allowing users to configure memory monitoring
5
- through configuration files.
6
- """
7
-
8
- import os
9
- from pathlib import Path
10
- from typing import Optional, Dict, Any
11
-
12
- import yaml
13
-
14
- from claude_mpm.config.memory_guardian_config import (
15
- MemoryGuardianConfig,
16
- MemoryThresholds,
17
- RestartPolicy,
18
- MonitoringConfig
19
- )
20
- from claude_mpm.core.logging_config import get_logger
21
-
22
-
23
- logger = get_logger(__name__)
24
-
25
-
26
- # Default configuration file locations
27
- DEFAULT_CONFIG_LOCATIONS = [
28
- Path.home() / ".claude-mpm" / "config" / "memory_guardian.yaml",
29
- Path.home() / ".claude-mpm" / "memory_guardian.yaml",
30
- Path.cwd() / ".claude-mpm" / "memory_guardian.yaml",
31
- Path.cwd() / "memory_guardian.yaml",
32
- ]
33
-
34
-
35
- def find_config_file() -> Optional[Path]:
36
- """Find memory guardian configuration file in standard locations.
37
-
38
- Returns:
39
- Path to configuration file or None if not found
40
- """
41
- for path in DEFAULT_CONFIG_LOCATIONS:
42
- if path.exists():
43
- logger.debug(f"Found memory guardian config at: {path}")
44
- return path
45
-
46
- return None
47
-
48
-
49
- def load_yaml_config(config_path: Path) -> Optional[Dict[str, Any]]:
50
- """Load YAML configuration from file.
51
-
52
- Args:
53
- config_path: Path to YAML configuration file
54
-
55
- Returns:
56
- Dictionary of configuration data or None if loading failed
57
- """
58
- try:
59
- if not config_path.exists():
60
- logger.warning(f"Configuration file not found: {config_path}")
61
- return None
62
-
63
- with open(config_path, 'r') as f:
64
- config_data = yaml.safe_load(f)
65
-
66
- if not config_data:
67
- logger.warning(f"Empty configuration file: {config_path}")
68
- return {}
69
-
70
- logger.info(f"Loaded configuration from: {config_path}")
71
- return config_data
72
-
73
- except yaml.YAMLError as e:
74
- logger.error(f"Invalid YAML in configuration file: {e}")
75
- return None
76
- except Exception as e:
77
- logger.error(f"Failed to load configuration file: {e}")
78
- return None
79
-
80
-
81
- def create_config_from_yaml(yaml_data: Dict[str, Any]) -> MemoryGuardianConfig:
82
- """Create MemoryGuardianConfig from YAML data.
83
-
84
- Args:
85
- yaml_data: Dictionary of configuration data from YAML
86
-
87
- Returns:
88
- MemoryGuardianConfig instance
89
- """
90
- config = MemoryGuardianConfig()
91
-
92
- # General settings
93
- config.enabled = yaml_data.get('enabled', config.enabled)
94
- config.auto_start = yaml_data.get('auto_start', config.auto_start)
95
- config.persist_state = yaml_data.get('persist_state', config.persist_state)
96
- config.state_file = yaml_data.get('state_file', config.state_file)
97
-
98
- # Memory thresholds
99
- if 'thresholds' in yaml_data:
100
- thresholds = yaml_data['thresholds']
101
- config.thresholds = MemoryThresholds(
102
- warning=thresholds.get('warning', config.thresholds.warning),
103
- critical=thresholds.get('critical', config.thresholds.critical),
104
- emergency=thresholds.get('emergency', config.thresholds.emergency)
105
- )
106
-
107
- # Monitoring configuration
108
- if 'monitoring' in yaml_data:
109
- monitoring = yaml_data['monitoring']
110
- config.monitoring = MonitoringConfig(
111
- check_interval=monitoring.get('check_interval', config.monitoring.check_interval),
112
- check_interval_warning=monitoring.get('check_interval_warning', config.monitoring.check_interval_warning),
113
- check_interval_critical=monitoring.get('check_interval_critical', config.monitoring.check_interval_critical),
114
- log_memory_stats=monitoring.get('log_memory_stats', config.monitoring.log_memory_stats),
115
- log_interval=monitoring.get('log_interval', config.monitoring.log_interval)
116
- )
117
-
118
- # Restart policy
119
- if 'restart_policy' in yaml_data:
120
- policy = yaml_data['restart_policy']
121
- config.restart_policy = RestartPolicy(
122
- max_attempts=policy.get('max_attempts', config.restart_policy.max_attempts),
123
- attempt_window=policy.get('attempt_window', config.restart_policy.attempt_window),
124
- cooldown_base=policy.get('cooldown_base', config.restart_policy.cooldown_base),
125
- cooldown_multiplier=policy.get('cooldown_multiplier', config.restart_policy.cooldown_multiplier),
126
- cooldown_max=policy.get('cooldown_max', config.restart_policy.cooldown_max),
127
- graceful_timeout=policy.get('graceful_timeout', config.restart_policy.graceful_timeout),
128
- force_kill_timeout=policy.get('force_kill_timeout', config.restart_policy.force_kill_timeout)
129
- )
130
-
131
- # Process configuration
132
- if 'process' in yaml_data:
133
- process = yaml_data['process']
134
- config.process_command = process.get('command', config.process_command)
135
- config.process_args = process.get('args', config.process_args)
136
- config.process_env = process.get('env', config.process_env)
137
- config.working_directory = process.get('working_directory', config.working_directory)
138
-
139
- return config
140
-
141
-
142
- def load_config(config_path: Optional[Path] = None) -> Optional[MemoryGuardianConfig]:
143
- """Load memory guardian configuration from YAML file.
144
-
145
- Args:
146
- config_path: Optional path to configuration file.
147
- If not provided, searches standard locations.
148
-
149
- Returns:
150
- MemoryGuardianConfig instance or None if loading failed
151
- """
152
- # Find configuration file if not specified
153
- if config_path is None:
154
- config_path = find_config_file()
155
- if config_path is None:
156
- logger.debug("No memory guardian configuration file found")
157
- return None
158
-
159
- # Load YAML data
160
- yaml_data = load_yaml_config(config_path)
161
- if yaml_data is None:
162
- return None
163
-
164
- # Create configuration
165
- try:
166
- config = create_config_from_yaml(yaml_data)
167
-
168
- # Validate configuration
169
- issues = config.validate()
170
- if issues:
171
- for issue in issues:
172
- logger.warning(f"Configuration validation issue: {issue}")
173
-
174
- return config
175
-
176
- except Exception as e:
177
- logger.error(f"Failed to create configuration from YAML: {e}")
178
- return None
179
-
180
-
181
- def save_config(config: MemoryGuardianConfig, config_path: Optional[Path] = None) -> bool:
182
- """Save memory guardian configuration to YAML file.
183
-
184
- Args:
185
- config: MemoryGuardianConfig instance to save
186
- config_path: Optional path to save configuration.
187
- If not provided, uses default location.
188
-
189
- Returns:
190
- True if save successful, False otherwise
191
- """
192
- try:
193
- # Determine save path
194
- if config_path is None:
195
- config_path = Path.home() / ".claude-mpm" / "config" / "memory_guardian.yaml"
196
-
197
- # Ensure directory exists
198
- config_path.parent.mkdir(parents=True, exist_ok=True)
199
-
200
- # Convert configuration to dictionary
201
- config_dict = config.to_dict()
202
-
203
- # Write to file
204
- with open(config_path, 'w') as f:
205
- yaml.dump(config_dict, f, default_flow_style=False, sort_keys=False)
206
-
207
- logger.info(f"Saved configuration to: {config_path}")
208
- return True
209
-
210
- except Exception as e:
211
- logger.error(f"Failed to save configuration: {e}")
212
- return False
213
-
214
-
215
- def create_default_config_file(config_path: Optional[Path] = None) -> bool:
216
- """Create a default memory guardian configuration file.
217
-
218
- Args:
219
- config_path: Optional path for configuration file.
220
- If not provided, uses default location.
221
-
222
- Returns:
223
- True if file created successfully, False otherwise
224
- """
225
- try:
226
- # Determine save path
227
- if config_path is None:
228
- config_path = Path.home() / ".claude-mpm" / "config" / "memory_guardian.yaml"
229
-
230
- # Check if file already exists
231
- if config_path.exists():
232
- logger.warning(f"Configuration file already exists: {config_path}")
233
- return False
234
-
235
- # Create default configuration
236
- config = MemoryGuardianConfig()
237
-
238
- # Add helpful comments to YAML
239
- yaml_content = """# Memory Guardian Configuration
240
- # This file configures memory monitoring and automatic restart for Claude Code
241
-
242
- # Enable/disable memory monitoring
243
- enabled: true
244
-
245
- # Automatically start monitoring when service initializes
246
- auto_start: true
247
-
248
- # Preserve state across restarts
249
- persist_state: true
250
-
251
- # Path to state file for persistence
252
- state_file: ~/.claude-mpm/state/memory_guardian.json
253
-
254
- # Memory thresholds in MB
255
- thresholds:
256
- # Warning threshold - logs warnings
257
- warning: 14400 # 14GB
258
-
259
- # Critical threshold - triggers restart
260
- critical: 18000 # 18GB
261
-
262
- # Emergency threshold - immediate restart
263
- emergency: 21600 # 21GB
264
-
265
- # Monitoring configuration
266
- monitoring:
267
- # Default check interval in seconds
268
- check_interval: 30
269
-
270
- # Check interval when in warning state
271
- check_interval_warning: 15
272
-
273
- # Check interval when in critical state
274
- check_interval_critical: 5
275
-
276
- # Enable periodic memory statistics logging
277
- log_memory_stats: true
278
-
279
- # Statistics logging interval in seconds
280
- log_interval: 60
281
-
282
- # Restart policy configuration
283
- restart_policy:
284
- # Maximum restart attempts (0 = unlimited)
285
- max_attempts: 3
286
-
287
- # Time window for counting attempts (seconds)
288
- attempt_window: 3600 # 1 hour
289
-
290
- # Base cooldown between restarts (seconds)
291
- cooldown_base: 10
292
-
293
- # Cooldown multiplier for consecutive failures
294
- cooldown_multiplier: 2.0
295
-
296
- # Maximum cooldown period (seconds)
297
- cooldown_max: 300 # 5 minutes
298
-
299
- # Timeout for graceful shutdown (seconds)
300
- graceful_timeout: 30
301
-
302
- # Timeout for force kill if graceful fails (seconds)
303
- force_kill_timeout: 10
304
-
305
- # Process configuration (usually set by runner)
306
- process:
307
- # Command to execute (set by runner)
308
- command: ["claude"]
309
-
310
- # Additional arguments
311
- args: []
312
-
313
- # Environment variables
314
- env: {}
315
-
316
- # Working directory (defaults to current)
317
- working_directory: null
318
- """
319
-
320
- # Ensure directory exists
321
- config_path.parent.mkdir(parents=True, exist_ok=True)
322
-
323
- # Write configuration file
324
- with open(config_path, 'w') as f:
325
- f.write(yaml_content)
326
-
327
- logger.info(f"Created default configuration file: {config_path}")
328
- print(f"✓ Created memory guardian configuration at: {config_path}")
329
- print(" Edit this file to customize memory thresholds and policies")
330
-
331
- return True
332
-
333
- except Exception as e:
334
- logger.error(f"Failed to create default configuration file: {e}")
335
- return False