claude-mpm 4.1.1__py3-none-any.whl → 4.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (357) hide show
  1. claude_mpm/BUILD_NUMBER +1 -1
  2. claude_mpm/VERSION +1 -1
  3. claude_mpm/__main__.py +1 -1
  4. claude_mpm/agents/BASE_PM.md +74 -46
  5. claude_mpm/agents/INSTRUCTIONS.md +11 -153
  6. claude_mpm/agents/WORKFLOW.md +61 -321
  7. claude_mpm/agents/__init__.py +11 -11
  8. claude_mpm/agents/agent_loader.py +23 -20
  9. claude_mpm/agents/agent_loader_integration.py +1 -1
  10. claude_mpm/agents/agents_metadata.py +27 -0
  11. claude_mpm/agents/async_agent_loader.py +5 -8
  12. claude_mpm/agents/base_agent_loader.py +36 -25
  13. claude_mpm/agents/frontmatter_validator.py +6 -6
  14. claude_mpm/agents/schema/agent_schema.json +1 -1
  15. claude_mpm/agents/system_agent_config.py +9 -9
  16. claude_mpm/agents/templates/api_qa.json +47 -2
  17. claude_mpm/agents/templates/imagemagick.json +256 -0
  18. claude_mpm/agents/templates/qa.json +41 -2
  19. claude_mpm/agents/templates/ticketing.json +5 -5
  20. claude_mpm/agents/templates/web_qa.json +50 -2
  21. claude_mpm/cli/__init__.py +51 -46
  22. claude_mpm/cli/__main__.py +1 -1
  23. claude_mpm/cli/commands/__init__.py +10 -12
  24. claude_mpm/cli/commands/agent_manager.py +186 -181
  25. claude_mpm/cli/commands/agents.py +271 -268
  26. claude_mpm/cli/commands/aggregate.py +30 -29
  27. claude_mpm/cli/commands/cleanup.py +50 -44
  28. claude_mpm/cli/commands/cleanup_orphaned_agents.py +25 -25
  29. claude_mpm/cli/commands/config.py +162 -127
  30. claude_mpm/cli/commands/doctor.py +52 -62
  31. claude_mpm/cli/commands/info.py +37 -25
  32. claude_mpm/cli/commands/mcp.py +3 -7
  33. claude_mpm/cli/commands/mcp_command_router.py +14 -18
  34. claude_mpm/cli/commands/mcp_install_commands.py +28 -23
  35. claude_mpm/cli/commands/mcp_pipx_config.py +58 -49
  36. claude_mpm/cli/commands/mcp_server_commands.py +23 -17
  37. claude_mpm/cli/commands/memory.py +192 -141
  38. claude_mpm/cli/commands/monitor.py +117 -88
  39. claude_mpm/cli/commands/run.py +120 -84
  40. claude_mpm/cli/commands/run_config_checker.py +4 -5
  41. claude_mpm/cli/commands/socketio_monitor.py +17 -19
  42. claude_mpm/cli/commands/tickets.py +92 -92
  43. claude_mpm/cli/parser.py +1 -5
  44. claude_mpm/cli/parsers/__init__.py +1 -1
  45. claude_mpm/cli/parsers/agent_manager_parser.py +50 -98
  46. claude_mpm/cli/parsers/agents_parser.py +2 -3
  47. claude_mpm/cli/parsers/base_parser.py +7 -5
  48. claude_mpm/cli/parsers/mcp_parser.py +4 -2
  49. claude_mpm/cli/parsers/monitor_parser.py +26 -18
  50. claude_mpm/cli/shared/__init__.py +10 -10
  51. claude_mpm/cli/shared/argument_patterns.py +57 -71
  52. claude_mpm/cli/shared/base_command.py +61 -53
  53. claude_mpm/cli/shared/error_handling.py +62 -58
  54. claude_mpm/cli/shared/output_formatters.py +78 -77
  55. claude_mpm/cli/startup_logging.py +204 -172
  56. claude_mpm/cli/utils.py +10 -11
  57. claude_mpm/cli_module/__init__.py +1 -1
  58. claude_mpm/cli_module/args.py +1 -1
  59. claude_mpm/cli_module/migration_example.py +5 -5
  60. claude_mpm/config/__init__.py +9 -9
  61. claude_mpm/config/agent_config.py +15 -14
  62. claude_mpm/config/experimental_features.py +4 -4
  63. claude_mpm/config/paths.py +0 -1
  64. claude_mpm/config/socketio_config.py +5 -6
  65. claude_mpm/constants.py +1 -2
  66. claude_mpm/core/__init__.py +8 -8
  67. claude_mpm/core/agent_name_normalizer.py +1 -1
  68. claude_mpm/core/agent_registry.py +20 -23
  69. claude_mpm/core/agent_session_manager.py +3 -3
  70. claude_mpm/core/base_service.py +7 -15
  71. claude_mpm/core/cache.py +4 -6
  72. claude_mpm/core/claude_runner.py +85 -113
  73. claude_mpm/core/config.py +43 -28
  74. claude_mpm/core/config_aliases.py +0 -9
  75. claude_mpm/core/config_constants.py +52 -30
  76. claude_mpm/core/constants.py +0 -1
  77. claude_mpm/core/container.py +18 -27
  78. claude_mpm/core/exceptions.py +2 -2
  79. claude_mpm/core/factories.py +10 -12
  80. claude_mpm/core/framework_loader.py +581 -280
  81. claude_mpm/core/hook_manager.py +26 -22
  82. claude_mpm/core/hook_performance_config.py +58 -47
  83. claude_mpm/core/injectable_service.py +1 -1
  84. claude_mpm/core/interactive_session.py +61 -152
  85. claude_mpm/core/interfaces.py +1 -100
  86. claude_mpm/core/lazy.py +5 -5
  87. claude_mpm/core/log_manager.py +587 -0
  88. claude_mpm/core/logger.py +125 -8
  89. claude_mpm/core/logging_config.py +15 -15
  90. claude_mpm/core/minimal_framework_loader.py +5 -8
  91. claude_mpm/core/oneshot_session.py +15 -33
  92. claude_mpm/core/optimized_agent_loader.py +4 -6
  93. claude_mpm/core/optimized_startup.py +2 -1
  94. claude_mpm/core/output_style_manager.py +147 -106
  95. claude_mpm/core/pm_hook_interceptor.py +0 -1
  96. claude_mpm/core/service_registry.py +11 -8
  97. claude_mpm/core/session_manager.py +1 -2
  98. claude_mpm/core/shared/__init__.py +1 -1
  99. claude_mpm/core/shared/config_loader.py +101 -97
  100. claude_mpm/core/shared/path_resolver.py +72 -68
  101. claude_mpm/core/shared/singleton_manager.py +56 -50
  102. claude_mpm/core/socketio_pool.py +26 -6
  103. claude_mpm/core/tool_access_control.py +4 -5
  104. claude_mpm/core/typing_utils.py +50 -59
  105. claude_mpm/core/unified_agent_registry.py +14 -19
  106. claude_mpm/core/unified_config.py +4 -6
  107. claude_mpm/core/unified_paths.py +197 -109
  108. claude_mpm/dashboard/open_dashboard.py +2 -4
  109. claude_mpm/experimental/cli_enhancements.py +51 -36
  110. claude_mpm/generators/agent_profile_generator.py +2 -4
  111. claude_mpm/hooks/base_hook.py +1 -2
  112. claude_mpm/hooks/claude_hooks/connection_pool.py +72 -26
  113. claude_mpm/hooks/claude_hooks/event_handlers.py +93 -38
  114. claude_mpm/hooks/claude_hooks/hook_handler.py +130 -76
  115. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
  116. claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
  117. claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
  118. claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
  119. claude_mpm/hooks/memory_integration_hook.py +5 -5
  120. claude_mpm/hooks/tool_call_interceptor.py +1 -1
  121. claude_mpm/hooks/validation_hooks.py +4 -4
  122. claude_mpm/init.py +4 -9
  123. claude_mpm/models/__init__.py +2 -2
  124. claude_mpm/models/agent_session.py +11 -14
  125. claude_mpm/scripts/mcp_server.py +20 -11
  126. claude_mpm/scripts/mcp_wrapper.py +5 -5
  127. claude_mpm/scripts/mpm_doctor.py +321 -0
  128. claude_mpm/scripts/socketio_daemon.py +28 -25
  129. claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
  130. claude_mpm/scripts/socketio_server_manager.py +116 -95
  131. claude_mpm/services/__init__.py +49 -49
  132. claude_mpm/services/agent_capabilities_service.py +12 -18
  133. claude_mpm/services/agents/__init__.py +22 -22
  134. claude_mpm/services/agents/agent_builder.py +140 -119
  135. claude_mpm/services/agents/deployment/__init__.py +3 -3
  136. claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
  137. claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
  138. claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
  139. claude_mpm/services/agents/deployment/agent_deployment.py +136 -106
  140. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
  141. claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
  142. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
  143. claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
  144. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
  145. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
  146. claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
  147. claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
  148. claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
  149. claude_mpm/services/agents/deployment/agent_validator.py +0 -1
  150. claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
  151. claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
  152. claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
  153. claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
  154. claude_mpm/services/agents/deployment/config/__init__.py +1 -1
  155. claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
  156. claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
  157. claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
  158. claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
  159. claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
  160. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
  161. claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
  162. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
  163. claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
  164. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
  165. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
  166. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
  167. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
  168. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
  169. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
  170. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
  171. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
  172. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
  173. claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
  174. claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
  175. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
  176. claude_mpm/services/agents/deployment/results/__init__.py +1 -1
  177. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
  178. claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
  179. claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
  180. claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
  181. claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
  182. claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
  183. claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
  184. claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
  185. claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
  186. claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
  187. claude_mpm/services/agents/loading/__init__.py +1 -1
  188. claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
  189. claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
  190. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
  191. claude_mpm/services/agents/management/__init__.py +1 -1
  192. claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
  193. claude_mpm/services/agents/management/agent_management_service.py +5 -9
  194. claude_mpm/services/agents/memory/__init__.py +4 -4
  195. claude_mpm/services/agents/memory/agent_memory_manager.py +280 -160
  196. claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
  197. claude_mpm/services/agents/memory/content_manager.py +44 -38
  198. claude_mpm/services/agents/memory/template_generator.py +4 -6
  199. claude_mpm/services/agents/registry/__init__.py +10 -6
  200. claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
  201. claude_mpm/services/agents/registry/modification_tracker.py +3 -6
  202. claude_mpm/services/async_session_logger.py +1 -2
  203. claude_mpm/services/claude_session_logger.py +1 -2
  204. claude_mpm/services/command_deployment_service.py +173 -0
  205. claude_mpm/services/command_handler_service.py +20 -22
  206. claude_mpm/services/core/__init__.py +25 -25
  207. claude_mpm/services/core/base.py +0 -5
  208. claude_mpm/services/core/interfaces/__init__.py +32 -32
  209. claude_mpm/services/core/interfaces/agent.py +0 -21
  210. claude_mpm/services/core/interfaces/communication.py +0 -27
  211. claude_mpm/services/core/interfaces/infrastructure.py +0 -56
  212. claude_mpm/services/core/interfaces/service.py +0 -29
  213. claude_mpm/services/diagnostics/__init__.py +1 -1
  214. claude_mpm/services/diagnostics/checks/__init__.py +6 -6
  215. claude_mpm/services/diagnostics/checks/agent_check.py +89 -80
  216. claude_mpm/services/diagnostics/checks/base_check.py +12 -16
  217. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
  218. claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
  219. claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
  220. claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
  221. claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
  222. claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
  223. claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
  224. claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
  225. claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
  226. claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
  227. claude_mpm/services/diagnostics/models.py +21 -19
  228. claude_mpm/services/event_aggregator.py +10 -17
  229. claude_mpm/services/event_bus/__init__.py +1 -1
  230. claude_mpm/services/event_bus/config.py +54 -35
  231. claude_mpm/services/event_bus/event_bus.py +76 -71
  232. claude_mpm/services/event_bus/relay.py +74 -64
  233. claude_mpm/services/events/__init__.py +11 -11
  234. claude_mpm/services/events/consumers/__init__.py +3 -3
  235. claude_mpm/services/events/consumers/dead_letter.py +71 -63
  236. claude_mpm/services/events/consumers/logging.py +39 -37
  237. claude_mpm/services/events/consumers/metrics.py +56 -57
  238. claude_mpm/services/events/consumers/socketio.py +82 -81
  239. claude_mpm/services/events/core.py +110 -99
  240. claude_mpm/services/events/interfaces.py +56 -72
  241. claude_mpm/services/events/producers/__init__.py +1 -1
  242. claude_mpm/services/events/producers/hook.py +38 -38
  243. claude_mpm/services/events/producers/system.py +46 -44
  244. claude_mpm/services/exceptions.py +81 -80
  245. claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
  246. claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
  247. claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
  248. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
  249. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
  250. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
  251. claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
  252. claude_mpm/services/hook_service.py +6 -9
  253. claude_mpm/services/infrastructure/__init__.py +1 -1
  254. claude_mpm/services/infrastructure/context_preservation.py +8 -12
  255. claude_mpm/services/infrastructure/monitoring.py +21 -23
  256. claude_mpm/services/mcp_gateway/__init__.py +37 -37
  257. claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
  258. claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
  259. claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
  260. claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
  261. claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
  262. claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
  263. claude_mpm/services/mcp_gateway/core/base.py +0 -3
  264. claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
  265. claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
  266. claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
  267. claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
  268. claude_mpm/services/mcp_gateway/main.py +2 -1
  269. claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
  270. claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
  271. claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
  272. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
  273. claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
  274. claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
  275. claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
  276. claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
  277. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
  278. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
  279. claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
  280. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
  281. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
  282. claude_mpm/services/memory/__init__.py +3 -3
  283. claude_mpm/services/memory/builder.py +3 -6
  284. claude_mpm/services/memory/cache/__init__.py +1 -1
  285. claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
  286. claude_mpm/services/memory/cache/simple_cache.py +1 -1
  287. claude_mpm/services/memory/indexed_memory.py +5 -7
  288. claude_mpm/services/memory/optimizer.py +7 -10
  289. claude_mpm/services/memory/router.py +8 -9
  290. claude_mpm/services/memory_hook_service.py +48 -34
  291. claude_mpm/services/monitor_build_service.py +77 -73
  292. claude_mpm/services/port_manager.py +130 -108
  293. claude_mpm/services/project/analyzer.py +12 -10
  294. claude_mpm/services/project/registry.py +11 -11
  295. claude_mpm/services/recovery_manager.py +10 -19
  296. claude_mpm/services/response_tracker.py +0 -1
  297. claude_mpm/services/runner_configuration_service.py +19 -20
  298. claude_mpm/services/session_management_service.py +7 -11
  299. claude_mpm/services/shared/__init__.py +1 -1
  300. claude_mpm/services/shared/async_service_base.py +58 -50
  301. claude_mpm/services/shared/config_service_base.py +73 -67
  302. claude_mpm/services/shared/lifecycle_service_base.py +82 -78
  303. claude_mpm/services/shared/manager_base.py +94 -82
  304. claude_mpm/services/shared/service_factory.py +96 -98
  305. claude_mpm/services/socketio/__init__.py +3 -3
  306. claude_mpm/services/socketio/client_proxy.py +5 -5
  307. claude_mpm/services/socketio/event_normalizer.py +199 -181
  308. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  309. claude_mpm/services/socketio/handlers/base.py +5 -4
  310. claude_mpm/services/socketio/handlers/connection.py +163 -136
  311. claude_mpm/services/socketio/handlers/file.py +13 -14
  312. claude_mpm/services/socketio/handlers/git.py +12 -7
  313. claude_mpm/services/socketio/handlers/hook.py +49 -44
  314. claude_mpm/services/socketio/handlers/memory.py +0 -1
  315. claude_mpm/services/socketio/handlers/project.py +0 -1
  316. claude_mpm/services/socketio/handlers/registry.py +37 -19
  317. claude_mpm/services/socketio/migration_utils.py +98 -84
  318. claude_mpm/services/socketio/server/__init__.py +1 -1
  319. claude_mpm/services/socketio/server/broadcaster.py +81 -87
  320. claude_mpm/services/socketio/server/core.py +65 -54
  321. claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
  322. claude_mpm/services/socketio/server/main.py +64 -38
  323. claude_mpm/services/socketio_client_manager.py +10 -12
  324. claude_mpm/services/subprocess_launcher_service.py +4 -7
  325. claude_mpm/services/system_instructions_service.py +13 -14
  326. claude_mpm/services/ticket_manager.py +2 -2
  327. claude_mpm/services/utility_service.py +5 -13
  328. claude_mpm/services/version_control/__init__.py +16 -16
  329. claude_mpm/services/version_control/branch_strategy.py +5 -8
  330. claude_mpm/services/version_control/conflict_resolution.py +9 -23
  331. claude_mpm/services/version_control/git_operations.py +5 -7
  332. claude_mpm/services/version_control/semantic_versioning.py +16 -17
  333. claude_mpm/services/version_control/version_parser.py +13 -18
  334. claude_mpm/services/version_service.py +10 -11
  335. claude_mpm/storage/__init__.py +1 -1
  336. claude_mpm/storage/state_storage.py +22 -28
  337. claude_mpm/utils/__init__.py +6 -6
  338. claude_mpm/utils/agent_dependency_loader.py +47 -33
  339. claude_mpm/utils/config_manager.py +11 -14
  340. claude_mpm/utils/dependency_cache.py +1 -1
  341. claude_mpm/utils/dependency_manager.py +13 -17
  342. claude_mpm/utils/dependency_strategies.py +8 -10
  343. claude_mpm/utils/environment_context.py +3 -9
  344. claude_mpm/utils/error_handler.py +3 -13
  345. claude_mpm/utils/file_utils.py +1 -1
  346. claude_mpm/utils/path_operations.py +8 -12
  347. claude_mpm/utils/robust_installer.py +110 -33
  348. claude_mpm/utils/subprocess_utils.py +5 -6
  349. claude_mpm/validation/agent_validator.py +3 -6
  350. claude_mpm/validation/frontmatter_validator.py +1 -1
  351. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/METADATA +1 -1
  352. claude_mpm-4.1.2.dist-info/RECORD +498 -0
  353. claude_mpm-4.1.1.dist-info/RECORD +0 -494
  354. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/WHEEL +0 -0
  355. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/entry_points.txt +0 -0
  356. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/licenses/LICENSE +0 -0
  357. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/top_level.txt +0 -0
@@ -30,7 +30,7 @@ import sys
30
30
  from enum import Enum
31
31
  from functools import lru_cache
32
32
  from pathlib import Path
33
- from typing import Dict, List, Optional, Union
33
+ from typing import Optional, Union
34
34
 
35
35
  logger = logging.getLogger(__name__)
36
36
 
@@ -67,7 +67,7 @@ class PathContext:
67
67
  @staticmethod
68
68
  def _is_editable_install() -> bool:
69
69
  """Check if the current installation is editable (development mode).
70
-
70
+
71
71
  This checks for various indicators of an editable/development installation:
72
72
  - Presence of pyproject.toml in parent directories
73
73
  - .pth files pointing to the source directory
@@ -76,8 +76,9 @@ class PathContext:
76
76
  """
77
77
  try:
78
78
  import claude_mpm
79
+
79
80
  module_path = Path(claude_mpm.__file__).parent
80
-
81
+
81
82
  # Check if we're in a src/ directory structure with pyproject.toml
82
83
  current = module_path
83
84
  for _ in range(5): # Check up to 5 levels up
@@ -89,18 +90,25 @@ class PathContext:
89
90
  if current == current.parent:
90
91
  break
91
92
  current = current.parent
92
-
93
+
93
94
  # Additional check: If we're running from within a claude-mpm development directory
94
95
  # This handles the case where pipx claude-mpm is invoked from within the dev directory
95
96
  cwd = Path.cwd()
96
97
  current = cwd
97
98
  for _ in range(5): # Check up to 5 levels up from current directory
98
- if (current / "pyproject.toml").exists() and (current / "src" / "claude_mpm").exists():
99
+ if (current / "pyproject.toml").exists() and (
100
+ current / "src" / "claude_mpm"
101
+ ).exists():
99
102
  # Check if this is the claude-mpm project
100
103
  try:
101
104
  pyproject_content = (current / "pyproject.toml").read_text()
102
- if "claude-mpm" in pyproject_content and "claude_mpm" in pyproject_content:
103
- logger.debug(f"Running from within claude-mpm development directory: {current}")
105
+ if (
106
+ "claude-mpm" in pyproject_content
107
+ and "claude_mpm" in pyproject_content
108
+ ):
109
+ logger.debug(
110
+ f"Running from within claude-mpm development directory: {current}"
111
+ )
104
112
  # Verify this is a development setup by checking for key files
105
113
  if (current / "scripts" / "claude-mpm").exists():
106
114
  return True
@@ -109,10 +117,11 @@ class PathContext:
109
117
  if current == current.parent:
110
118
  break
111
119
  current = current.parent
112
-
120
+
113
121
  # Check for .pth files indicating editable install
114
122
  try:
115
123
  import site
124
+
116
125
  for site_dir in site.getsitepackages():
117
126
  site_path = Path(site_dir)
118
127
  if site_path.exists():
@@ -121,35 +130,45 @@ class PathContext:
121
130
  try:
122
131
  content = pth_file.read_text()
123
132
  # Check if the .pth file points to our module's parent
124
- if str(module_path.parent) in content or str(module_path) in content:
125
- logger.debug(f"Found editable install via .pth file: {pth_file}")
133
+ if (
134
+ str(module_path.parent) in content
135
+ or str(module_path) in content
136
+ ):
137
+ logger.debug(
138
+ f"Found editable install via .pth file: {pth_file}"
139
+ )
126
140
  return True
127
141
  except Exception:
128
142
  continue
129
-
143
+
130
144
  # Check for egg-link files
131
145
  for egg_link in site_path.glob("*egg-link"):
132
146
  if "claude" in egg_link.name.lower():
133
147
  try:
134
148
  content = egg_link.read_text()
135
- if str(module_path.parent) in content or str(module_path) in content:
136
- logger.debug(f"Found editable install via egg-link: {egg_link}")
149
+ if (
150
+ str(module_path.parent) in content
151
+ or str(module_path) in content
152
+ ):
153
+ logger.debug(
154
+ f"Found editable install via egg-link: {egg_link}"
155
+ )
137
156
  return True
138
157
  except Exception:
139
158
  continue
140
159
  except ImportError:
141
160
  pass
142
-
161
+
143
162
  except Exception as e:
144
163
  logger.debug(f"Error checking for editable install: {e}")
145
-
164
+
146
165
  return False
147
166
 
148
167
  @staticmethod
149
168
  @lru_cache(maxsize=1)
150
169
  def detect_deployment_context() -> DeploymentContext:
151
170
  """Detect the current deployment context.
152
-
171
+
153
172
  Priority order:
154
173
  1. Environment variable override (CLAUDE_MPM_DEV_MODE)
155
174
  2. Current working directory is a claude-mpm development project
@@ -158,61 +177,80 @@ class PathContext:
158
177
  """
159
178
  # Check for environment variable override
160
179
  if os.environ.get("CLAUDE_MPM_DEV_MODE", "").lower() in ("1", "true", "yes"):
161
- logger.info("Development mode forced via CLAUDE_MPM_DEV_MODE environment variable")
180
+ logger.info(
181
+ "Development mode forced via CLAUDE_MPM_DEV_MODE environment variable"
182
+ )
162
183
  return DeploymentContext.DEVELOPMENT
163
-
184
+
164
185
  # Check if current working directory is a claude-mpm development project
165
186
  # This handles the case where pipx claude-mpm is run from within the dev directory
166
187
  cwd = Path.cwd()
167
188
  current = cwd
168
189
  for _ in range(5): # Check up to 5 levels up from current directory
169
- if (current / "pyproject.toml").exists() and (current / "src" / "claude_mpm").exists():
190
+ if (current / "pyproject.toml").exists() and (
191
+ current / "src" / "claude_mpm"
192
+ ).exists():
170
193
  # Check if this is the claude-mpm project
171
194
  try:
172
195
  pyproject_content = (current / "pyproject.toml").read_text()
173
- if 'name = "claude-mpm"' in pyproject_content or '"claude-mpm"' in pyproject_content:
174
- logger.info(f"Detected claude-mpm development directory at {current}")
175
- logger.info("Using development mode for local source preference")
196
+ if (
197
+ 'name = "claude-mpm"' in pyproject_content
198
+ or '"claude-mpm"' in pyproject_content
199
+ ):
200
+ logger.info(
201
+ f"Detected claude-mpm development directory at {current}"
202
+ )
203
+ logger.info(
204
+ "Using development mode for local source preference"
205
+ )
176
206
  return DeploymentContext.DEVELOPMENT
177
207
  except Exception:
178
208
  pass
179
209
  if current == current.parent:
180
210
  break
181
211
  current = current.parent
182
-
212
+
183
213
  try:
184
214
  import claude_mpm
215
+
185
216
  module_path = Path(claude_mpm.__file__).parent
186
-
217
+
187
218
  # First check if this is an editable install, regardless of path
188
219
  # This is important for cases where pipx points to a development installation
189
220
  if PathContext._is_editable_install():
190
- logger.info(f"Detected editable/development installation")
221
+ logger.info("Detected editable/development installation")
191
222
  # Check if we should use development paths
192
223
  # This could be because we're in a src/ directory or running from dev directory
193
224
  if module_path.parent.name == "src":
194
225
  return DeploymentContext.DEVELOPMENT
195
- elif "pipx" in str(module_path):
226
+ if "pipx" in str(module_path):
196
227
  # Running via pipx but from within a development directory
197
228
  # Use development mode to prefer local source over pipx installation
198
229
  cwd = Path.cwd()
199
230
  current = cwd
200
231
  for _ in range(5):
201
- if (current / "src" / "claude_mpm").exists() and (current / "pyproject.toml").exists():
202
- logger.info(f"Running pipx from development directory, using development mode")
232
+ if (current / "src" / "claude_mpm").exists() and (
233
+ current / "pyproject.toml"
234
+ ).exists():
235
+ logger.info(
236
+ "Running pipx from development directory, using development mode"
237
+ )
203
238
  return DeploymentContext.DEVELOPMENT
204
239
  if current == current.parent:
205
240
  break
206
241
  current = current.parent
207
242
  return DeploymentContext.EDITABLE_INSTALL
208
- else:
209
- return DeploymentContext.EDITABLE_INSTALL
210
-
243
+ return DeploymentContext.EDITABLE_INSTALL
244
+
211
245
  # Check for development mode based on directory structure
212
246
  # module_path is typically /path/to/project/src/claude_mpm
213
- if (module_path.parent.name == "src" and
214
- (module_path.parent.parent / "src" / "claude_mpm").exists()):
215
- logger.info(f"Detected development mode via directory structure at {module_path}")
247
+ if (
248
+ module_path.parent.name == "src"
249
+ and (module_path.parent.parent / "src" / "claude_mpm").exists()
250
+ ):
251
+ logger.info(
252
+ f"Detected development mode via directory structure at {module_path}"
253
+ )
216
254
  return DeploymentContext.DEVELOPMENT
217
255
 
218
256
  # Check for pipx install
@@ -224,7 +262,7 @@ class PathContext:
224
262
  if "dist-packages" in str(module_path):
225
263
  logger.info(f"Detected system package installation at {module_path}")
226
264
  return DeploymentContext.SYSTEM_PACKAGE
227
-
265
+
228
266
  # Check for site-packages (could be pip or editable)
229
267
  if "site-packages" in str(module_path):
230
268
  # Already checked for editable above, so this is a regular pip install
@@ -236,7 +274,9 @@ class PathContext:
236
274
  return DeploymentContext.PIP_INSTALL
237
275
 
238
276
  except ImportError:
239
- logger.info("ImportError during context detection, defaulting to development")
277
+ logger.info(
278
+ "ImportError during context detection, defaulting to development"
279
+ )
240
280
  return DeploymentContext.DEVELOPMENT
241
281
 
242
282
 
@@ -297,33 +337,42 @@ class UnifiedPathManager:
297
337
 
298
338
  module_path = Path(claude_mpm.__file__).parent
299
339
 
300
- if self._deployment_context in (DeploymentContext.DEVELOPMENT, DeploymentContext.EDITABLE_INSTALL):
340
+ if self._deployment_context in (
341
+ DeploymentContext.DEVELOPMENT,
342
+ DeploymentContext.EDITABLE_INSTALL,
343
+ ):
301
344
  # For development mode, first check if we're running from within a dev directory
302
345
  # This handles the case where pipx is invoked from a development directory
303
346
  cwd = Path.cwd()
304
347
  current = cwd
305
348
  for _ in range(5):
306
- if (current / "src" / "claude_mpm").exists() and (current / "pyproject.toml").exists():
349
+ if (current / "src" / "claude_mpm").exists() and (
350
+ current / "pyproject.toml"
351
+ ).exists():
307
352
  # Verify this is the claude-mpm project
308
353
  try:
309
354
  pyproject_content = (current / "pyproject.toml").read_text()
310
355
  if "claude-mpm" in pyproject_content:
311
- logger.debug(f"Found framework root via cwd at {current}")
356
+ logger.debug(
357
+ f"Found framework root via cwd at {current}"
358
+ )
312
359
  return current
313
360
  except Exception:
314
361
  pass
315
362
  if current == current.parent:
316
363
  break
317
364
  current = current.parent
318
-
365
+
319
366
  # Development or editable install: go up to project root from module
320
367
  current = module_path
321
368
  while current != current.parent:
322
- if (current / "src" / "claude_mpm").exists() and (current / "pyproject.toml").exists():
369
+ if (current / "src" / "claude_mpm").exists() and (
370
+ current / "pyproject.toml"
371
+ ).exists():
323
372
  logger.debug(f"Found framework root at {current}")
324
373
  return current
325
374
  current = current.parent
326
-
375
+
327
376
  # Secondary check: Look for pyproject.toml without src structure
328
377
  current = module_path
329
378
  while current != current.parent:
@@ -366,14 +415,18 @@ class UnifiedPathManager:
366
415
  @property
367
416
  def package_root(self) -> Path:
368
417
  """Get the claude_mpm package root directory."""
369
- if self._deployment_context in (DeploymentContext.DEVELOPMENT, DeploymentContext.EDITABLE_INSTALL):
418
+ if self._deployment_context in (
419
+ DeploymentContext.DEVELOPMENT,
420
+ DeploymentContext.EDITABLE_INSTALL,
421
+ ):
370
422
  # In development mode, always use the source directory
371
423
  package_path = self.framework_root / "src" / "claude_mpm"
372
424
  if package_path.exists():
373
425
  return package_path
374
-
426
+
375
427
  try:
376
428
  import claude_mpm
429
+
377
430
  return Path(claude_mpm.__file__).parent
378
431
  except ImportError:
379
432
  return self.framework_root / "src" / "claude_mpm"
@@ -386,14 +439,13 @@ class UnifiedPathManager:
386
439
  """Get configuration directory for specified scope."""
387
440
  if scope == "user":
388
441
  return Path.home() / self.CONFIG_DIR_NAME
389
- elif scope == "project":
442
+ if scope == "project":
390
443
  return self.project_root / self.CONFIG_DIR_NAME
391
- elif scope == "framework":
444
+ if scope == "framework":
392
445
  return self.framework_root / self.CONFIG_DIR_NAME
393
- else:
394
- raise ValueError(
395
- f"Invalid scope: {scope}. Must be 'user', 'project', or 'framework'"
396
- )
446
+ raise ValueError(
447
+ f"Invalid scope: {scope}. Must be 'user', 'project', or 'framework'"
448
+ )
397
449
 
398
450
  def get_user_config_dir(self) -> Path:
399
451
  """Get the user-level configuration directory."""
@@ -412,17 +464,18 @@ class UnifiedPathManager:
412
464
  """Get agents directory for specified scope."""
413
465
  if scope == "user":
414
466
  return self.get_user_config_dir() / "agents"
415
- elif scope == "project":
467
+ if scope == "project":
416
468
  return self.get_project_config_dir() / "agents"
417
- elif scope == "framework":
418
- if self._deployment_context in (DeploymentContext.DEVELOPMENT, DeploymentContext.EDITABLE_INSTALL):
469
+ if scope == "framework":
470
+ if self._deployment_context in (
471
+ DeploymentContext.DEVELOPMENT,
472
+ DeploymentContext.EDITABLE_INSTALL,
473
+ ):
419
474
  return self.framework_root / "src" / "claude_mpm" / "agents"
420
- else:
421
- return self.package_root / "agents"
422
- else:
423
- raise ValueError(
424
- f"Invalid scope: {scope}. Must be 'user', 'project', or 'framework'"
425
- )
475
+ return self.package_root / "agents"
476
+ raise ValueError(
477
+ f"Invalid scope: {scope}. Must be 'user', 'project', or 'framework'"
478
+ )
426
479
 
427
480
  def get_user_agents_dir(self) -> Path:
428
481
  """Get the user-level agents directory."""
@@ -446,10 +499,12 @@ class UnifiedPathManager:
446
499
 
447
500
  def get_scripts_dir(self) -> Path:
448
501
  """Get the scripts directory."""
449
- if self._deployment_context in (DeploymentContext.DEVELOPMENT, DeploymentContext.EDITABLE_INSTALL):
502
+ if self._deployment_context in (
503
+ DeploymentContext.DEVELOPMENT,
504
+ DeploymentContext.EDITABLE_INSTALL,
505
+ ):
450
506
  return self.framework_root / "scripts"
451
- else:
452
- return self.package_root / "scripts"
507
+ return self.package_root / "scripts"
453
508
 
454
509
  def get_static_dir(self) -> Path:
455
510
  """Get the static files directory."""
@@ -643,124 +698,157 @@ class UnifiedPathManager:
643
698
 
644
699
  def get_executable_path(self) -> Optional[Path]:
645
700
  """Get the path to the claude-mpm executable for the current deployment context.
646
-
701
+
647
702
  This method provides deployment-context-aware executable path detection,
648
703
  particularly useful for MCP server configuration.
649
-
704
+
650
705
  Returns:
651
706
  Path to executable or None if not found
652
707
  """
653
708
  import shutil
654
-
709
+
655
710
  # Try standard which first
656
711
  which_result = shutil.which("claude-mpm")
657
712
  if which_result:
658
713
  return Path(which_result)
659
-
714
+
660
715
  # Enhanced detection based on deployment context
661
716
  if self._deployment_context == DeploymentContext.PIPX_INSTALL:
662
717
  return self._find_pipx_executable()
663
- elif self._deployment_context in (DeploymentContext.DEVELOPMENT, DeploymentContext.EDITABLE_INSTALL):
718
+ if self._deployment_context in (
719
+ DeploymentContext.DEVELOPMENT,
720
+ DeploymentContext.EDITABLE_INSTALL,
721
+ ):
664
722
  return self._find_development_executable()
665
- elif self._deployment_context == DeploymentContext.PIP_INSTALL:
723
+ if self._deployment_context == DeploymentContext.PIP_INSTALL:
666
724
  return self._find_pip_executable()
667
-
725
+
668
726
  return None
669
-
727
+
670
728
  def _find_pipx_executable(self) -> Optional[Path]:
671
729
  """Find claude-mpm executable in pipx installation."""
672
730
  try:
673
731
  import claude_mpm
732
+
674
733
  module_path = Path(claude_mpm.__file__).parent
675
-
734
+
676
735
  if "pipx" not in str(module_path):
677
736
  return None
678
-
737
+
679
738
  # Common pipx executable locations
680
739
  home = Path.home()
681
740
  pipx_paths = [
682
741
  home / ".local" / "bin" / "claude-mpm",
683
- home / ".local" / "share" / "pipx" / "venvs" / "claude-mpm" / "bin" / "claude-mpm",
742
+ home
743
+ / ".local"
744
+ / "share"
745
+ / "pipx"
746
+ / "venvs"
747
+ / "claude-mpm"
748
+ / "bin"
749
+ / "claude-mpm",
684
750
  ]
685
-
751
+
686
752
  # Windows paths
687
753
  if sys.platform == "win32":
688
- pipx_paths.extend([
689
- home / "AppData" / "Local" / "pipx" / "bin" / "claude-mpm.exe",
690
- home / ".local" / "bin" / "claude-mpm.exe",
691
- ])
692
-
754
+ pipx_paths.extend(
755
+ [
756
+ home / "AppData" / "Local" / "pipx" / "bin" / "claude-mpm.exe",
757
+ home / ".local" / "bin" / "claude-mpm.exe",
758
+ ]
759
+ )
760
+
693
761
  for path in pipx_paths:
694
762
  if path.exists():
695
763
  logger.debug(f"Found pipx executable: {path}")
696
764
  return path
697
-
765
+
698
766
  # Try to derive from module path
699
767
  # Navigate up from module to find venv, then to bin
700
768
  venv_path = module_path
701
769
  for _ in range(5): # Prevent infinite loops
702
- if venv_path.name == "claude-mpm" and (venv_path / "pyvenv.cfg").exists():
770
+ if (
771
+ venv_path.name == "claude-mpm"
772
+ and (venv_path / "pyvenv.cfg").exists()
773
+ ):
703
774
  # Found the venv directory
704
- bin_dir = venv_path / ("Scripts" if sys.platform == "win32" else "bin")
705
- exe_name = "claude-mpm.exe" if sys.platform == "win32" else "claude-mpm"
775
+ bin_dir = venv_path / (
776
+ "Scripts" if sys.platform == "win32" else "bin"
777
+ )
778
+ exe_name = (
779
+ "claude-mpm.exe" if sys.platform == "win32" else "claude-mpm"
780
+ )
706
781
  exe_path = bin_dir / exe_name
707
-
782
+
708
783
  if exe_path.exists():
709
- logger.debug(f"Found pipx executable via module path: {exe_path}")
784
+ logger.debug(
785
+ f"Found pipx executable via module path: {exe_path}"
786
+ )
710
787
  return exe_path
711
788
  break
712
-
789
+
713
790
  if venv_path == venv_path.parent:
714
791
  break
715
792
  venv_path = venv_path.parent
716
-
793
+
717
794
  except Exception as e:
718
795
  logger.debug(f"Error finding pipx executable: {e}")
719
-
796
+
720
797
  return None
721
-
798
+
722
799
  def _find_development_executable(self) -> Optional[Path]:
723
800
  """Find claude-mpm executable in development installation."""
724
801
  # For development, prefer the script in the project
725
802
  scripts_dir = self.get_scripts_dir()
726
803
  dev_executable = scripts_dir / "claude-mpm"
727
-
804
+
728
805
  if dev_executable.exists():
729
806
  return dev_executable
730
-
807
+
731
808
  # Check if we're in a development venv
732
- if hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix):
733
- venv_bin = Path(sys.prefix) / ("Scripts" if sys.platform == "win32" else "bin")
809
+ if hasattr(sys, "real_prefix") or (
810
+ hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix
811
+ ):
812
+ venv_bin = Path(sys.prefix) / (
813
+ "Scripts" if sys.platform == "win32" else "bin"
814
+ )
734
815
  venv_executable = venv_bin / "claude-mpm"
735
816
  if venv_executable.exists():
736
817
  return venv_executable
737
-
818
+
738
819
  return None
739
-
820
+
740
821
  def _find_pip_executable(self) -> Optional[Path]:
741
822
  """Find claude-mpm executable in pip installation."""
742
823
  # For pip installs, check the current Python environment
743
- if hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix):
824
+ if hasattr(sys, "real_prefix") or (
825
+ hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix
826
+ ):
744
827
  # In a virtual environment
745
- venv_bin = Path(sys.prefix) / ("Scripts" if sys.platform == "win32" else "bin")
828
+ venv_bin = Path(sys.prefix) / (
829
+ "Scripts" if sys.platform == "win32" else "bin"
830
+ )
746
831
  venv_executable = venv_bin / "claude-mpm"
747
832
  if venv_executable.exists():
748
833
  return venv_executable
749
-
834
+
750
835
  # Check system-wide installation
751
836
  try:
752
837
  import site
838
+
753
839
  for site_dir in site.getsitepackages():
754
840
  # Look for installed scripts
755
841
  site_path = Path(site_dir)
756
- scripts_dir = site_path.parent / ("Scripts" if sys.platform == "win32" else "bin")
842
+ scripts_dir = site_path.parent / (
843
+ "Scripts" if sys.platform == "win32" else "bin"
844
+ )
757
845
  if scripts_dir.exists():
758
846
  exe_path = scripts_dir / "claude-mpm"
759
847
  if exe_path.exists():
760
848
  return exe_path
761
849
  except Exception as e:
762
850
  logger.debug(f"Error finding pip executable: {e}")
763
-
851
+
764
852
  return None
765
853
 
766
854
 
@@ -833,18 +921,18 @@ def get_executable_path() -> Optional[Path]:
833
921
  # ============================================================================
834
922
 
835
923
  __all__ = [
836
- "UnifiedPathManager",
837
- "PathType",
838
924
  "DeploymentContext",
839
925
  "PathContext",
840
- "get_path_manager",
841
- "get_project_root",
842
- "get_framework_root",
843
- "get_package_root",
844
- "get_scripts_dir",
926
+ "PathType",
927
+ "UnifiedPathManager",
928
+ "find_file_upwards",
845
929
  "get_agents_dir",
846
930
  "get_config_dir",
847
- "find_file_upwards",
848
- "get_package_resource_path",
849
931
  "get_executable_path",
932
+ "get_framework_root",
933
+ "get_package_resource_path",
934
+ "get_package_root",
935
+ "get_path_manager",
936
+ "get_project_root",
937
+ "get_scripts_dir",
850
938
  ]
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env python3
2
2
  """Open the dashboard statically in the browser."""
3
3
 
4
- import os
5
4
  import webbrowser
6
5
  from pathlib import Path
7
6
 
@@ -29,9 +28,8 @@ def discover_socketio_port():
29
28
 
30
29
  # If 8765 is not available, return the first active instance port
31
30
  return instances[0].get("port", 8765)
32
- else:
33
- print("⚠️ No active SocketIO instances found, using default port 8765")
34
- return 8765
31
+ print("⚠️ No active SocketIO instances found, using default port 8765")
32
+ return 8765
35
33
  except Exception as e:
36
34
  print(f"⚠️ Failed to discover SocketIO port: {e}")
37
35
  print(" Using default port 8765")