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.
- claude_mpm/BUILD_NUMBER +1 -1
- claude_mpm/VERSION +1 -1
- claude_mpm/__main__.py +1 -1
- claude_mpm/agents/BASE_PM.md +74 -46
- claude_mpm/agents/INSTRUCTIONS.md +11 -153
- claude_mpm/agents/WORKFLOW.md +61 -321
- claude_mpm/agents/__init__.py +11 -11
- claude_mpm/agents/agent_loader.py +23 -20
- claude_mpm/agents/agent_loader_integration.py +1 -1
- claude_mpm/agents/agents_metadata.py +27 -0
- claude_mpm/agents/async_agent_loader.py +5 -8
- claude_mpm/agents/base_agent_loader.py +36 -25
- claude_mpm/agents/frontmatter_validator.py +6 -6
- claude_mpm/agents/schema/agent_schema.json +1 -1
- claude_mpm/agents/system_agent_config.py +9 -9
- claude_mpm/agents/templates/api_qa.json +47 -2
- claude_mpm/agents/templates/imagemagick.json +256 -0
- claude_mpm/agents/templates/qa.json +41 -2
- claude_mpm/agents/templates/ticketing.json +5 -5
- claude_mpm/agents/templates/web_qa.json +50 -2
- claude_mpm/cli/__init__.py +51 -46
- claude_mpm/cli/__main__.py +1 -1
- claude_mpm/cli/commands/__init__.py +10 -12
- claude_mpm/cli/commands/agent_manager.py +186 -181
- claude_mpm/cli/commands/agents.py +271 -268
- claude_mpm/cli/commands/aggregate.py +30 -29
- claude_mpm/cli/commands/cleanup.py +50 -44
- claude_mpm/cli/commands/cleanup_orphaned_agents.py +25 -25
- claude_mpm/cli/commands/config.py +162 -127
- claude_mpm/cli/commands/doctor.py +52 -62
- claude_mpm/cli/commands/info.py +37 -25
- claude_mpm/cli/commands/mcp.py +3 -7
- claude_mpm/cli/commands/mcp_command_router.py +14 -18
- claude_mpm/cli/commands/mcp_install_commands.py +28 -23
- claude_mpm/cli/commands/mcp_pipx_config.py +58 -49
- claude_mpm/cli/commands/mcp_server_commands.py +23 -17
- claude_mpm/cli/commands/memory.py +192 -141
- claude_mpm/cli/commands/monitor.py +117 -88
- claude_mpm/cli/commands/run.py +120 -84
- claude_mpm/cli/commands/run_config_checker.py +4 -5
- claude_mpm/cli/commands/socketio_monitor.py +17 -19
- claude_mpm/cli/commands/tickets.py +92 -92
- claude_mpm/cli/parser.py +1 -5
- claude_mpm/cli/parsers/__init__.py +1 -1
- claude_mpm/cli/parsers/agent_manager_parser.py +50 -98
- claude_mpm/cli/parsers/agents_parser.py +2 -3
- claude_mpm/cli/parsers/base_parser.py +7 -5
- claude_mpm/cli/parsers/mcp_parser.py +4 -2
- claude_mpm/cli/parsers/monitor_parser.py +26 -18
- claude_mpm/cli/shared/__init__.py +10 -10
- claude_mpm/cli/shared/argument_patterns.py +57 -71
- claude_mpm/cli/shared/base_command.py +61 -53
- claude_mpm/cli/shared/error_handling.py +62 -58
- claude_mpm/cli/shared/output_formatters.py +78 -77
- claude_mpm/cli/startup_logging.py +204 -172
- claude_mpm/cli/utils.py +10 -11
- claude_mpm/cli_module/__init__.py +1 -1
- claude_mpm/cli_module/args.py +1 -1
- claude_mpm/cli_module/migration_example.py +5 -5
- claude_mpm/config/__init__.py +9 -9
- claude_mpm/config/agent_config.py +15 -14
- claude_mpm/config/experimental_features.py +4 -4
- claude_mpm/config/paths.py +0 -1
- claude_mpm/config/socketio_config.py +5 -6
- claude_mpm/constants.py +1 -2
- claude_mpm/core/__init__.py +8 -8
- claude_mpm/core/agent_name_normalizer.py +1 -1
- claude_mpm/core/agent_registry.py +20 -23
- claude_mpm/core/agent_session_manager.py +3 -3
- claude_mpm/core/base_service.py +7 -15
- claude_mpm/core/cache.py +4 -6
- claude_mpm/core/claude_runner.py +85 -113
- claude_mpm/core/config.py +43 -28
- claude_mpm/core/config_aliases.py +0 -9
- claude_mpm/core/config_constants.py +52 -30
- claude_mpm/core/constants.py +0 -1
- claude_mpm/core/container.py +18 -27
- claude_mpm/core/exceptions.py +2 -2
- claude_mpm/core/factories.py +10 -12
- claude_mpm/core/framework_loader.py +581 -280
- claude_mpm/core/hook_manager.py +26 -22
- claude_mpm/core/hook_performance_config.py +58 -47
- claude_mpm/core/injectable_service.py +1 -1
- claude_mpm/core/interactive_session.py +61 -152
- claude_mpm/core/interfaces.py +1 -100
- claude_mpm/core/lazy.py +5 -5
- claude_mpm/core/log_manager.py +587 -0
- claude_mpm/core/logger.py +125 -8
- claude_mpm/core/logging_config.py +15 -15
- claude_mpm/core/minimal_framework_loader.py +5 -8
- claude_mpm/core/oneshot_session.py +15 -33
- claude_mpm/core/optimized_agent_loader.py +4 -6
- claude_mpm/core/optimized_startup.py +2 -1
- claude_mpm/core/output_style_manager.py +147 -106
- claude_mpm/core/pm_hook_interceptor.py +0 -1
- claude_mpm/core/service_registry.py +11 -8
- claude_mpm/core/session_manager.py +1 -2
- claude_mpm/core/shared/__init__.py +1 -1
- claude_mpm/core/shared/config_loader.py +101 -97
- claude_mpm/core/shared/path_resolver.py +72 -68
- claude_mpm/core/shared/singleton_manager.py +56 -50
- claude_mpm/core/socketio_pool.py +26 -6
- claude_mpm/core/tool_access_control.py +4 -5
- claude_mpm/core/typing_utils.py +50 -59
- claude_mpm/core/unified_agent_registry.py +14 -19
- claude_mpm/core/unified_config.py +4 -6
- claude_mpm/core/unified_paths.py +197 -109
- claude_mpm/dashboard/open_dashboard.py +2 -4
- claude_mpm/experimental/cli_enhancements.py +51 -36
- claude_mpm/generators/agent_profile_generator.py +2 -4
- claude_mpm/hooks/base_hook.py +1 -2
- claude_mpm/hooks/claude_hooks/connection_pool.py +72 -26
- claude_mpm/hooks/claude_hooks/event_handlers.py +93 -38
- claude_mpm/hooks/claude_hooks/hook_handler.py +130 -76
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
- claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
- claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
- claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
- claude_mpm/hooks/memory_integration_hook.py +5 -5
- claude_mpm/hooks/tool_call_interceptor.py +1 -1
- claude_mpm/hooks/validation_hooks.py +4 -4
- claude_mpm/init.py +4 -9
- claude_mpm/models/__init__.py +2 -2
- claude_mpm/models/agent_session.py +11 -14
- claude_mpm/scripts/mcp_server.py +20 -11
- claude_mpm/scripts/mcp_wrapper.py +5 -5
- claude_mpm/scripts/mpm_doctor.py +321 -0
- claude_mpm/scripts/socketio_daemon.py +28 -25
- claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
- claude_mpm/scripts/socketio_server_manager.py +116 -95
- claude_mpm/services/__init__.py +49 -49
- claude_mpm/services/agent_capabilities_service.py +12 -18
- claude_mpm/services/agents/__init__.py +22 -22
- claude_mpm/services/agents/agent_builder.py +140 -119
- claude_mpm/services/agents/deployment/__init__.py +3 -3
- claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
- claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
- claude_mpm/services/agents/deployment/agent_deployment.py +136 -106
- claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
- claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
- claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
- claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
- claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
- claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
- claude_mpm/services/agents/deployment/agent_validator.py +0 -1
- claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
- claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
- claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
- claude_mpm/services/agents/deployment/config/__init__.py +1 -1
- claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
- claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
- claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
- claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
- claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
- claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
- claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
- claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
- claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
- claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
- claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
- claude_mpm/services/agents/deployment/results/__init__.py +1 -1
- claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
- claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
- claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
- claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
- claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
- claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
- claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
- claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
- claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
- claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
- claude_mpm/services/agents/loading/__init__.py +1 -1
- claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
- claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
- claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
- claude_mpm/services/agents/management/__init__.py +1 -1
- claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
- claude_mpm/services/agents/management/agent_management_service.py +5 -9
- claude_mpm/services/agents/memory/__init__.py +4 -4
- claude_mpm/services/agents/memory/agent_memory_manager.py +280 -160
- claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
- claude_mpm/services/agents/memory/content_manager.py +44 -38
- claude_mpm/services/agents/memory/template_generator.py +4 -6
- claude_mpm/services/agents/registry/__init__.py +10 -6
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
- claude_mpm/services/agents/registry/modification_tracker.py +3 -6
- claude_mpm/services/async_session_logger.py +1 -2
- claude_mpm/services/claude_session_logger.py +1 -2
- claude_mpm/services/command_deployment_service.py +173 -0
- claude_mpm/services/command_handler_service.py +20 -22
- claude_mpm/services/core/__init__.py +25 -25
- claude_mpm/services/core/base.py +0 -5
- claude_mpm/services/core/interfaces/__init__.py +32 -32
- claude_mpm/services/core/interfaces/agent.py +0 -21
- claude_mpm/services/core/interfaces/communication.py +0 -27
- claude_mpm/services/core/interfaces/infrastructure.py +0 -56
- claude_mpm/services/core/interfaces/service.py +0 -29
- claude_mpm/services/diagnostics/__init__.py +1 -1
- claude_mpm/services/diagnostics/checks/__init__.py +6 -6
- claude_mpm/services/diagnostics/checks/agent_check.py +89 -80
- claude_mpm/services/diagnostics/checks/base_check.py +12 -16
- claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
- claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
- claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
- claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
- claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
- claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
- claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
- claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
- claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
- claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
- claude_mpm/services/diagnostics/models.py +21 -19
- claude_mpm/services/event_aggregator.py +10 -17
- claude_mpm/services/event_bus/__init__.py +1 -1
- claude_mpm/services/event_bus/config.py +54 -35
- claude_mpm/services/event_bus/event_bus.py +76 -71
- claude_mpm/services/event_bus/relay.py +74 -64
- claude_mpm/services/events/__init__.py +11 -11
- claude_mpm/services/events/consumers/__init__.py +3 -3
- claude_mpm/services/events/consumers/dead_letter.py +71 -63
- claude_mpm/services/events/consumers/logging.py +39 -37
- claude_mpm/services/events/consumers/metrics.py +56 -57
- claude_mpm/services/events/consumers/socketio.py +82 -81
- claude_mpm/services/events/core.py +110 -99
- claude_mpm/services/events/interfaces.py +56 -72
- claude_mpm/services/events/producers/__init__.py +1 -1
- claude_mpm/services/events/producers/hook.py +38 -38
- claude_mpm/services/events/producers/system.py +46 -44
- claude_mpm/services/exceptions.py +81 -80
- claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
- claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
- claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
- claude_mpm/services/hook_service.py +6 -9
- claude_mpm/services/infrastructure/__init__.py +1 -1
- claude_mpm/services/infrastructure/context_preservation.py +8 -12
- claude_mpm/services/infrastructure/monitoring.py +21 -23
- claude_mpm/services/mcp_gateway/__init__.py +37 -37
- claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
- claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
- claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
- claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
- claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
- claude_mpm/services/mcp_gateway/core/base.py +0 -3
- claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
- claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
- claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
- claude_mpm/services/mcp_gateway/main.py +2 -1
- claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
- claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
- claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
- claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
- claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
- claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
- claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
- claude_mpm/services/memory/__init__.py +3 -3
- claude_mpm/services/memory/builder.py +3 -6
- claude_mpm/services/memory/cache/__init__.py +1 -1
- claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
- claude_mpm/services/memory/cache/simple_cache.py +1 -1
- claude_mpm/services/memory/indexed_memory.py +5 -7
- claude_mpm/services/memory/optimizer.py +7 -10
- claude_mpm/services/memory/router.py +8 -9
- claude_mpm/services/memory_hook_service.py +48 -34
- claude_mpm/services/monitor_build_service.py +77 -73
- claude_mpm/services/port_manager.py +130 -108
- claude_mpm/services/project/analyzer.py +12 -10
- claude_mpm/services/project/registry.py +11 -11
- claude_mpm/services/recovery_manager.py +10 -19
- claude_mpm/services/response_tracker.py +0 -1
- claude_mpm/services/runner_configuration_service.py +19 -20
- claude_mpm/services/session_management_service.py +7 -11
- claude_mpm/services/shared/__init__.py +1 -1
- claude_mpm/services/shared/async_service_base.py +58 -50
- claude_mpm/services/shared/config_service_base.py +73 -67
- claude_mpm/services/shared/lifecycle_service_base.py +82 -78
- claude_mpm/services/shared/manager_base.py +94 -82
- claude_mpm/services/shared/service_factory.py +96 -98
- claude_mpm/services/socketio/__init__.py +3 -3
- claude_mpm/services/socketio/client_proxy.py +5 -5
- claude_mpm/services/socketio/event_normalizer.py +199 -181
- claude_mpm/services/socketio/handlers/__init__.py +3 -3
- claude_mpm/services/socketio/handlers/base.py +5 -4
- claude_mpm/services/socketio/handlers/connection.py +163 -136
- claude_mpm/services/socketio/handlers/file.py +13 -14
- claude_mpm/services/socketio/handlers/git.py +12 -7
- claude_mpm/services/socketio/handlers/hook.py +49 -44
- claude_mpm/services/socketio/handlers/memory.py +0 -1
- claude_mpm/services/socketio/handlers/project.py +0 -1
- claude_mpm/services/socketio/handlers/registry.py +37 -19
- claude_mpm/services/socketio/migration_utils.py +98 -84
- claude_mpm/services/socketio/server/__init__.py +1 -1
- claude_mpm/services/socketio/server/broadcaster.py +81 -87
- claude_mpm/services/socketio/server/core.py +65 -54
- claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
- claude_mpm/services/socketio/server/main.py +64 -38
- claude_mpm/services/socketio_client_manager.py +10 -12
- claude_mpm/services/subprocess_launcher_service.py +4 -7
- claude_mpm/services/system_instructions_service.py +13 -14
- claude_mpm/services/ticket_manager.py +2 -2
- claude_mpm/services/utility_service.py +5 -13
- claude_mpm/services/version_control/__init__.py +16 -16
- claude_mpm/services/version_control/branch_strategy.py +5 -8
- claude_mpm/services/version_control/conflict_resolution.py +9 -23
- claude_mpm/services/version_control/git_operations.py +5 -7
- claude_mpm/services/version_control/semantic_versioning.py +16 -17
- claude_mpm/services/version_control/version_parser.py +13 -18
- claude_mpm/services/version_service.py +10 -11
- claude_mpm/storage/__init__.py +1 -1
- claude_mpm/storage/state_storage.py +22 -28
- claude_mpm/utils/__init__.py +6 -6
- claude_mpm/utils/agent_dependency_loader.py +47 -33
- claude_mpm/utils/config_manager.py +11 -14
- claude_mpm/utils/dependency_cache.py +1 -1
- claude_mpm/utils/dependency_manager.py +13 -17
- claude_mpm/utils/dependency_strategies.py +8 -10
- claude_mpm/utils/environment_context.py +3 -9
- claude_mpm/utils/error_handler.py +3 -13
- claude_mpm/utils/file_utils.py +1 -1
- claude_mpm/utils/path_operations.py +8 -12
- claude_mpm/utils/robust_installer.py +110 -33
- claude_mpm/utils/subprocess_utils.py +5 -6
- claude_mpm/validation/agent_validator.py +3 -6
- claude_mpm/validation/frontmatter_validator.py +1 -1
- {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/METADATA +1 -1
- claude_mpm-4.1.2.dist-info/RECORD +498 -0
- claude_mpm-4.1.1.dist-info/RECORD +0 -494
- {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/WHEEL +0 -0
- {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/top_level.txt +0 -0
claude_mpm/core/unified_paths.py
CHANGED
|
@@ -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
|
|
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 (
|
|
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
|
|
103
|
-
|
|
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
|
|
125
|
-
|
|
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
|
|
136
|
-
|
|
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(
|
|
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 (
|
|
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
|
|
174
|
-
|
|
175
|
-
|
|
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(
|
|
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
|
-
|
|
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 (
|
|
202
|
-
|
|
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
|
-
|
|
209
|
-
|
|
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 (
|
|
214
|
-
|
|
215
|
-
|
|
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(
|
|
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 (
|
|
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 (
|
|
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(
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
442
|
+
if scope == "project":
|
|
390
443
|
return self.project_root / self.CONFIG_DIR_NAME
|
|
391
|
-
|
|
444
|
+
if scope == "framework":
|
|
392
445
|
return self.framework_root / self.CONFIG_DIR_NAME
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
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
|
-
|
|
467
|
+
if scope == "project":
|
|
416
468
|
return self.get_project_config_dir() / "agents"
|
|
417
|
-
|
|
418
|
-
if self._deployment_context in (
|
|
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
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
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 (
|
|
502
|
+
if self._deployment_context in (
|
|
503
|
+
DeploymentContext.DEVELOPMENT,
|
|
504
|
+
DeploymentContext.EDITABLE_INSTALL,
|
|
505
|
+
):
|
|
450
506
|
return self.framework_root / "scripts"
|
|
451
|
-
|
|
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
|
-
|
|
718
|
+
if self._deployment_context in (
|
|
719
|
+
DeploymentContext.DEVELOPMENT,
|
|
720
|
+
DeploymentContext.EDITABLE_INSTALL,
|
|
721
|
+
):
|
|
664
722
|
return self._find_development_executable()
|
|
665
|
-
|
|
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
|
|
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
|
-
|
|
690
|
-
|
|
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
|
|
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 / (
|
|
705
|
-
|
|
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(
|
|
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,
|
|
733
|
-
|
|
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,
|
|
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) / (
|
|
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 / (
|
|
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
|
-
"
|
|
841
|
-
"
|
|
842
|
-
"
|
|
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
|
-
|
|
33
|
-
|
|
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")
|