claude-mpm 4.1.1__py3-none-any.whl â 4.1.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.
- 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/engineer.json +33 -11
- 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 +648 -1098
- 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 +339 -967
- claude_mpm/cli/commands/monitor.py +117 -88
- claude_mpm/cli/commands/run.py +233 -542
- 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 +280 -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 +22 -29
- 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 +500 -680
- 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 -17
- 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 +99 -154
- claude_mpm/hooks/claude_hooks/hook_handler.py +110 -720
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
- claude_mpm/hooks/claude_hooks/hook_handler_original.py +1040 -0
- claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +347 -0
- 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/services/__init__.py +13 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +190 -0
- claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
- claude_mpm/hooks/claude_hooks/services/state_manager.py +282 -0
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
- 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 +129 -511
- 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/base_agent_locator.py +132 -0
- 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_results_manager.py +185 -0
- 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/single_agent_deployer.py +315 -0
- 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 +157 -503
- 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/memory_categorization_service.py +165 -0
- claude_mpm/services/agents/memory/memory_file_service.py +103 -0
- claude_mpm/services/agents/memory/memory_format_service.py +201 -0
- claude_mpm/services/agents/memory/memory_limits_service.py +99 -0
- claude_mpm/services/agents/memory/template_generator.py +4 -6
- claude_mpm/services/agents/registry/__init__.py +11 -7
- 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/cli/__init__.py +18 -0
- claude_mpm/services/cli/agent_cleanup_service.py +407 -0
- claude_mpm/services/cli/agent_dependency_service.py +395 -0
- claude_mpm/services/cli/agent_listing_service.py +463 -0
- claude_mpm/services/cli/agent_output_formatter.py +605 -0
- claude_mpm/services/cli/agent_validation_service.py +589 -0
- claude_mpm/services/cli/dashboard_launcher.py +424 -0
- claude_mpm/services/cli/memory_crud_service.py +617 -0
- claude_mpm/services/cli/memory_output_formatter.py +604 -0
- claude_mpm/services/cli/session_manager.py +513 -0
- claude_mpm/services/cli/socketio_manager.py +498 -0
- claude_mpm/services/cli/startup_checker.py +370 -0
- 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/cache_manager.py +311 -0
- 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/core/memory_manager.py +637 -0
- claude_mpm/services/core/path_resolver.py +498 -0
- claude_mpm/services/core/service_container.py +520 -0
- claude_mpm/services/core/service_interfaces.py +436 -0
- 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 +152 -97
- 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.3.dist-info}/METADATA +1 -1
- claude_mpm-4.1.3.dist-info/RECORD +528 -0
- claude_mpm/cli/commands/run_config_checker.py +0 -160
- claude_mpm-4.1.1.dist-info/RECORD +0 -494
- {claude_mpm-4.1.1.dist-info â claude_mpm-4.1.3.dist-info}/WHEEL +0 -0
- {claude_mpm-4.1.1.dist-info â claude_mpm-4.1.3.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.1.1.dist-info â claude_mpm-4.1.3.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.1.1.dist-info â claude_mpm-4.1.3.dist-info}/top_level.txt +0 -0
claude_mpm/scripts/mcp_server.py
CHANGED
|
@@ -5,14 +5,17 @@ This script launches the MCP gateway server for Claude Code integration.
|
|
|
5
5
|
It handles proper Python path setup and error reporting to stderr.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
import sys
|
|
9
|
-
import os
|
|
10
8
|
import logging
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
11
|
|
|
12
12
|
# Since we're now in src/claude_mpm/scripts/, we need to go up 3 levels to reach the project root
|
|
13
13
|
# Then down into src to add it to the path
|
|
14
|
-
project_root = os.path.abspath(
|
|
15
|
-
|
|
14
|
+
project_root = os.path.abspath(
|
|
15
|
+
os.path.join(os.path.dirname(__file__), "..", "..", "..")
|
|
16
|
+
)
|
|
17
|
+
sys.path.insert(0, os.path.join(project_root, "src"))
|
|
18
|
+
|
|
16
19
|
|
|
17
20
|
def setup_logging():
|
|
18
21
|
"""Configure logging to stderr to avoid interfering with stdio protocol."""
|
|
@@ -22,25 +25,29 @@ def setup_logging():
|
|
|
22
25
|
stream=sys.stderr,
|
|
23
26
|
)
|
|
24
27
|
|
|
28
|
+
|
|
25
29
|
def main():
|
|
26
30
|
"""Main entry point for the MCP server launcher."""
|
|
27
31
|
try:
|
|
28
32
|
# Setup logging first
|
|
29
33
|
setup_logging()
|
|
30
34
|
logger = logging.getLogger("MCPLauncher")
|
|
31
|
-
|
|
35
|
+
|
|
32
36
|
# Import modules after path setup
|
|
33
37
|
try:
|
|
34
|
-
from claude_mpm.services.mcp_gateway.server.stdio_server import SimpleMCPServer
|
|
35
38
|
import asyncio
|
|
39
|
+
|
|
40
|
+
from claude_mpm.services.mcp_gateway.server.stdio_server import (
|
|
41
|
+
SimpleMCPServer,
|
|
42
|
+
)
|
|
36
43
|
except ImportError as e:
|
|
37
44
|
logger.error(f"Failed to import required modules: {e}")
|
|
38
45
|
logger.error("Make sure claude-mpm is properly installed")
|
|
39
46
|
sys.exit(1)
|
|
40
|
-
|
|
47
|
+
|
|
41
48
|
# Create and run server
|
|
42
49
|
logger.info("Starting MCP Gateway Server...")
|
|
43
|
-
|
|
50
|
+
|
|
44
51
|
async def run_server():
|
|
45
52
|
"""Async function to run the server."""
|
|
46
53
|
try:
|
|
@@ -49,10 +56,10 @@ def main():
|
|
|
49
56
|
except Exception as e:
|
|
50
57
|
logger.error(f"Server runtime error: {e}")
|
|
51
58
|
raise
|
|
52
|
-
|
|
59
|
+
|
|
53
60
|
# Run the async server
|
|
54
61
|
asyncio.run(run_server())
|
|
55
|
-
|
|
62
|
+
|
|
56
63
|
except KeyboardInterrupt:
|
|
57
64
|
# Clean shutdown on Ctrl+C
|
|
58
65
|
logger.info("Server shutdown requested")
|
|
@@ -61,8 +68,10 @@ def main():
|
|
|
61
68
|
# Log any unexpected errors
|
|
62
69
|
logger.error(f"Unexpected error: {e}")
|
|
63
70
|
import traceback
|
|
71
|
+
|
|
64
72
|
traceback.print_exc(file=sys.stderr)
|
|
65
73
|
sys.exit(1)
|
|
66
74
|
|
|
75
|
+
|
|
67
76
|
if __name__ == "__main__":
|
|
68
|
-
main()
|
|
77
|
+
main()
|
|
@@ -10,7 +10,6 @@ for the pyproject.toml scripts configuration.
|
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
import sys
|
|
13
|
-
import os
|
|
14
13
|
from pathlib import Path
|
|
15
14
|
|
|
16
15
|
|
|
@@ -20,20 +19,21 @@ def entry_point():
|
|
|
20
19
|
current_file = Path(__file__).resolve()
|
|
21
20
|
project_root = current_file.parent.parent.parent.parent
|
|
22
21
|
wrapper_script = project_root / "scripts" / "mcp_wrapper.py"
|
|
23
|
-
|
|
22
|
+
|
|
24
23
|
if not wrapper_script.exists():
|
|
25
24
|
print(f"Error: Wrapper script not found at {wrapper_script}", file=sys.stderr)
|
|
26
25
|
sys.exit(1)
|
|
27
|
-
|
|
26
|
+
|
|
28
27
|
# Add the scripts directory to path and import the wrapper
|
|
29
28
|
scripts_dir = str(wrapper_script.parent)
|
|
30
29
|
if scripts_dir not in sys.path:
|
|
31
30
|
sys.path.insert(0, scripts_dir)
|
|
32
|
-
|
|
31
|
+
|
|
33
32
|
# Import and run the wrapper
|
|
34
33
|
import mcp_wrapper
|
|
34
|
+
|
|
35
35
|
mcp_wrapper.main()
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
if __name__ == "__main__":
|
|
39
|
-
entry_point()
|
|
39
|
+
entry_point()
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
MPM Doctor operational script.
|
|
4
|
+
|
|
5
|
+
WHY: This script provides the core functionality for the /mpm-doctor slash command.
|
|
6
|
+
All operational logic is contained here, while the CLI integration remains in the
|
|
7
|
+
command parser and interactive session handler.
|
|
8
|
+
|
|
9
|
+
DESIGN DECISIONS:
|
|
10
|
+
- Centralized diagnostic execution
|
|
11
|
+
- Support for multiple output formats
|
|
12
|
+
- Configurable check selection
|
|
13
|
+
- Lightweight wrapper around DiagnosticRunner
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import argparse
|
|
17
|
+
import logging
|
|
18
|
+
import sys
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import Any, Dict, List, Optional
|
|
21
|
+
|
|
22
|
+
from ..services.diagnostics import DiagnosticRunner, DoctorReporter
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def run_diagnostics(
|
|
26
|
+
verbose: bool = False,
|
|
27
|
+
fix: bool = False,
|
|
28
|
+
checks: Optional[List[str]] = None,
|
|
29
|
+
parallel: bool = False,
|
|
30
|
+
output_format: str = "terminal",
|
|
31
|
+
no_color: bool = False,
|
|
32
|
+
) -> Dict[str, Any]:
|
|
33
|
+
"""
|
|
34
|
+
Execute MPM diagnostics with the specified configuration.
|
|
35
|
+
|
|
36
|
+
WHY: Provides a single entry point for all diagnostic operations,
|
|
37
|
+
whether called from CLI, interactive mode, or programmatically.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
verbose: Show detailed diagnostic information
|
|
41
|
+
fix: Attempt to fix issues automatically
|
|
42
|
+
checks: List of specific checks to run (None for all)
|
|
43
|
+
parallel: Run checks in parallel for faster execution
|
|
44
|
+
output_format: Output format ("terminal", "json", "markdown")
|
|
45
|
+
no_color: Disable colored output
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
Dictionary containing:
|
|
49
|
+
- success: bool - whether diagnostics completed successfully
|
|
50
|
+
- summary: DiagnosticSummary object
|
|
51
|
+
- error_count: int - number of errors found
|
|
52
|
+
- warning_count: int - number of warnings found
|
|
53
|
+
- message: str - optional error message if failed
|
|
54
|
+
"""
|
|
55
|
+
logger = logging.getLogger(__name__)
|
|
56
|
+
|
|
57
|
+
# Create diagnostic runner
|
|
58
|
+
runner = DiagnosticRunner(verbose=verbose, fix=fix)
|
|
59
|
+
|
|
60
|
+
# Run diagnostics
|
|
61
|
+
try:
|
|
62
|
+
if checks:
|
|
63
|
+
logger.info(f"Running specific checks: {', '.join(checks)}")
|
|
64
|
+
summary = runner.run_specific_checks(checks)
|
|
65
|
+
elif parallel:
|
|
66
|
+
logger.info("Running diagnostics in parallel mode")
|
|
67
|
+
summary = runner.run_diagnostics_parallel()
|
|
68
|
+
else:
|
|
69
|
+
logger.info("Running comprehensive diagnostics")
|
|
70
|
+
summary = runner.run_diagnostics()
|
|
71
|
+
|
|
72
|
+
except KeyboardInterrupt:
|
|
73
|
+
return {
|
|
74
|
+
"success": False,
|
|
75
|
+
"summary": None,
|
|
76
|
+
"error_count": 0,
|
|
77
|
+
"warning_count": 0,
|
|
78
|
+
"message": "Diagnostics interrupted by user",
|
|
79
|
+
}
|
|
80
|
+
except Exception as e:
|
|
81
|
+
logger.error(f"Diagnostic failed: {e}")
|
|
82
|
+
return {
|
|
83
|
+
"success": False,
|
|
84
|
+
"summary": None,
|
|
85
|
+
"error_count": 1,
|
|
86
|
+
"warning_count": 0,
|
|
87
|
+
"message": f"Diagnostic failed: {e!s}",
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
# Return success with summary
|
|
91
|
+
return {
|
|
92
|
+
"success": True,
|
|
93
|
+
"summary": summary,
|
|
94
|
+
"error_count": summary.error_count,
|
|
95
|
+
"warning_count": summary.warning_count,
|
|
96
|
+
"message": None,
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def format_output(
|
|
101
|
+
summary,
|
|
102
|
+
output_format: str = "terminal",
|
|
103
|
+
verbose: bool = False,
|
|
104
|
+
no_color: bool = False,
|
|
105
|
+
) -> str:
|
|
106
|
+
"""
|
|
107
|
+
Format diagnostic summary for output.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
summary: DiagnosticSummary object
|
|
111
|
+
output_format: Output format ("terminal", "json", "markdown")
|
|
112
|
+
verbose: Show detailed information
|
|
113
|
+
no_color: Disable colored output
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
Formatted output string
|
|
117
|
+
"""
|
|
118
|
+
# Create reporter
|
|
119
|
+
reporter = DoctorReporter(use_color=not no_color, verbose=verbose)
|
|
120
|
+
|
|
121
|
+
# Capture output as string for non-terminal formats
|
|
122
|
+
if output_format != "terminal":
|
|
123
|
+
import io
|
|
124
|
+
import sys
|
|
125
|
+
|
|
126
|
+
# Capture stdout
|
|
127
|
+
old_stdout = sys.stdout
|
|
128
|
+
sys.stdout = buffer = io.StringIO()
|
|
129
|
+
|
|
130
|
+
try:
|
|
131
|
+
reporter.report(summary, format=output_format)
|
|
132
|
+
output = buffer.getvalue()
|
|
133
|
+
finally:
|
|
134
|
+
sys.stdout = old_stdout
|
|
135
|
+
|
|
136
|
+
return output
|
|
137
|
+
# For terminal format, just report directly
|
|
138
|
+
reporter.report(summary, format=output_format)
|
|
139
|
+
return ""
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def run_doctor_slash_command(args: List[str]) -> bool:
|
|
143
|
+
"""
|
|
144
|
+
Execute the /mpm-doctor slash command.
|
|
145
|
+
|
|
146
|
+
WHY: Provides a simplified interface for the interactive mode slash command,
|
|
147
|
+
parsing basic arguments and returning a simple success/failure result.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
args: Command arguments (e.g., ['--verbose', '--no-color'])
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
bool: True if successful, False otherwise
|
|
154
|
+
"""
|
|
155
|
+
# Parse arguments
|
|
156
|
+
verbose = "--verbose" in args or "-v" in args
|
|
157
|
+
no_color = "--no-color" in args
|
|
158
|
+
fix = "--fix" in args
|
|
159
|
+
parallel = "--parallel" in args
|
|
160
|
+
|
|
161
|
+
# Extract specific checks if provided
|
|
162
|
+
checks = None
|
|
163
|
+
if "--checks" in args:
|
|
164
|
+
try:
|
|
165
|
+
idx = args.index("--checks")
|
|
166
|
+
if idx + 1 < len(args):
|
|
167
|
+
# Get all arguments after --checks until next flag
|
|
168
|
+
checks = []
|
|
169
|
+
for i in range(idx + 1, len(args)):
|
|
170
|
+
if args[i].startswith("-"):
|
|
171
|
+
break
|
|
172
|
+
checks.append(args[i])
|
|
173
|
+
except (ValueError, IndexError):
|
|
174
|
+
pass
|
|
175
|
+
|
|
176
|
+
# Print header
|
|
177
|
+
print("\n" + "=" * 60)
|
|
178
|
+
print("Claude MPM Doctor Report")
|
|
179
|
+
print("=" * 60)
|
|
180
|
+
|
|
181
|
+
# Run diagnostics
|
|
182
|
+
result = run_diagnostics(
|
|
183
|
+
verbose=verbose,
|
|
184
|
+
fix=fix,
|
|
185
|
+
checks=checks,
|
|
186
|
+
parallel=parallel,
|
|
187
|
+
output_format="terminal",
|
|
188
|
+
no_color=no_color,
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
# Handle results
|
|
192
|
+
if not result["success"]:
|
|
193
|
+
print(f"\nâ {result['message']}")
|
|
194
|
+
if verbose and result.get("message", "").startswith("Diagnostic failed"):
|
|
195
|
+
import traceback
|
|
196
|
+
|
|
197
|
+
traceback.print_exc()
|
|
198
|
+
return False
|
|
199
|
+
|
|
200
|
+
# Format and display output
|
|
201
|
+
format_output(
|
|
202
|
+
result["summary"], output_format="terminal", verbose=verbose, no_color=no_color
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
# Return based on status
|
|
206
|
+
return result["error_count"] == 0
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def main():
|
|
210
|
+
"""
|
|
211
|
+
Main entry point for standalone execution.
|
|
212
|
+
|
|
213
|
+
WHY: Allows the script to be run directly for testing or debugging.
|
|
214
|
+
"""
|
|
215
|
+
parser = argparse.ArgumentParser(
|
|
216
|
+
description="Claude MPM Doctor - Diagnostic Tool",
|
|
217
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
parser.add_argument(
|
|
221
|
+
"--verbose",
|
|
222
|
+
"-v",
|
|
223
|
+
action="store_true",
|
|
224
|
+
help="Show detailed diagnostic information",
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
parser.add_argument(
|
|
228
|
+
"--json", action="store_true", help="Output results in JSON format"
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
parser.add_argument(
|
|
232
|
+
"--markdown", action="store_true", help="Output results in Markdown format"
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
parser.add_argument(
|
|
236
|
+
"--fix",
|
|
237
|
+
action="store_true",
|
|
238
|
+
help="Attempt to fix issues automatically (experimental)",
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
parser.add_argument(
|
|
242
|
+
"--checks",
|
|
243
|
+
nargs="+",
|
|
244
|
+
choices=[
|
|
245
|
+
"installation",
|
|
246
|
+
"configuration",
|
|
247
|
+
"filesystem",
|
|
248
|
+
"claude",
|
|
249
|
+
"agents",
|
|
250
|
+
"mcp",
|
|
251
|
+
"monitor",
|
|
252
|
+
"common",
|
|
253
|
+
],
|
|
254
|
+
help="Run only specific checks",
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
parser.add_argument(
|
|
258
|
+
"--parallel",
|
|
259
|
+
action="store_true",
|
|
260
|
+
help="Run checks in parallel for faster execution",
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
parser.add_argument(
|
|
264
|
+
"--no-color", action="store_true", help="Disable colored output"
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
parser.add_argument("--output", "-o", type=Path, help="Save output to file")
|
|
268
|
+
|
|
269
|
+
args = parser.parse_args()
|
|
270
|
+
|
|
271
|
+
# Determine output format
|
|
272
|
+
if args.json:
|
|
273
|
+
output_format = "json"
|
|
274
|
+
elif args.markdown:
|
|
275
|
+
output_format = "markdown"
|
|
276
|
+
else:
|
|
277
|
+
output_format = "terminal"
|
|
278
|
+
|
|
279
|
+
# Run diagnostics
|
|
280
|
+
result = run_diagnostics(
|
|
281
|
+
verbose=args.verbose,
|
|
282
|
+
fix=args.fix,
|
|
283
|
+
checks=args.checks,
|
|
284
|
+
parallel=args.parallel,
|
|
285
|
+
output_format=output_format,
|
|
286
|
+
no_color=args.no_color,
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
# Handle failure
|
|
290
|
+
if not result["success"]:
|
|
291
|
+
print(f"\nâ {result['message']}")
|
|
292
|
+
sys.exit(2)
|
|
293
|
+
|
|
294
|
+
# Format output
|
|
295
|
+
output = format_output(
|
|
296
|
+
result["summary"],
|
|
297
|
+
output_format=output_format,
|
|
298
|
+
verbose=args.verbose,
|
|
299
|
+
no_color=args.no_color,
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
# Save to file if requested
|
|
303
|
+
if args.output:
|
|
304
|
+
try:
|
|
305
|
+
args.output.write_text(output)
|
|
306
|
+
print(f"Report saved to: {args.output}")
|
|
307
|
+
except Exception as e:
|
|
308
|
+
print(f"â Failed to save report: {e!s}")
|
|
309
|
+
sys.exit(2)
|
|
310
|
+
|
|
311
|
+
# Determine exit code
|
|
312
|
+
if result["error_count"] > 0:
|
|
313
|
+
sys.exit(2) # Errors found
|
|
314
|
+
elif result["warning_count"] > 0:
|
|
315
|
+
sys.exit(1) # Warnings found
|
|
316
|
+
else:
|
|
317
|
+
sys.exit(0) # All OK
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
if __name__ == "__main__":
|
|
321
|
+
main()
|
|
@@ -4,7 +4,6 @@ Pure Python daemon management for Socket.IO server.
|
|
|
4
4
|
No external dependencies required.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
import json
|
|
8
7
|
import os
|
|
9
8
|
import signal
|
|
10
9
|
import subprocess
|
|
@@ -12,60 +11,64 @@ import sys
|
|
|
12
11
|
import time
|
|
13
12
|
from pathlib import Path
|
|
14
13
|
|
|
14
|
+
|
|
15
15
|
# Detect and use virtual environment Python if available
|
|
16
16
|
def get_python_executable():
|
|
17
17
|
"""
|
|
18
18
|
Get the appropriate Python executable, preferring virtual environment.
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
WHY: The daemon must use the same Python environment as the parent process
|
|
21
21
|
to ensure all dependencies are available. System Python won't have the
|
|
22
22
|
required packages installed.
|
|
23
23
|
"""
|
|
24
24
|
# First, check if we're already in a virtual environment
|
|
25
|
-
if hasattr(sys,
|
|
25
|
+
if hasattr(sys, "real_prefix") or (
|
|
26
|
+
hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix
|
|
27
|
+
):
|
|
26
28
|
# We're in a virtual environment, use its Python
|
|
27
29
|
return sys.executable
|
|
28
|
-
|
|
30
|
+
|
|
29
31
|
# Check for common virtual environment indicators
|
|
30
32
|
# 1. VIRTUAL_ENV environment variable (most common)
|
|
31
|
-
venv_path = os.environ.get(
|
|
33
|
+
venv_path = os.environ.get("VIRTUAL_ENV")
|
|
32
34
|
if venv_path:
|
|
33
|
-
venv_python = Path(venv_path) /
|
|
35
|
+
venv_python = Path(venv_path) / "bin" / "python"
|
|
34
36
|
if venv_python.exists():
|
|
35
37
|
return str(venv_python)
|
|
36
|
-
|
|
38
|
+
|
|
37
39
|
# 2. Check if current executable is in a venv directory structure
|
|
38
40
|
exe_path = Path(sys.executable).resolve()
|
|
39
41
|
for parent in exe_path.parents:
|
|
40
42
|
# Check for common venv directory names
|
|
41
|
-
if parent.name in (
|
|
43
|
+
if parent.name in ("venv", ".venv", "env", ".env"):
|
|
42
44
|
# This looks like a virtual environment
|
|
43
45
|
return sys.executable
|
|
44
|
-
|
|
46
|
+
|
|
45
47
|
# Check for typical venv structure (bin/python or Scripts/python.exe)
|
|
46
|
-
if parent.name ==
|
|
48
|
+
if parent.name == "bin" and (parent.parent / "pyvenv.cfg").exists():
|
|
47
49
|
return sys.executable
|
|
48
|
-
if parent.name ==
|
|
50
|
+
if parent.name == "Scripts" and (parent.parent / "pyvenv.cfg").exists():
|
|
49
51
|
return sys.executable
|
|
50
|
-
|
|
52
|
+
|
|
51
53
|
# 3. Try to detect project-specific venv
|
|
52
54
|
# Look for venv in the project root (going up from script location)
|
|
53
55
|
script_path = Path(__file__).resolve()
|
|
54
56
|
for parent in script_path.parents:
|
|
55
57
|
# Stop at src or when we've gone too far up
|
|
56
|
-
if parent.name ==
|
|
58
|
+
if parent.name == "src" or not (parent / "src").exists():
|
|
57
59
|
# Check for venv directories
|
|
58
|
-
for venv_name in (
|
|
60
|
+
for venv_name in ("venv", ".venv", "env", ".env"):
|
|
59
61
|
venv_dir = parent / venv_name
|
|
60
62
|
if venv_dir.exists():
|
|
61
|
-
venv_python = venv_dir /
|
|
63
|
+
venv_python = venv_dir / "bin" / "python"
|
|
62
64
|
if venv_python.exists():
|
|
63
65
|
return str(venv_python)
|
|
64
66
|
break
|
|
65
|
-
|
|
67
|
+
|
|
66
68
|
# Fall back to current Python executable
|
|
67
69
|
return sys.executable
|
|
68
70
|
|
|
71
|
+
|
|
69
72
|
# Store the detected Python executable for daemon usage
|
|
70
73
|
PYTHON_EXECUTABLE = get_python_executable()
|
|
71
74
|
|
|
@@ -242,7 +245,9 @@ def start_server():
|
|
|
242
245
|
)
|
|
243
246
|
print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Python executable: {sys.executable}")
|
|
244
247
|
print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Python version: {sys.version}")
|
|
245
|
-
print(
|
|
248
|
+
print(
|
|
249
|
+
f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Python path: {sys.path[:3]}..."
|
|
250
|
+
) # Show first 3 entries
|
|
246
251
|
server = SocketIOServer(host="localhost", port=selected_port)
|
|
247
252
|
|
|
248
253
|
# Handle signals
|
|
@@ -281,7 +286,7 @@ def stop_server():
|
|
|
281
286
|
"""Stop the Socket.IO daemon server."""
|
|
282
287
|
if not is_running():
|
|
283
288
|
print("Socket.IO daemon server is not running.")
|
|
284
|
-
print(
|
|
289
|
+
print("Check for other servers: socketio_server_manager.py status")
|
|
285
290
|
return
|
|
286
291
|
|
|
287
292
|
try:
|
|
@@ -351,7 +356,7 @@ def status_server():
|
|
|
351
356
|
# Show instance information
|
|
352
357
|
instance = port_manager.get_instance_by_port(current_port)
|
|
353
358
|
if instance:
|
|
354
|
-
print(
|
|
359
|
+
print("\nđ Instance Information:")
|
|
355
360
|
print(f" ⢠Port: {instance.get('port')}")
|
|
356
361
|
print(f" ⢠Started: {time.ctime(instance.get('start_time', 0))}")
|
|
357
362
|
print(f" ⢠Instance ID: {instance.get('instance_id')}")
|
|
@@ -370,19 +375,17 @@ def status_server():
|
|
|
370
375
|
if response.status_code == 200:
|
|
371
376
|
data = response.json()
|
|
372
377
|
if "server_id" in data and data.get("server_id") != "daemon-socketio":
|
|
373
|
-
print(
|
|
374
|
-
f"\nâ ď¸ POTENTIAL CONFLICT: HTTP-managed server also detected"
|
|
375
|
-
)
|
|
378
|
+
print("\nâ ď¸ POTENTIAL CONFLICT: HTTP-managed server also detected")
|
|
376
379
|
print(f" Server ID: {data.get('server_id')}")
|
|
377
|
-
print(
|
|
380
|
+
print(" Use 'socketio_server_manager.py diagnose' to resolve")
|
|
378
381
|
except:
|
|
379
382
|
pass
|
|
380
383
|
|
|
381
384
|
else:
|
|
382
385
|
print("Socket.IO daemon server is not running")
|
|
383
|
-
print(
|
|
386
|
+
print("\nđ§ Start Commands:")
|
|
384
387
|
print(f" ⢠Daemon: {__file__} start")
|
|
385
|
-
print(
|
|
388
|
+
print(" ⢠HTTP-managed: socketio_server_manager.py start")
|
|
386
389
|
|
|
387
390
|
|
|
388
391
|
def list_instances():
|