claude-mpm 3.9.9__py3-none-any.whl → 4.0.3__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 (411) 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 +155 -0
  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 +1 -1
  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 +90 -49
  31. claude_mpm/cli/__main__.py +3 -2
  32. claude_mpm/cli/commands/__init__.py +21 -18
  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 +143 -762
  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 +203 -81
  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 +305 -197
  50. claude_mpm/cli/parser.py +24 -1150
  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 +104 -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 +217 -0
  69. claude_mpm/config/paths.py +94 -208
  70. claude_mpm/config/socketio_config.py +84 -73
  71. claude_mpm/constants.py +36 -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/css/dashboard.css +27 -8
  113. claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
  114. claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
  115. claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
  116. claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
  117. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
  118. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
  119. claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
  120. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
  121. claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
  122. claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
  123. claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
  124. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
  125. claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
  126. claude_mpm/dashboard/static/dist/dashboard.js +2 -0
  127. claude_mpm/dashboard/static/dist/socket-client.js +2 -0
  128. claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
  129. claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
  130. claude_mpm/dashboard/static/js/components/event-viewer.js +74 -70
  131. claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
  132. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +106 -92
  133. claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
  134. claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
  135. claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
  136. claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
  137. claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
  138. claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
  139. claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
  140. claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
  141. claude_mpm/dashboard/static/js/dashboard.js +178 -453
  142. claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
  143. claude_mpm/dashboard/static/js/socket-client.js +120 -54
  144. claude_mpm/dashboard/templates/index.html +40 -50
  145. claude_mpm/experimental/cli_enhancements.py +60 -58
  146. claude_mpm/generators/__init__.py +1 -1
  147. claude_mpm/generators/agent_profile_generator.py +75 -65
  148. claude_mpm/hooks/__init__.py +1 -1
  149. claude_mpm/hooks/base_hook.py +33 -28
  150. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  151. claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
  152. claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
  153. claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
  154. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
  155. claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
  156. claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
  157. claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
  158. claude_mpm/hooks/memory_integration_hook.py +140 -100
  159. claude_mpm/hooks/tool_call_interceptor.py +89 -76
  160. claude_mpm/hooks/validation_hooks.py +57 -49
  161. claude_mpm/init.py +145 -121
  162. claude_mpm/models/__init__.py +9 -9
  163. claude_mpm/models/agent_definition.py +33 -23
  164. claude_mpm/models/agent_session.py +228 -200
  165. claude_mpm/scripts/__init__.py +1 -1
  166. claude_mpm/scripts/socketio_daemon.py +192 -75
  167. claude_mpm/scripts/socketio_server_manager.py +328 -0
  168. claude_mpm/scripts/start_activity_logging.py +25 -22
  169. claude_mpm/services/__init__.py +68 -43
  170. claude_mpm/services/agent_capabilities_service.py +271 -0
  171. claude_mpm/services/agents/__init__.py +23 -32
  172. claude_mpm/services/agents/deployment/__init__.py +3 -3
  173. claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
  174. claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
  175. claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
  176. claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
  177. claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
  178. claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
  179. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
  180. claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
  181. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
  182. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
  183. claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
  184. claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
  185. claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
  186. claude_mpm/services/agents/deployment/agent_validator.py +352 -0
  187. claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
  188. claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
  189. claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
  190. claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
  191. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  192. claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
  193. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  194. claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
  195. claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
  196. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  197. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  198. claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
  199. claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
  200. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  201. claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
  202. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  203. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  204. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  205. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  206. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
  207. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  208. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  209. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
  210. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
  211. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
  212. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
  213. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
  214. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  215. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
  216. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  217. claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
  218. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
  219. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  220. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  221. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  222. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  223. claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
  224. claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
  225. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  226. claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
  227. claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
  228. claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
  229. claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
  230. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  231. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  232. claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
  233. claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
  234. claude_mpm/services/agents/loading/__init__.py +2 -2
  235. claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
  236. claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
  237. claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
  238. claude_mpm/services/agents/management/__init__.py +2 -2
  239. claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
  240. claude_mpm/services/agents/management/agent_management_service.py +209 -156
  241. claude_mpm/services/agents/memory/__init__.py +9 -6
  242. claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
  243. claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
  244. claude_mpm/services/agents/memory/analyzer.py +430 -0
  245. claude_mpm/services/agents/memory/content_manager.py +376 -0
  246. claude_mpm/services/agents/memory/template_generator.py +468 -0
  247. claude_mpm/services/agents/registry/__init__.py +7 -10
  248. claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
  249. claude_mpm/services/agents/registry/modification_tracker.py +351 -285
  250. claude_mpm/services/async_session_logger.py +187 -153
  251. claude_mpm/services/claude_session_logger.py +87 -72
  252. claude_mpm/services/command_handler_service.py +217 -0
  253. claude_mpm/services/communication/__init__.py +3 -2
  254. claude_mpm/services/core/__init__.py +50 -97
  255. claude_mpm/services/core/base.py +60 -53
  256. claude_mpm/services/core/interfaces/__init__.py +188 -0
  257. claude_mpm/services/core/interfaces/agent.py +351 -0
  258. claude_mpm/services/core/interfaces/communication.py +343 -0
  259. claude_mpm/services/core/interfaces/infrastructure.py +413 -0
  260. claude_mpm/services/core/interfaces/service.py +434 -0
  261. claude_mpm/services/core/interfaces.py +19 -944
  262. claude_mpm/services/event_aggregator.py +208 -170
  263. claude_mpm/services/exceptions.py +387 -308
  264. claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
  265. claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
  266. claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
  267. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
  268. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
  269. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
  270. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
  271. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
  272. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  273. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  274. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  275. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  276. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
  277. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  278. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  279. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
  280. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
  281. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  282. claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
  283. claude_mpm/services/hook_service.py +106 -114
  284. claude_mpm/services/infrastructure/__init__.py +7 -5
  285. claude_mpm/services/infrastructure/context_preservation.py +571 -0
  286. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  287. claude_mpm/services/infrastructure/logging.py +83 -76
  288. claude_mpm/services/infrastructure/monitoring.py +547 -404
  289. claude_mpm/services/mcp_gateway/__init__.py +40 -23
  290. claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
  291. claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
  292. claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
  293. claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
  294. claude_mpm/services/mcp_gateway/core/__init__.py +14 -21
  295. claude_mpm/services/mcp_gateway/core/base.py +80 -67
  296. claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
  297. claude_mpm/services/mcp_gateway/core/interfaces.py +97 -93
  298. claude_mpm/services/mcp_gateway/main.py +307 -127
  299. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  300. claude_mpm/services/mcp_gateway/registry/service_registry.py +100 -101
  301. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  302. claude_mpm/services/mcp_gateway/server/__init__.py +4 -4
  303. claude_mpm/services/mcp_gateway/server/{mcp_server.py → mcp_gateway.py} +149 -153
  304. claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
  305. claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
  306. claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
  307. claude_mpm/services/mcp_gateway/tools/base_adapter.py +110 -121
  308. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
  309. claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
  310. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
  311. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
  312. claude_mpm/services/memory/__init__.py +2 -2
  313. claude_mpm/services/memory/builder.py +451 -362
  314. claude_mpm/services/memory/cache/__init__.py +2 -2
  315. claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
  316. claude_mpm/services/memory/cache/simple_cache.py +107 -93
  317. claude_mpm/services/memory/indexed_memory.py +195 -193
  318. claude_mpm/services/memory/optimizer.py +267 -234
  319. claude_mpm/services/memory/router.py +571 -263
  320. claude_mpm/services/memory_hook_service.py +237 -0
  321. claude_mpm/services/port_manager.py +223 -0
  322. claude_mpm/services/project/__init__.py +3 -3
  323. claude_mpm/services/project/analyzer.py +451 -305
  324. claude_mpm/services/project/registry.py +262 -240
  325. claude_mpm/services/recovery_manager.py +287 -231
  326. claude_mpm/services/response_tracker.py +87 -67
  327. claude_mpm/services/runner_configuration_service.py +587 -0
  328. claude_mpm/services/session_management_service.py +304 -0
  329. claude_mpm/services/socketio/__init__.py +4 -4
  330. claude_mpm/services/socketio/client_proxy.py +174 -0
  331. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  332. claude_mpm/services/socketio/handlers/base.py +44 -30
  333. claude_mpm/services/socketio/handlers/connection.py +145 -65
  334. claude_mpm/services/socketio/handlers/file.py +123 -108
  335. claude_mpm/services/socketio/handlers/git.py +607 -373
  336. claude_mpm/services/socketio/handlers/hook.py +170 -0
  337. claude_mpm/services/socketio/handlers/memory.py +4 -4
  338. claude_mpm/services/socketio/handlers/project.py +4 -4
  339. claude_mpm/services/socketio/handlers/registry.py +53 -38
  340. claude_mpm/services/socketio/server/__init__.py +18 -0
  341. claude_mpm/services/socketio/server/broadcaster.py +252 -0
  342. claude_mpm/services/socketio/server/core.py +399 -0
  343. claude_mpm/services/socketio/server/main.py +323 -0
  344. claude_mpm/services/socketio_client_manager.py +160 -133
  345. claude_mpm/services/socketio_server.py +36 -1885
  346. claude_mpm/services/subprocess_launcher_service.py +316 -0
  347. claude_mpm/services/system_instructions_service.py +258 -0
  348. claude_mpm/services/ticket_manager.py +20 -534
  349. claude_mpm/services/utility_service.py +285 -0
  350. claude_mpm/services/version_control/__init__.py +18 -21
  351. claude_mpm/services/version_control/branch_strategy.py +20 -10
  352. claude_mpm/services/version_control/conflict_resolution.py +37 -13
  353. claude_mpm/services/version_control/git_operations.py +52 -21
  354. claude_mpm/services/version_control/semantic_versioning.py +92 -53
  355. claude_mpm/services/version_control/version_parser.py +145 -125
  356. claude_mpm/services/version_service.py +270 -0
  357. claude_mpm/storage/__init__.py +9 -0
  358. claude_mpm/storage/state_storage.py +552 -0
  359. claude_mpm/ticket_wrapper.py +2 -2
  360. claude_mpm/utils/__init__.py +2 -2
  361. claude_mpm/utils/agent_dependency_loader.py +453 -243
  362. claude_mpm/utils/config_manager.py +157 -118
  363. claude_mpm/utils/console.py +1 -1
  364. claude_mpm/utils/dependency_cache.py +102 -107
  365. claude_mpm/utils/dependency_manager.py +52 -47
  366. claude_mpm/utils/dependency_strategies.py +131 -96
  367. claude_mpm/utils/environment_context.py +110 -102
  368. claude_mpm/utils/error_handler.py +75 -55
  369. claude_mpm/utils/file_utils.py +80 -67
  370. claude_mpm/utils/framework_detection.py +12 -11
  371. claude_mpm/utils/import_migration_example.py +12 -60
  372. claude_mpm/utils/imports.py +48 -45
  373. claude_mpm/utils/path_operations.py +100 -93
  374. claude_mpm/utils/robust_installer.py +172 -164
  375. claude_mpm/utils/session_logging.py +30 -23
  376. claude_mpm/utils/subprocess_utils.py +99 -61
  377. claude_mpm/validation/__init__.py +1 -1
  378. claude_mpm/validation/agent_validator.py +151 -111
  379. claude_mpm/validation/frontmatter_validator.py +92 -71
  380. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/METADATA +51 -2
  381. claude_mpm-4.0.3.dist-info/RECORD +402 -0
  382. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/entry_points.txt +1 -0
  383. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/licenses/LICENSE +1 -1
  384. claude_mpm/config/memory_guardian_config.py +0 -325
  385. claude_mpm/core/config_paths.py +0 -150
  386. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  387. claude_mpm/deployment_paths.py +0 -261
  388. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  389. claude_mpm/models/state_models.py +0 -433
  390. claude_mpm/services/agent/__init__.py +0 -24
  391. claude_mpm/services/agent/deployment.py +0 -2548
  392. claude_mpm/services/agent/management.py +0 -598
  393. claude_mpm/services/agent/registry.py +0 -813
  394. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  395. claude_mpm/services/communication/socketio.py +0 -1935
  396. claude_mpm/services/communication/websocket.py +0 -479
  397. claude_mpm/services/framework_claude_md_generator.py +0 -624
  398. claude_mpm/services/health_monitor.py +0 -893
  399. claude_mpm/services/infrastructure/memory_guardian.py +0 -770
  400. claude_mpm/services/mcp_gateway/server/mcp_server_simple.py +0 -444
  401. claude_mpm/services/optimized_hook_service.py +0 -542
  402. claude_mpm/services/project_analyzer.py +0 -864
  403. claude_mpm/services/project_registry.py +0 -608
  404. claude_mpm/services/standalone_socketio_server.py +0 -1300
  405. claude_mpm/services/ticket_manager_di.py +0 -318
  406. claude_mpm/services/ticketing_service_original.py +0 -510
  407. claude_mpm/utils/paths.py +0 -395
  408. claude_mpm/utils/platform_memory.py +0 -524
  409. claude_mpm-3.9.9.dist-info/RECORD +0 -293
  410. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/WHEEL +0 -0
  411. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,552 @@
1
+ from pathlib import Path
2
+
3
+ """State Storage module for reliable state persistence.
4
+
5
+ This module provides atomic file operations and various serialization
6
+ formats for state data storage.
7
+
8
+ Design Principles:
9
+ - Atomic file operations (write-to-temp-then-rename)
10
+ - Multiple serialization formats (JSON, pickle, compressed)
11
+ - File locking for concurrent access safety
12
+ - Corruption detection and recovery
13
+ """
14
+
15
+ import fcntl
16
+ import gzip
17
+ import hashlib
18
+ import json
19
+ import logging
20
+ import os
21
+ import pickle
22
+ import platform
23
+ import shutil
24
+ import tempfile
25
+ import time
26
+ from contextlib import contextmanager
27
+ from datetime import datetime
28
+ from typing import Any, BinaryIO, Dict, Optional, TextIO, Union
29
+
30
+
31
+ class StateStorage:
32
+ """Reliable state storage with atomic operations."""
33
+
34
+ def __init__(self, storage_dir: Optional[Path] = None):
35
+ """Initialize State Storage.
36
+
37
+ Args:
38
+ storage_dir: Directory for state storage (default: ~/.claude-mpm/storage)
39
+ """
40
+ self.storage_dir = storage_dir or Path.home() / ".claude-mpm" / "storage"
41
+ self.storage_dir.mkdir(parents=True, exist_ok=True)
42
+
43
+ # Logging
44
+ self.logger = logging.getLogger(__name__)
45
+
46
+ # File locking support (Unix-like systems)
47
+ self.supports_locking = platform.system() != "Windows"
48
+
49
+ # Statistics
50
+ self.write_count = 0
51
+ self.read_count = 0
52
+ self.error_count = 0
53
+
54
+ def write_json(
55
+ self,
56
+ data: Dict[str, Any],
57
+ file_path: Union[str, Path],
58
+ compress: bool = False,
59
+ atomic: bool = True,
60
+ ) -> bool:
61
+ """Write data to JSON file atomically.
62
+
63
+ Args:
64
+ data: Data to serialize
65
+ file_path: Target file path
66
+ compress: Whether to compress with gzip
67
+ atomic: Whether to use atomic write
68
+
69
+ Returns:
70
+ True if write successful
71
+ """
72
+ try:
73
+ file_path = Path(file_path)
74
+
75
+ if atomic:
76
+ return self._atomic_write(
77
+ file_path, data, serializer="json", compress=compress
78
+ )
79
+ else:
80
+ # Direct write (not atomic)
81
+ if compress:
82
+ with gzip.open(file_path, "wt", encoding="utf-8") as f:
83
+ json.dump(data, f, indent=2, default=str)
84
+ else:
85
+ with open(file_path, "w") as f:
86
+ json.dump(data, f, indent=2, default=str)
87
+
88
+ self.write_count += 1
89
+ return True
90
+
91
+ except Exception as e:
92
+ self.logger.error(f"Failed to write JSON to {file_path}: {e}")
93
+ self.error_count += 1
94
+ return False
95
+
96
+ def read_json(
97
+ self, file_path: Union[str, Path], compressed: Optional[bool] = None
98
+ ) -> Optional[Dict[str, Any]]:
99
+ """Read data from JSON file.
100
+
101
+ Args:
102
+ file_path: Source file path
103
+ compressed: Whether file is compressed (auto-detect if None)
104
+
105
+ Returns:
106
+ Deserialized data or None if read failed
107
+ """
108
+ try:
109
+ file_path = Path(file_path)
110
+
111
+ if not file_path.exists():
112
+ self.logger.debug(f"File not found: {file_path}")
113
+ return None
114
+
115
+ # Auto-detect compression
116
+ if compressed is None:
117
+ compressed = file_path.suffix == ".gz"
118
+
119
+ with self._file_lock(file_path, "r"):
120
+ if compressed:
121
+ with gzip.open(file_path, "rt", encoding="utf-8") as f:
122
+ data = json.load(f)
123
+ else:
124
+ with open(file_path, "r") as f:
125
+ data = json.load(f)
126
+
127
+ self.read_count += 1
128
+ return data
129
+
130
+ except Exception as e:
131
+ self.logger.error(f"Failed to read JSON from {file_path}: {e}")
132
+ self.error_count += 1
133
+ return None
134
+
135
+ def write_pickle(
136
+ self,
137
+ data: Any,
138
+ file_path: Union[str, Path],
139
+ compress: bool = False,
140
+ atomic: bool = True,
141
+ ) -> bool:
142
+ """Write data to pickle file atomically.
143
+
144
+ Args:
145
+ data: Data to serialize
146
+ file_path: Target file path
147
+ compress: Whether to compress with gzip
148
+ atomic: Whether to use atomic write
149
+
150
+ Returns:
151
+ True if write successful
152
+ """
153
+ try:
154
+ file_path = Path(file_path)
155
+
156
+ if atomic:
157
+ return self._atomic_write(
158
+ file_path, data, serializer="pickle", compress=compress
159
+ )
160
+ else:
161
+ # Direct write (not atomic)
162
+ if compress:
163
+ with gzip.open(file_path, "wb") as f:
164
+ pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
165
+ else:
166
+ with open(file_path, "wb") as f:
167
+ pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
168
+
169
+ self.write_count += 1
170
+ return True
171
+
172
+ except Exception as e:
173
+ self.logger.error(f"Failed to write pickle to {file_path}: {e}")
174
+ self.error_count += 1
175
+ return False
176
+
177
+ def read_pickle(
178
+ self, file_path: Union[str, Path], compressed: Optional[bool] = None
179
+ ) -> Optional[Any]:
180
+ """Read data from pickle file.
181
+
182
+ Args:
183
+ file_path: Source file path
184
+ compressed: Whether file is compressed (auto-detect if None)
185
+
186
+ Returns:
187
+ Deserialized data or None if read failed
188
+ """
189
+ try:
190
+ file_path = Path(file_path)
191
+
192
+ if not file_path.exists():
193
+ self.logger.debug(f"File not found: {file_path}")
194
+ return None
195
+
196
+ # Auto-detect compression
197
+ if compressed is None:
198
+ compressed = file_path.suffix == ".gz"
199
+
200
+ with self._file_lock(file_path, "rb"):
201
+ if compressed:
202
+ with gzip.open(file_path, "rb") as f:
203
+ data = pickle.load(f)
204
+ else:
205
+ with open(file_path, "rb") as f:
206
+ data = pickle.load(f)
207
+
208
+ self.read_count += 1
209
+ return data
210
+
211
+ except Exception as e:
212
+ self.logger.error(f"Failed to read pickle from {file_path}: {e}")
213
+ self.error_count += 1
214
+ return None
215
+
216
+ def _atomic_write(
217
+ self,
218
+ file_path: Path,
219
+ data: Any,
220
+ serializer: str = "json",
221
+ compress: bool = False,
222
+ ) -> bool:
223
+ """Perform atomic write operation.
224
+
225
+ Args:
226
+ file_path: Target file path
227
+ data: Data to write
228
+ serializer: Serialization format ('json' or 'pickle')
229
+ compress: Whether to compress
230
+
231
+ Returns:
232
+ True if write successful
233
+ """
234
+ try:
235
+ # Ensure parent directory exists
236
+ file_path.parent.mkdir(parents=True, exist_ok=True)
237
+
238
+ # Create temporary file
239
+ temp_fd, temp_path = tempfile.mkstemp(
240
+ dir=file_path.parent, prefix=f".{file_path.stem}_", suffix=".tmp"
241
+ )
242
+
243
+ try:
244
+ # Write to temporary file
245
+ if serializer == "json":
246
+ if compress:
247
+ with gzip.open(temp_path, "wt", encoding="utf-8") as f:
248
+ json.dump(data, f, indent=2, default=str)
249
+ else:
250
+ with os.fdopen(temp_fd, "w") as f:
251
+ json.dump(data, f, indent=2, default=str)
252
+ elif serializer == "pickle":
253
+ if compress:
254
+ with gzip.open(temp_path, "wb") as f:
255
+ pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
256
+ else:
257
+ with os.fdopen(temp_fd, "wb") as f:
258
+ pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
259
+ else:
260
+ raise ValueError(f"Unknown serializer: {serializer}")
261
+
262
+ # Add checksum for integrity verification
263
+ self._add_checksum(temp_path)
264
+
265
+ # Atomic rename
266
+ Path(temp_path).replace(file_path)
267
+
268
+ self.write_count += 1
269
+ self.logger.debug(f"Atomic write successful: {file_path}")
270
+ return True
271
+
272
+ finally:
273
+ # Clean up temp file if it still exists
274
+ if Path(temp_path).exists():
275
+ os.unlink(temp_path)
276
+
277
+ except Exception as e:
278
+ self.logger.error(f"Atomic write failed for {file_path}: {e}")
279
+ self.error_count += 1
280
+ return False
281
+
282
+ @contextmanager
283
+ def _file_lock(self, file_path: Path, mode: str):
284
+ """Context manager for file locking.
285
+
286
+ Args:
287
+ file_path: File to lock
288
+ mode: File open mode
289
+
290
+ Yields:
291
+ Locked file handle
292
+ """
293
+ if not self.supports_locking:
294
+ # No locking on Windows
295
+ with open(file_path, mode) as f:
296
+ yield f
297
+ return
298
+
299
+ # Unix-like systems with fcntl
300
+ f = None
301
+ try:
302
+ f = open(file_path, mode)
303
+
304
+ # Try to acquire lock (non-blocking)
305
+ max_attempts = 50
306
+ for attempt in range(max_attempts):
307
+ try:
308
+ fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
309
+ break
310
+ except IOError:
311
+ if attempt == max_attempts - 1:
312
+ raise
313
+ time.sleep(0.1)
314
+
315
+ yield f
316
+
317
+ finally:
318
+ if f:
319
+ try:
320
+ fcntl.flock(f.fileno(), fcntl.LOCK_UN)
321
+ except:
322
+ pass
323
+ f.close()
324
+
325
+ def _add_checksum(self, file_path: Union[str, Path]) -> None:
326
+ """Add checksum to file for integrity verification.
327
+
328
+ Args:
329
+ file_path: File to add checksum to
330
+ """
331
+ try:
332
+ file_path = Path(file_path)
333
+
334
+ # Calculate checksum
335
+ hasher = hashlib.sha256()
336
+ with open(file_path, "rb") as f:
337
+ for chunk in iter(lambda: f.read(4096), b""):
338
+ hasher.update(chunk)
339
+
340
+ checksum = hasher.hexdigest()
341
+
342
+ # Write checksum file
343
+ checksum_path = file_path.with_suffix(file_path.suffix + ".sha256")
344
+ with open(checksum_path, "w") as f:
345
+ f.write(checksum)
346
+
347
+ except Exception as e:
348
+ self.logger.warning(f"Could not add checksum: {e}")
349
+
350
+ def verify_checksum(self, file_path: Union[str, Path]) -> bool:
351
+ """Verify file checksum for integrity.
352
+
353
+ Args:
354
+ file_path: File to verify
355
+
356
+ Returns:
357
+ True if checksum valid or not present
358
+ """
359
+ try:
360
+ file_path = Path(file_path)
361
+ checksum_path = file_path.with_suffix(file_path.suffix + ".sha256")
362
+
363
+ if not checksum_path.exists():
364
+ return True # No checksum to verify
365
+
366
+ # Read expected checksum
367
+ with open(checksum_path, "r") as f:
368
+ expected = f.read().strip()
369
+
370
+ # Calculate actual checksum
371
+ hasher = hashlib.sha256()
372
+ with open(file_path, "rb") as f:
373
+ for chunk in iter(lambda: f.read(4096), b""):
374
+ hasher.update(chunk)
375
+
376
+ actual = hasher.hexdigest()
377
+
378
+ if actual != expected:
379
+ self.logger.error(f"Checksum mismatch for {file_path}")
380
+ return False
381
+
382
+ return True
383
+
384
+ except Exception as e:
385
+ self.logger.warning(f"Could not verify checksum: {e}")
386
+ return True # Assume valid if can't verify
387
+
388
+ def cleanup_temp_files(self) -> int:
389
+ """Clean up temporary files in storage directory.
390
+
391
+ Returns:
392
+ Number of files cleaned up
393
+ """
394
+ try:
395
+ cleaned = 0
396
+
397
+ # Find temp files
398
+ for temp_file in self.storage_dir.glob(".*_*.tmp"):
399
+ try:
400
+ # Check if file is old (> 1 hour)
401
+ age = time.time() - temp_file.stat().st_mtime
402
+ if age > 3600:
403
+ temp_file.unlink()
404
+ cleaned += 1
405
+ self.logger.debug(f"Cleaned up temp file: {temp_file}")
406
+ except:
407
+ pass
408
+
409
+ # Clean up orphaned checksum files
410
+ for checksum_file in self.storage_dir.glob("*.sha256"):
411
+ data_file = checksum_file.with_suffix("")
412
+ if not data_file.exists():
413
+ checksum_file.unlink()
414
+ cleaned += 1
415
+
416
+ if cleaned > 0:
417
+ self.logger.info(f"Cleaned up {cleaned} temporary files")
418
+
419
+ return cleaned
420
+
421
+ except Exception as e:
422
+ self.logger.error(f"Error cleaning up temp files: {e}")
423
+ return 0
424
+
425
+ def get_storage_info(self) -> Dict[str, Any]:
426
+ """Get storage statistics and information.
427
+
428
+ Returns:
429
+ Dictionary containing storage info
430
+ """
431
+ try:
432
+ # Calculate storage size
433
+ total_size = 0
434
+ file_count = 0
435
+
436
+ for file_path in self.storage_dir.rglob("*"):
437
+ if file_path.is_file():
438
+ total_size += file_path.stat().st_size
439
+ file_count += 1
440
+
441
+ # Find temp files
442
+ temp_files = list(self.storage_dir.glob(".*_*.tmp"))
443
+
444
+ return {
445
+ "storage_directory": str(self.storage_dir),
446
+ "total_files": file_count,
447
+ "total_size_mb": round(total_size / (1024 * 1024), 2),
448
+ "temp_files": len(temp_files),
449
+ "write_count": self.write_count,
450
+ "read_count": self.read_count,
451
+ "error_count": self.error_count,
452
+ "supports_locking": self.supports_locking,
453
+ }
454
+
455
+ except Exception as e:
456
+ self.logger.error(f"Error getting storage info: {e}")
457
+ return {"storage_directory": str(self.storage_dir), "error": str(e)}
458
+
459
+
460
+ class StateCache:
461
+ """In-memory cache for frequently accessed state data."""
462
+
463
+ def __init__(self, max_size: int = 100, ttl_seconds: int = 300):
464
+ """Initialize State Cache.
465
+
466
+ Args:
467
+ max_size: Maximum number of cached items
468
+ ttl_seconds: Time-to-live for cached items
469
+ """
470
+ self.max_size = max_size
471
+ self.ttl_seconds = ttl_seconds
472
+ self.cache: Dict[str, Tuple[Any, float]] = {}
473
+ self.access_count: Dict[str, int] = {}
474
+
475
+ # Statistics
476
+ self.hits = 0
477
+ self.misses = 0
478
+
479
+ def get(self, key: str) -> Optional[Any]:
480
+ """Get item from cache.
481
+
482
+ Args:
483
+ key: Cache key
484
+
485
+ Returns:
486
+ Cached value or None if not found/expired
487
+ """
488
+ if key not in self.cache:
489
+ self.misses += 1
490
+ return None
491
+
492
+ value, timestamp = self.cache[key]
493
+
494
+ # Check TTL
495
+ if time.time() - timestamp > self.ttl_seconds:
496
+ del self.cache[key]
497
+ del self.access_count[key]
498
+ self.misses += 1
499
+ return None
500
+
501
+ self.hits += 1
502
+ self.access_count[key] = self.access_count.get(key, 0) + 1
503
+ return value
504
+
505
+ def set(self, key: str, value: Any) -> None:
506
+ """Set item in cache.
507
+
508
+ Args:
509
+ key: Cache key
510
+ value: Value to cache
511
+ """
512
+ # Evict if at capacity
513
+ if len(self.cache) >= self.max_size and key not in self.cache:
514
+ self._evict_lru()
515
+
516
+ self.cache[key] = (value, time.time())
517
+ self.access_count[key] = 0
518
+
519
+ def _evict_lru(self) -> None:
520
+ """Evict least recently used item."""
521
+ if not self.cache:
522
+ return
523
+
524
+ # Find LRU item
525
+ lru_key = min(self.access_count.keys(), key=lambda k: self.access_count[k])
526
+
527
+ del self.cache[lru_key]
528
+ del self.access_count[lru_key]
529
+
530
+ def clear(self) -> None:
531
+ """Clear all cached items."""
532
+ self.cache.clear()
533
+ self.access_count.clear()
534
+
535
+ def get_stats(self) -> Dict[str, Any]:
536
+ """Get cache statistics.
537
+
538
+ Returns:
539
+ Dictionary containing cache stats
540
+ """
541
+ total_requests = self.hits + self.misses
542
+ hit_rate = (self.hits / total_requests * 100) if total_requests > 0 else 0
543
+
544
+ return {
545
+ "size": len(self.cache),
546
+ "max_size": self.max_size,
547
+ "ttl_seconds": self.ttl_seconds,
548
+ "hits": self.hits,
549
+ "misses": self.misses,
550
+ "hit_rate": round(hit_rate, 2),
551
+ "total_requests": total_requests,
552
+ }
@@ -7,7 +7,6 @@ that was moved to the scripts directory.
7
7
  """
8
8
 
9
9
  import sys
10
- import os
11
10
  from pathlib import Path
12
11
 
13
12
  # Add scripts directory to path so we can import the ticket module
@@ -20,10 +19,11 @@ try:
20
19
  except ImportError:
21
20
  # Fallback if direct import fails
22
21
  import importlib.util
22
+
23
23
  ticket_path = scripts_dir / "ticket.py"
24
24
  spec = importlib.util.spec_from_file_location("ticket", ticket_path)
25
25
  ticket_module = importlib.util.module_from_spec(spec)
26
26
  spec.loader.exec_module(ticket_module)
27
27
  main = ticket_module.main
28
28
 
29
- __all__ = ["main"]
29
+ __all__ = ["main"]
@@ -6,11 +6,11 @@ __all__ = [
6
6
  "setup_logging",
7
7
  "safe_import",
8
8
  "safe_import_multiple",
9
- "PathResolver",
9
+ "get_path_manager()",
10
10
  "get_framework_root",
11
11
  "get_project_root",
12
12
  "find_file_upwards",
13
13
  "ConfigurationManager",
14
14
  "load_config",
15
15
  "save_config",
16
- ]
16
+ ]