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,549 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Unified Path Management System for Claude MPM
4
+ ==============================================
5
+
6
+ This module consolidates all path management functionality from the duplicate modules:
7
+ - config/paths.py (ClaudeMPMPaths)
8
+ - utils/paths.py (get_path_manager())
9
+ - deployment_paths.py (get_path_manager())
10
+ - core/config_paths.py (get_path_manager())
11
+
12
+ Design Principles:
13
+ - Single source of truth for all path operations
14
+ - Consistent API across all path types
15
+ - Robust deployment scenario handling
16
+ - Efficient caching with cache invalidation
17
+ - Clear separation of concerns
18
+ - Backward compatibility during migration
19
+
20
+ Architecture:
21
+ - UnifiedPathManager: Main singleton class
22
+ - PathType enum: Categorizes different path types
23
+ - PathContext: Handles deployment context detection
24
+ - Cached properties with smart invalidation
25
+ """
26
+
27
+ import logging
28
+ import os
29
+ import sys
30
+ from enum import Enum
31
+ from functools import lru_cache
32
+ from pathlib import Path
33
+ from typing import Dict, List, Optional, Union
34
+
35
+ logger = logging.getLogger(__name__)
36
+
37
+
38
+ class PathType(Enum):
39
+ """Enumeration of different path types for categorization."""
40
+
41
+ PROJECT = "project"
42
+ FRAMEWORK = "framework"
43
+ USER = "user"
44
+ SYSTEM = "system"
45
+ CONFIG = "config"
46
+ AGENTS = "agents"
47
+ TEMPLATES = "templates"
48
+ SCRIPTS = "scripts"
49
+ STATIC = "static"
50
+ LOGS = "logs"
51
+ CACHE = "cache"
52
+
53
+
54
+ class DeploymentContext(Enum):
55
+ """Enumeration of deployment contexts."""
56
+
57
+ DEVELOPMENT = "development"
58
+ EDITABLE_INSTALL = "editable_install"
59
+ PIP_INSTALL = "pip_install"
60
+ PIPX_INSTALL = "pipx_install"
61
+ SYSTEM_PACKAGE = "system_package"
62
+
63
+
64
+ class PathContext:
65
+ """Handles deployment context detection and path resolution."""
66
+
67
+ @staticmethod
68
+ @lru_cache(maxsize=1)
69
+ def detect_deployment_context() -> DeploymentContext:
70
+ """Detect the current deployment context."""
71
+ try:
72
+ import claude_mpm
73
+
74
+ module_path = Path(claude_mpm.__file__).parent
75
+
76
+ # Check for development mode
77
+ if (module_path.parent / "src").exists():
78
+ return DeploymentContext.DEVELOPMENT
79
+
80
+ # Check for editable install
81
+ if (
82
+ "site-packages" in str(module_path)
83
+ and (module_path.parent.parent / "src").exists()
84
+ ):
85
+ return DeploymentContext.EDITABLE_INSTALL
86
+
87
+ # Check for pipx install
88
+ if "pipx" in str(module_path):
89
+ return DeploymentContext.PIPX_INSTALL
90
+
91
+ # Check for system package
92
+ if "dist-packages" in str(module_path):
93
+ return DeploymentContext.SYSTEM_PACKAGE
94
+
95
+ # Default to pip install
96
+ return DeploymentContext.PIP_INSTALL
97
+
98
+ except ImportError:
99
+ return DeploymentContext.DEVELOPMENT
100
+
101
+
102
+ class UnifiedPathManager:
103
+ """
104
+ Unified path management system that consolidates all path-related functionality.
105
+
106
+ This class provides a single, authoritative interface for all path operations
107
+ in Claude MPM, replacing the multiple duplicate path management modules.
108
+ """
109
+
110
+ _instance: Optional["UnifiedPathManager"] = None
111
+ _cache_invalidated: bool = False
112
+
113
+ # Configuration constants
114
+ CONFIG_DIR_NAME = ".claude-mpm"
115
+ LEGACY_CONFIG_DIR_NAME = ".claude-pm" # For migration support
116
+
117
+ def __new__(cls) -> "UnifiedPathManager":
118
+ """Singleton pattern to ensure single instance."""
119
+ if cls._instance is None:
120
+ cls._instance = super().__new__(cls)
121
+ cls._instance._initialized = False
122
+ return cls._instance
123
+
124
+ def __init__(self):
125
+ """Initialize the path manager."""
126
+ if self._initialized:
127
+ return
128
+
129
+ self._deployment_context = PathContext.detect_deployment_context()
130
+ self._project_markers = [
131
+ ".git",
132
+ "pyproject.toml",
133
+ "package.json",
134
+ "Cargo.toml",
135
+ "go.mod",
136
+ "pom.xml",
137
+ "build.gradle",
138
+ self.CONFIG_DIR_NAME,
139
+ ]
140
+ self._initialized = True
141
+
142
+ logger.debug(
143
+ f"UnifiedPathManager initialized with context: {self._deployment_context}"
144
+ )
145
+
146
+ # ========================================================================
147
+ # Core Path Resolution Methods
148
+ # ========================================================================
149
+
150
+ @property
151
+ @lru_cache(maxsize=1)
152
+ def framework_root(self) -> Path:
153
+ """Get the framework root directory."""
154
+ try:
155
+ import claude_mpm
156
+
157
+ module_path = Path(claude_mpm.__file__).parent
158
+
159
+ if self._deployment_context == DeploymentContext.DEVELOPMENT:
160
+ # Development: go up to project root
161
+ current = module_path
162
+ while current != current.parent:
163
+ if (current / "src" / "claude_mpm").exists():
164
+ return current
165
+ current = current.parent
166
+
167
+ # For installed packages, the module path is the framework root
168
+ return (
169
+ module_path.parent if module_path.name == "claude_mpm" else module_path
170
+ )
171
+
172
+ except ImportError:
173
+ # Fallback: search from current file location
174
+ current = Path(__file__).parent
175
+ while current != current.parent:
176
+ if (current / "src" / "claude_mpm").exists():
177
+ return current
178
+ current = current.parent
179
+
180
+ raise FileNotFoundError("Could not determine framework root")
181
+
182
+ @property
183
+ @lru_cache(maxsize=1)
184
+ def project_root(self) -> Path:
185
+ """Get the current project root directory."""
186
+ current = Path.cwd()
187
+ while current != current.parent:
188
+ for marker in self._project_markers:
189
+ if (current / marker).exists():
190
+ logger.debug(f"Found project root at {current} via {marker}")
191
+ return current
192
+ current = current.parent
193
+
194
+ # Fallback to current directory
195
+ logger.warning("Could not find project root, using current directory")
196
+ return Path.cwd()
197
+
198
+ @property
199
+ def package_root(self) -> Path:
200
+ """Get the claude_mpm package root directory."""
201
+ try:
202
+ import claude_mpm
203
+
204
+ return Path(claude_mpm.__file__).parent
205
+ except ImportError:
206
+ return self.framework_root / "src" / "claude_mpm"
207
+
208
+ # ========================================================================
209
+ # Configuration Paths
210
+ # ========================================================================
211
+
212
+ def get_config_dir(self, scope: str = "project") -> Path:
213
+ """Get configuration directory for specified scope."""
214
+ if scope == "user":
215
+ return Path.home() / self.CONFIG_DIR_NAME
216
+ elif scope == "project":
217
+ return self.project_root / self.CONFIG_DIR_NAME
218
+ elif scope == "framework":
219
+ return self.framework_root / self.CONFIG_DIR_NAME
220
+ else:
221
+ raise ValueError(
222
+ f"Invalid scope: {scope}. Must be 'user', 'project', or 'framework'"
223
+ )
224
+
225
+ def get_user_config_dir(self) -> Path:
226
+ """Get the user-level configuration directory."""
227
+ return Path.home() / self.CONFIG_DIR_NAME
228
+
229
+ def get_project_config_dir(self, project_root: Optional[Path] = None) -> Path:
230
+ """Get the project-level configuration directory."""
231
+ root = project_root or self.project_root
232
+ return root / self.CONFIG_DIR_NAME
233
+
234
+ # ========================================================================
235
+ # Agent Paths
236
+ # ========================================================================
237
+
238
+ def get_agents_dir(self, scope: str = "framework") -> Path:
239
+ """Get agents directory for specified scope."""
240
+ if scope == "user":
241
+ return self.get_user_config_dir() / "agents"
242
+ elif scope == "project":
243
+ return self.get_project_config_dir() / "agents"
244
+ elif scope == "framework":
245
+ if self._deployment_context == DeploymentContext.DEVELOPMENT:
246
+ return self.framework_root / "src" / "claude_mpm" / "agents"
247
+ else:
248
+ return self.package_root / "agents"
249
+ else:
250
+ raise ValueError(
251
+ f"Invalid scope: {scope}. Must be 'user', 'project', or 'framework'"
252
+ )
253
+
254
+ def get_user_agents_dir(self) -> Path:
255
+ """Get the user-level agents directory."""
256
+ return self.get_user_config_dir() / "agents"
257
+
258
+ def get_project_agents_dir(self, project_root: Optional[Path] = None) -> Path:
259
+ """Get the project-level agents directory."""
260
+ return self.get_project_config_dir(project_root) / "agents"
261
+
262
+ def get_system_agents_dir(self) -> Path:
263
+ """Get the system-level agents directory."""
264
+ return self.get_agents_dir("framework")
265
+
266
+ def get_templates_dir(self) -> Path:
267
+ """Get the agent templates directory."""
268
+ return self.get_agents_dir("framework") / "templates"
269
+
270
+ # ========================================================================
271
+ # Resource and Static Paths
272
+ # ========================================================================
273
+
274
+ def get_scripts_dir(self) -> Path:
275
+ """Get the scripts directory."""
276
+ if self._deployment_context == DeploymentContext.DEVELOPMENT:
277
+ return self.framework_root / "scripts"
278
+ else:
279
+ return self.package_root / "scripts"
280
+
281
+ def get_static_dir(self) -> Path:
282
+ """Get the static files directory."""
283
+ return self.package_root / "dashboard" / "static"
284
+
285
+ def get_templates_web_dir(self) -> Path:
286
+ """Get the web templates directory."""
287
+ return self.package_root / "dashboard" / "templates"
288
+
289
+ # ========================================================================
290
+ # Utility and Working Paths
291
+ # ========================================================================
292
+
293
+ def get_logs_dir(self, scope: str = "project") -> Path:
294
+ """Get logs directory for specified scope."""
295
+ base_dir = self.get_config_dir(scope)
296
+ return base_dir / "logs"
297
+
298
+ def get_cache_dir(self, scope: str = "user") -> Path:
299
+ """Get cache directory for specified scope."""
300
+ base_dir = self.get_config_dir(scope)
301
+ return base_dir / "cache"
302
+
303
+ def get_backups_dir(self, scope: str = "user") -> Path:
304
+ """Get backups directory for specified scope."""
305
+ base_dir = self.get_config_dir(scope)
306
+ return base_dir / "backups"
307
+
308
+ def get_memories_dir(self, scope: str = "project") -> Path:
309
+ """Get memories directory for specified scope."""
310
+ base_dir = self.get_config_dir(scope)
311
+ return base_dir / "memories"
312
+
313
+ # ========================================================================
314
+ # File Path Resolution
315
+ # ========================================================================
316
+
317
+ def get_resource_path(self, resource_type: str, filename: str) -> Path:
318
+ """Get path to a resource file."""
319
+ resource_dirs = {
320
+ "scripts": self.get_scripts_dir(),
321
+ "templates": self.get_templates_dir(),
322
+ "static": self.get_static_dir(),
323
+ "agents": self.get_agents_dir("framework"),
324
+ "web_templates": self.get_templates_web_dir(),
325
+ }
326
+
327
+ base_dir = resource_dirs.get(resource_type, self.package_root)
328
+ return base_dir / filename
329
+
330
+ def find_file_upwards(
331
+ self, filename: str, start_path: Optional[Path] = None
332
+ ) -> Optional[Path]:
333
+ """Search for a file by traversing up the directory tree."""
334
+ current = start_path or Path.cwd()
335
+
336
+ while current != current.parent:
337
+ candidate = current / filename
338
+ if candidate.exists():
339
+ return candidate
340
+ current = current.parent
341
+
342
+ return None
343
+
344
+ def get_package_resource_path(self, resource_path: str) -> Path:
345
+ """Get the path to a resource within the claude_mpm package."""
346
+ # Try using importlib.resources for proper package resource access
347
+ try:
348
+ from importlib import resources
349
+
350
+ parts = resource_path.split("/")
351
+ if len(parts) == 1:
352
+ with resources.path("claude_mpm", parts[0]) as p:
353
+ if p.exists():
354
+ return p
355
+ else:
356
+ # For nested paths, navigate step by step
357
+ package = "claude_mpm"
358
+ for part in parts[:-1]:
359
+ package = f"{package}.{part}"
360
+ with resources.path(package, parts[-1]) as p:
361
+ if p.exists():
362
+ return p
363
+ except (ImportError, ModuleNotFoundError, TypeError, AttributeError):
364
+ # Fall back to file system detection
365
+ pass
366
+
367
+ # Fallback: Use package root
368
+ resource = self.package_root / resource_path
369
+ if resource.exists():
370
+ return resource
371
+
372
+ raise FileNotFoundError(f"Resource not found: {resource_path}")
373
+
374
+ # ========================================================================
375
+ # Path Validation and Utilities
376
+ # ========================================================================
377
+
378
+ def ensure_directory(self, path: Path) -> Path:
379
+ """Ensure a directory exists, creating it if necessary."""
380
+ path.mkdir(parents=True, exist_ok=True)
381
+ return path
382
+
383
+ def validate_not_legacy(self, path: Path) -> bool:
384
+ """Check if a path contains the legacy configuration directory name."""
385
+ return self.LEGACY_CONFIG_DIR_NAME not in str(path)
386
+
387
+ def get_relative_to_root(
388
+ self, path: Union[str, Path], root_type: str = "project"
389
+ ) -> Path:
390
+ """Get a path relative to a specific root."""
391
+ if root_type == "project":
392
+ root = self.project_root
393
+ elif root_type == "framework":
394
+ root = self.framework_root
395
+ else:
396
+ raise ValueError(
397
+ f"Invalid root_type: {root_type}. Must be 'project' or 'framework'"
398
+ )
399
+
400
+ return root / path
401
+
402
+ def resolve_import_path(self, module_path: str) -> Path:
403
+ """Resolve a module import path to a file path."""
404
+ parts = module_path.split(".")
405
+ if parts[0] == "claude_mpm":
406
+ parts = parts[1:] # Remove package name
407
+
408
+ return self.package_root.joinpath(*parts).with_suffix(".py")
409
+
410
+ # ========================================================================
411
+ # Cache Management
412
+ # ========================================================================
413
+
414
+ def clear_cache(self):
415
+ """Clear all cached path lookups."""
416
+ # Clear lru_cache instances
417
+ try:
418
+ # Clear property caches if they exist
419
+ if hasattr(type(self).framework_root, "fget") and hasattr(
420
+ type(self).framework_root.fget, "cache_clear"
421
+ ):
422
+ type(self).framework_root.fget.cache_clear()
423
+ if hasattr(type(self).project_root, "fget") and hasattr(
424
+ type(self).project_root.fget, "cache_clear"
425
+ ):
426
+ type(self).project_root.fget.cache_clear()
427
+ except AttributeError:
428
+ # Properties might not have cache_clear if not using lru_cache
429
+ pass
430
+
431
+ # Clear static method cache
432
+ PathContext.detect_deployment_context.cache_clear()
433
+
434
+ logger.debug("Cleared all UnifiedPathManager caches")
435
+
436
+ def invalidate_cache(self):
437
+ """Mark cache as invalidated for next access."""
438
+ self._cache_invalidated = True
439
+ self.clear_cache()
440
+
441
+ # ========================================================================
442
+ # Legacy Compatibility Methods
443
+ # ========================================================================
444
+
445
+ def get_version(self) -> str:
446
+ """Get the project version."""
447
+ version_candidates = [
448
+ self.framework_root / "VERSION",
449
+ self.package_root / "VERSION",
450
+ self.project_root / "VERSION",
451
+ ]
452
+
453
+ for version_file in version_candidates:
454
+ if version_file.exists():
455
+ return version_file.read_text().strip()
456
+
457
+ # Fallback to package metadata
458
+ try:
459
+ import claude_mpm
460
+
461
+ return getattr(claude_mpm, "__version__", "unknown")
462
+ except (ImportError, AttributeError):
463
+ return "unknown"
464
+
465
+ def ensure_src_in_path(self):
466
+ """Ensure src directory is in Python path."""
467
+ src_dir = self.framework_root / "src"
468
+ if src_dir.exists() and str(src_dir) not in sys.path:
469
+ sys.path.insert(0, str(src_dir))
470
+
471
+
472
+ # ============================================================================
473
+ # Singleton Instance and Convenience Functions
474
+ # ============================================================================
475
+
476
+ # Global singleton instance
477
+ _path_manager: Optional[UnifiedPathManager] = None
478
+
479
+
480
+ def get_path_manager() -> UnifiedPathManager:
481
+ """Get the global UnifiedPathManager instance."""
482
+ global _path_manager
483
+ if _path_manager is None:
484
+ _path_manager = UnifiedPathManager()
485
+ return _path_manager
486
+
487
+
488
+ # Convenience functions for backward compatibility
489
+ def get_project_root() -> Path:
490
+ """Get the current project root directory."""
491
+ return get_path_manager().project_root
492
+
493
+
494
+ def get_framework_root() -> Path:
495
+ """Get the framework root directory."""
496
+ return get_path_manager().framework_root
497
+
498
+
499
+ def get_package_root() -> Path:
500
+ """Get the claude_mpm package root directory."""
501
+ return get_path_manager().package_root
502
+
503
+
504
+ def get_scripts_dir() -> Path:
505
+ """Get the scripts directory."""
506
+ return get_path_manager().get_scripts_dir()
507
+
508
+
509
+ def get_agents_dir() -> Path:
510
+ """Get the framework agents directory."""
511
+ return get_path_manager().get_agents_dir("framework")
512
+
513
+
514
+ def get_config_dir(scope: str = "project") -> Path:
515
+ """Get configuration directory for specified scope."""
516
+ return get_path_manager().get_config_dir(scope)
517
+
518
+
519
+ def find_file_upwards(
520
+ filename: str, start_path: Optional[Path] = None
521
+ ) -> Optional[Path]:
522
+ """Search for a file by traversing up the directory tree."""
523
+ return get_path_manager().find_file_upwards(filename, start_path)
524
+
525
+
526
+ def get_package_resource_path(resource_path: str) -> Path:
527
+ """Get the path to a resource within the claude_mpm package."""
528
+ return get_path_manager().get_package_resource_path(resource_path)
529
+
530
+
531
+ # ============================================================================
532
+ # Export All Public Symbols
533
+ # ============================================================================
534
+
535
+ __all__ = [
536
+ "UnifiedPathManager",
537
+ "PathType",
538
+ "DeploymentContext",
539
+ "PathContext",
540
+ "get_path_manager",
541
+ "get_project_root",
542
+ "get_framework_root",
543
+ "get_package_root",
544
+ "get_scripts_dir",
545
+ "get_agents_dir",
546
+ "get_config_dir",
547
+ "find_file_upwards",
548
+ "get_package_resource_path",
549
+ ]
@@ -10,4 +10,4 @@
10
10
  <p>Redirecting to Claude MPM Dashboard...</p>
11
11
  <p>If you are not redirected, <a href="/dashboard?autoconnect=true&port=8765">click here</a>.</p>
12
12
  </body>
13
- </html>
13
+ </html>
@@ -5,30 +5,64 @@ import os
5
5
  import webbrowser
6
6
  from pathlib import Path
7
7
 
8
+ try:
9
+ from ..services.port_manager import PortManager
10
+ except ImportError:
11
+ # Fallback for when running as standalone script
12
+ import sys
13
+
14
+ sys.path.insert(0, str(Path(__file__).parent.parent.parent))
15
+ from claude_mpm.services.port_manager import PortManager
16
+
17
+
18
+ def discover_socketio_port():
19
+ """Discover the port of the running SocketIO server, preferring 8765."""
20
+ try:
21
+ port_manager = PortManager()
22
+ instances = port_manager.list_active_instances()
23
+
24
+ if instances:
25
+ # First, check if port 8765 is being used
26
+ for instance in instances:
27
+ if instance.get("port") == 8765:
28
+ return 8765
29
+
30
+ # If 8765 is not available, return the first active instance port
31
+ return instances[0].get("port", 8765)
32
+ else:
33
+ print("⚠️ No active SocketIO instances found, using default port 8765")
34
+ return 8765
35
+ except Exception as e:
36
+ print(f"⚠️ Failed to discover SocketIO port: {e}")
37
+ print(" Using default port 8765")
38
+ return 8765
39
+
40
+
8
41
  def open_dashboard(port=8765, autoconnect=True):
9
42
  """Open the dashboard HTML file directly in the browser.
10
-
43
+
11
44
  Args:
12
- port: Socket.IO server port to connect to
45
+ port: Socket.IO server port to connect to (defaults to 8765, auto-discovers if needed)
13
46
  autoconnect: Whether to auto-connect on load
14
47
  """
15
- # Get the static index.html path (main entry point)
16
- dashboard_path = Path(__file__).parent / "templates" / "index.html"
17
-
18
- if not dashboard_path.exists():
19
- raise FileNotFoundError(f"Dashboard not found at {dashboard_path}")
20
-
21
- # Build URL with query parameters for Socket.IO connection
22
- dashboard_url = f"file://{dashboard_path.absolute()}?port={port}"
23
- if autoconnect:
24
- dashboard_url += "&autoconnect=true"
25
-
26
- print(f"🌐 Opening static dashboard: {dashboard_url}")
27
- print(f"📡 Dashboard will connect to Socket.IO server at localhost:{port}")
48
+ # If default port 8765 is specified, check if we need to auto-discover
49
+ if port == 8765:
50
+ discovered_port = discover_socketio_port()
51
+ if discovered_port != 8765:
52
+ print(
53
+ f"🔍 SocketIO server found on port {discovered_port} instead of default 8765"
54
+ )
55
+ port = discovered_port
56
+ # Build HTTP URL to connect to the SocketIO server's dashboard
57
+ dashboard_url = f"http://localhost:{port}"
58
+
59
+ print(f"🌐 Opening dashboard: {dashboard_url}")
60
+ print(f"📡 Dashboard served by Socket.IO server at localhost:{port}")
28
61
  webbrowser.open(dashboard_url)
29
-
62
+
30
63
  return dashboard_url
31
64
 
65
+
32
66
  if __name__ == "__main__":
33
67
  # Test opening the dashboard
34
- open_dashboard()
68
+ open_dashboard()