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
|
@@ -10,8 +10,6 @@ delegates to specialized components rather than inheriting from them.
|
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
import asyncio
|
|
13
|
-
import logging
|
|
14
|
-
import os
|
|
15
13
|
import threading
|
|
16
14
|
import time
|
|
17
15
|
from collections import deque
|
|
@@ -31,15 +29,10 @@ except ImportError:
|
|
|
31
29
|
web = None
|
|
32
30
|
|
|
33
31
|
from ....core.constants import (
|
|
34
|
-
NetworkConfig,
|
|
35
|
-
PerformanceConfig,
|
|
36
32
|
SystemLimits,
|
|
37
|
-
TimeoutConfig,
|
|
38
33
|
)
|
|
34
|
+
from ....core.logging_config import get_logger
|
|
39
35
|
from ...core.interfaces.communication import SocketIOServiceInterface
|
|
40
|
-
from ....core.logging_config import get_logger, log_operation, log_performance_context
|
|
41
|
-
from ....core.unified_paths import get_project_root, get_scripts_dir
|
|
42
|
-
from ...exceptions import SocketIOServerError as MPMConnectionError
|
|
43
36
|
from ..handlers import EventHandlerRegistry, FileEventHandler, GitEventHandler
|
|
44
37
|
from .broadcaster import SocketIOEventBroadcaster
|
|
45
38
|
from .core import SocketIOServerCore
|
|
@@ -91,10 +84,10 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
91
84
|
self.claude_status = "unknown"
|
|
92
85
|
self.claude_pid = None
|
|
93
86
|
self.event_history = deque(maxlen=SystemLimits.MAX_EVENTS_BUFFER)
|
|
94
|
-
|
|
87
|
+
|
|
95
88
|
# Active session tracking for heartbeat
|
|
96
89
|
self.active_sessions: Dict[str, Dict[str, Any]] = {}
|
|
97
|
-
|
|
90
|
+
|
|
98
91
|
# EventBus integration
|
|
99
92
|
self.eventbus_integration = None
|
|
100
93
|
|
|
@@ -106,7 +99,14 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
106
99
|
|
|
107
100
|
# Set reference to main server for session data
|
|
108
101
|
self.core.main_server = self
|
|
109
|
-
|
|
102
|
+
|
|
103
|
+
# Debug logging for EventBus initialization
|
|
104
|
+
self.logger.info("Starting Socket.IO server with EventBus integration...")
|
|
105
|
+
print(
|
|
106
|
+
f"[{datetime.now().isoformat()}] SocketIOServer.start_sync() called",
|
|
107
|
+
flush=True,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
110
|
# Start the core server
|
|
111
111
|
self.core.start_sync()
|
|
112
112
|
|
|
@@ -127,11 +127,11 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
127
127
|
max_wait = 5.0 # Maximum wait time in seconds
|
|
128
128
|
wait_interval = 0.1 # Check interval
|
|
129
129
|
waited = 0.0
|
|
130
|
-
|
|
130
|
+
|
|
131
131
|
while self.core.loop is None and waited < max_wait:
|
|
132
132
|
time.sleep(wait_interval)
|
|
133
133
|
waited += wait_interval
|
|
134
|
-
|
|
134
|
+
|
|
135
135
|
if self.core.loop is None:
|
|
136
136
|
self.logger.warning(
|
|
137
137
|
f"Event loop not initialized after {max_wait}s wait. "
|
|
@@ -139,27 +139,51 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
139
139
|
)
|
|
140
140
|
else:
|
|
141
141
|
self.logger.debug(f"Event loop ready after {waited:.1f}s")
|
|
142
|
-
|
|
142
|
+
|
|
143
143
|
# Set the loop reference for broadcaster
|
|
144
144
|
self.broadcaster.loop = self.core.loop
|
|
145
|
-
|
|
145
|
+
|
|
146
146
|
# Start the retry processor for resilient event delivery
|
|
147
147
|
self.broadcaster.start_retry_processor()
|
|
148
148
|
|
|
149
149
|
# Register events
|
|
150
150
|
self._register_events()
|
|
151
|
-
|
|
151
|
+
|
|
152
152
|
# Setup EventBus integration
|
|
153
153
|
# WHY: This connects the EventBus to the Socket.IO server, allowing
|
|
154
154
|
# events from other parts of the system to be broadcast to dashboard
|
|
155
|
+
print(
|
|
156
|
+
f"[{datetime.now().isoformat()}] Setting up EventBus integration...",
|
|
157
|
+
flush=True,
|
|
158
|
+
)
|
|
155
159
|
try:
|
|
156
160
|
self.eventbus_integration = EventBusIntegration(self)
|
|
161
|
+
print(
|
|
162
|
+
f"[{datetime.now().isoformat()}] EventBusIntegration instance created",
|
|
163
|
+
flush=True,
|
|
164
|
+
)
|
|
165
|
+
|
|
157
166
|
if self.eventbus_integration.setup(self.port):
|
|
158
167
|
self.logger.info("EventBus integration setup successful")
|
|
168
|
+
print(
|
|
169
|
+
f"[{datetime.now().isoformat()}] EventBus integration setup successful",
|
|
170
|
+
flush=True,
|
|
171
|
+
)
|
|
159
172
|
else:
|
|
160
173
|
self.logger.warning("EventBus integration setup failed or disabled")
|
|
174
|
+
print(
|
|
175
|
+
f"[{datetime.now().isoformat()}] EventBus integration setup failed or disabled",
|
|
176
|
+
flush=True,
|
|
177
|
+
)
|
|
161
178
|
except Exception as e:
|
|
162
179
|
self.logger.error(f"Failed to setup EventBus integration: {e}")
|
|
180
|
+
print(
|
|
181
|
+
f"[{datetime.now().isoformat()}] Failed to setup EventBus integration: {e}",
|
|
182
|
+
flush=True,
|
|
183
|
+
)
|
|
184
|
+
import traceback
|
|
185
|
+
|
|
186
|
+
traceback.print_exc()
|
|
163
187
|
self.eventbus_integration = None
|
|
164
188
|
|
|
165
189
|
# Update running state
|
|
@@ -175,7 +199,7 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
175
199
|
# Stop the retry processor if running
|
|
176
200
|
if self.broadcaster:
|
|
177
201
|
self.broadcaster.stop_retry_processor()
|
|
178
|
-
|
|
202
|
+
|
|
179
203
|
# Teardown EventBus integration
|
|
180
204
|
if self.eventbus_integration:
|
|
181
205
|
try:
|
|
@@ -183,14 +207,15 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
183
207
|
self.logger.info("EventBus integration teardown complete")
|
|
184
208
|
except Exception as e:
|
|
185
209
|
self.logger.error(f"Error during EventBus teardown: {e}")
|
|
186
|
-
|
|
210
|
+
|
|
187
211
|
# Stop health monitoring in connection handler
|
|
188
212
|
if self.event_registry:
|
|
189
213
|
from ..handlers import ConnectionEventHandler
|
|
214
|
+
|
|
190
215
|
conn_handler = self.event_registry.get_handler(ConnectionEventHandler)
|
|
191
|
-
if conn_handler and hasattr(conn_handler,
|
|
216
|
+
if conn_handler and hasattr(conn_handler, "stop_health_monitoring"):
|
|
192
217
|
conn_handler.stop_health_monitoring()
|
|
193
|
-
|
|
218
|
+
|
|
194
219
|
self.core.stop_sync()
|
|
195
220
|
self.running = False
|
|
196
221
|
|
|
@@ -219,25 +244,27 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
219
244
|
"""Broadcast an event to all connected clients."""
|
|
220
245
|
if self.broadcaster:
|
|
221
246
|
self.broadcaster.broadcast_event(event_type, data)
|
|
222
|
-
|
|
223
|
-
def send_to_client(
|
|
247
|
+
|
|
248
|
+
def send_to_client(
|
|
249
|
+
self, client_id: str, event_type: str, data: Dict[str, Any]
|
|
250
|
+
) -> bool:
|
|
224
251
|
"""Send an event to a specific client.
|
|
225
|
-
|
|
226
|
-
WHY: The SocketIOServiceInterface requires this method for targeted
|
|
252
|
+
|
|
253
|
+
WHY: The SocketIOServiceInterface requires this method for targeted
|
|
227
254
|
messaging. We delegate to the Socket.IO server's emit method with
|
|
228
255
|
the client's session ID as the room.
|
|
229
|
-
|
|
256
|
+
|
|
230
257
|
Args:
|
|
231
258
|
client_id: ID of the target client
|
|
232
259
|
event_type: Type of event to send
|
|
233
260
|
data: Event data to send
|
|
234
|
-
|
|
261
|
+
|
|
235
262
|
Returns:
|
|
236
263
|
True if message sent successfully
|
|
237
264
|
"""
|
|
238
265
|
if not self.core or not self.core.sio:
|
|
239
266
|
return False
|
|
240
|
-
|
|
267
|
+
|
|
241
268
|
try:
|
|
242
269
|
# Socket.IO uses session IDs as room names for individual clients
|
|
243
270
|
# We can send to a specific client by using their session ID as the room
|
|
@@ -246,7 +273,7 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
246
273
|
if self.core.loop:
|
|
247
274
|
asyncio.run_coroutine_threadsafe(
|
|
248
275
|
self.core.sio.emit(event_type, data, room=client_id),
|
|
249
|
-
self.core.loop
|
|
276
|
+
self.core.loop,
|
|
250
277
|
)
|
|
251
278
|
return True
|
|
252
279
|
return False
|
|
@@ -257,7 +284,7 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
257
284
|
def session_started(self, session_id: str, launch_method: str, working_dir: str):
|
|
258
285
|
"""Notify that a session has started."""
|
|
259
286
|
self.session_id = session_id
|
|
260
|
-
|
|
287
|
+
|
|
261
288
|
# Track active session for heartbeat
|
|
262
289
|
self.active_sessions[session_id] = {
|
|
263
290
|
"session_id": session_id,
|
|
@@ -267,7 +294,7 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
267
294
|
"launch_method": launch_method,
|
|
268
295
|
"working_dir": working_dir,
|
|
269
296
|
}
|
|
270
|
-
|
|
297
|
+
|
|
271
298
|
if self.broadcaster:
|
|
272
299
|
self.broadcaster.session_started(session_id, launch_method, working_dir)
|
|
273
300
|
|
|
@@ -276,7 +303,7 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
276
303
|
# Remove from active sessions
|
|
277
304
|
if self.session_id and self.session_id in self.active_sessions:
|
|
278
305
|
del self.active_sessions[self.session_id]
|
|
279
|
-
|
|
306
|
+
|
|
280
307
|
if self.broadcaster:
|
|
281
308
|
self.broadcaster.session_ended()
|
|
282
309
|
|
|
@@ -300,7 +327,7 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
300
327
|
if self.session_id and self.session_id in self.active_sessions:
|
|
301
328
|
self.active_sessions[self.session_id]["agent"] = agent
|
|
302
329
|
self.active_sessions[self.session_id]["status"] = status
|
|
303
|
-
|
|
330
|
+
|
|
304
331
|
if self.broadcaster:
|
|
305
332
|
self.broadcaster.agent_delegated(agent, task, status)
|
|
306
333
|
|
|
@@ -344,16 +371,16 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
344
371
|
def is_running(self) -> bool:
|
|
345
372
|
"""Check if server is running."""
|
|
346
373
|
return self.core.is_running()
|
|
347
|
-
|
|
374
|
+
|
|
348
375
|
def get_active_sessions(self) -> List[Dict[str, Any]]:
|
|
349
376
|
"""Get list of active sessions for heartbeat.
|
|
350
|
-
|
|
377
|
+
|
|
351
378
|
WHY: Provides session information for system heartbeat events.
|
|
352
379
|
"""
|
|
353
380
|
# Clean up old sessions (older than 1 hour)
|
|
354
381
|
cutoff_time = datetime.now().timestamp() - 3600
|
|
355
382
|
sessions_to_remove = []
|
|
356
|
-
|
|
383
|
+
|
|
357
384
|
for session_id, session_data in self.active_sessions.items():
|
|
358
385
|
try:
|
|
359
386
|
start_time = datetime.fromisoformat(session_data["start_time"])
|
|
@@ -361,14 +388,13 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
361
388
|
sessions_to_remove.append(session_id)
|
|
362
389
|
except:
|
|
363
390
|
pass
|
|
364
|
-
|
|
391
|
+
|
|
365
392
|
for session_id in sessions_to_remove:
|
|
366
393
|
del self.active_sessions[session_id]
|
|
367
|
-
|
|
394
|
+
|
|
368
395
|
# Return list of active sessions
|
|
369
396
|
return list(self.active_sessions.values())
|
|
370
397
|
|
|
371
|
-
|
|
372
398
|
# Legacy compatibility properties
|
|
373
399
|
@property
|
|
374
400
|
def sio(self):
|
|
@@ -15,7 +15,6 @@ WHY this approach:
|
|
|
15
15
|
|
|
16
16
|
import asyncio
|
|
17
17
|
import importlib.metadata
|
|
18
|
-
import json
|
|
19
18
|
import socket
|
|
20
19
|
import threading
|
|
21
20
|
import time
|
|
@@ -34,6 +33,8 @@ except ImportError:
|
|
|
34
33
|
requests = None
|
|
35
34
|
socketio = None
|
|
36
35
|
|
|
36
|
+
import contextlib
|
|
37
|
+
|
|
37
38
|
from ..core.logger import get_logger
|
|
38
39
|
|
|
39
40
|
# Get claude-mpm version for compatibility checking
|
|
@@ -74,11 +75,10 @@ class ServerInfo:
|
|
|
74
75
|
# Simple version comparison - in production use proper semver
|
|
75
76
|
if client_version >= "0.7.0":
|
|
76
77
|
return True, warnings
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return False, warnings
|
|
78
|
+
warnings.append(
|
|
79
|
+
f"Client version {client_version} may not be fully supported"
|
|
80
|
+
)
|
|
81
|
+
return False, warnings
|
|
82
82
|
except Exception as e:
|
|
83
83
|
warnings.append(f"Could not parse version: {e}")
|
|
84
84
|
return False, warnings
|
|
@@ -106,7 +106,7 @@ class SocketIOClientManager:
|
|
|
106
106
|
self.logger.warning("Socket.IO client dependencies not available")
|
|
107
107
|
|
|
108
108
|
def discover_servers(
|
|
109
|
-
self, ports: List[int] = None, hosts: List[str] = None
|
|
109
|
+
self, ports: Optional[List[int]] = None, hosts: Optional[List[str]] = None
|
|
110
110
|
) -> List[ServerInfo]:
|
|
111
111
|
"""Discover available Socket.IO servers.
|
|
112
112
|
|
|
@@ -165,7 +165,7 @@ class SocketIOClientManager:
|
|
|
165
165
|
return discovered
|
|
166
166
|
|
|
167
167
|
def find_best_server(
|
|
168
|
-
self, discovered_servers: List[ServerInfo] = None
|
|
168
|
+
self, discovered_servers: Optional[List[ServerInfo]] = None
|
|
169
169
|
) -> Optional[ServerInfo]:
|
|
170
170
|
"""Find the best compatible server from discovered servers."""
|
|
171
171
|
if discovered_servers is None:
|
|
@@ -272,10 +272,8 @@ class SocketIOClientManager:
|
|
|
272
272
|
except Exception as e:
|
|
273
273
|
self.logger.error(f"❌ Failed to connect to server {server_info.url}: {e}")
|
|
274
274
|
if self.client:
|
|
275
|
-
|
|
275
|
+
with contextlib.suppress(Exception):
|
|
276
276
|
await self.client.disconnect()
|
|
277
|
-
except:
|
|
278
|
-
pass
|
|
279
277
|
self.client = None
|
|
280
278
|
return False
|
|
281
279
|
|
|
@@ -408,7 +406,7 @@ class SocketIOClientManager:
|
|
|
408
406
|
else:
|
|
409
407
|
# Too many failed attempts, wait longer
|
|
410
408
|
self.logger.warning(
|
|
411
|
-
|
|
409
|
+
"⏳ Max connection attempts reached, waiting 30s..."
|
|
412
410
|
)
|
|
413
411
|
await asyncio.sleep(30)
|
|
414
412
|
connection_attempts = 0 # Reset after longer wait
|
|
@@ -10,6 +10,7 @@ This service handles:
|
|
|
10
10
|
Extracted from ClaudeRunner to follow Single Responsibility Principle.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
+
import contextlib
|
|
13
14
|
import os
|
|
14
15
|
import pty
|
|
15
16
|
import select
|
|
@@ -40,11 +41,9 @@ class SubprocessLauncherService(BaseService, SubprocessLauncherInterface):
|
|
|
40
41
|
|
|
41
42
|
async def _initialize(self) -> None:
|
|
42
43
|
"""Initialize the service. No special initialization needed."""
|
|
43
|
-
pass
|
|
44
44
|
|
|
45
45
|
async def _cleanup(self) -> None:
|
|
46
46
|
"""Cleanup service resources. No cleanup needed."""
|
|
47
|
-
pass
|
|
48
47
|
|
|
49
48
|
# Implementation of abstract methods from SubprocessLauncherInterface
|
|
50
49
|
|
|
@@ -206,10 +205,8 @@ class SubprocessLauncherService(BaseService, SubprocessLauncherInterface):
|
|
|
206
205
|
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, original_tty)
|
|
207
206
|
|
|
208
207
|
# Close PTY
|
|
209
|
-
|
|
208
|
+
with contextlib.suppress(Exception):
|
|
210
209
|
os.close(master_fd)
|
|
211
|
-
except:
|
|
212
|
-
pass
|
|
213
210
|
|
|
214
211
|
# Ensure process is terminated
|
|
215
212
|
if "process" in locals() and process.poll() is None:
|
|
@@ -313,9 +310,9 @@ class SubprocessLauncherService(BaseService, SubprocessLauncherInterface):
|
|
|
313
310
|
env = os.environ.copy()
|
|
314
311
|
if base_env:
|
|
315
312
|
env.update(base_env)
|
|
316
|
-
|
|
313
|
+
|
|
317
314
|
# Disable telemetry for Claude Code subprocesses
|
|
318
315
|
# This ensures Claude Code doesn't send telemetry data during runtime
|
|
319
316
|
env["DISABLE_TELEMETRY"] = "1"
|
|
320
|
-
|
|
317
|
+
|
|
321
318
|
return env
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
1
|
"""System instructions service for loading and processing system instructions.
|
|
4
2
|
|
|
5
3
|
This service handles:
|
|
@@ -36,11 +34,9 @@ class SystemInstructionsService(BaseService, SystemInstructionsInterface):
|
|
|
36
34
|
|
|
37
35
|
async def _initialize(self) -> None:
|
|
38
36
|
"""Initialize the service. No special initialization needed."""
|
|
39
|
-
pass
|
|
40
37
|
|
|
41
38
|
async def _cleanup(self) -> None:
|
|
42
39
|
"""Cleanup service resources. No cleanup needed."""
|
|
43
|
-
pass
|
|
44
40
|
|
|
45
41
|
def load_system_instructions(self, instruction_type: str = "default") -> str:
|
|
46
42
|
"""Load and process system instructions from agents/INSTRUCTIONS.md.
|
|
@@ -50,7 +46,7 @@ class SystemInstructionsService(BaseService, SystemInstructionsInterface):
|
|
|
50
46
|
|
|
51
47
|
Now uses the FrameworkLoader for comprehensive instruction loading including:
|
|
52
48
|
- INSTRUCTIONS.md
|
|
53
|
-
- WORKFLOW.md
|
|
49
|
+
- WORKFLOW.md
|
|
54
50
|
- MEMORY.md
|
|
55
51
|
- Actual PM memories from .claude-mpm/memories/PM.md
|
|
56
52
|
- Agent capabilities
|
|
@@ -64,23 +60,28 @@ class SystemInstructionsService(BaseService, SystemInstructionsInterface):
|
|
|
64
60
|
if self._loaded_instructions is not None:
|
|
65
61
|
self.logger.debug("Returning cached system instructions")
|
|
66
62
|
return self._loaded_instructions
|
|
67
|
-
|
|
63
|
+
|
|
68
64
|
# Create FrameworkLoader only once
|
|
69
65
|
if self._framework_loader is None:
|
|
70
66
|
from claude_mpm.core.framework_loader import FrameworkLoader
|
|
67
|
+
|
|
71
68
|
self._framework_loader = FrameworkLoader()
|
|
72
69
|
self.logger.debug("Created new FrameworkLoader instance")
|
|
73
|
-
|
|
70
|
+
|
|
74
71
|
# Load instructions and cache them
|
|
75
72
|
instructions = self._framework_loader.get_framework_instructions()
|
|
76
|
-
|
|
73
|
+
|
|
77
74
|
if instructions:
|
|
78
75
|
self._loaded_instructions = instructions
|
|
79
|
-
self.logger.info(
|
|
76
|
+
self.logger.info(
|
|
77
|
+
"Loaded and cached framework instructions via FrameworkLoader"
|
|
78
|
+
)
|
|
80
79
|
return instructions
|
|
81
|
-
|
|
80
|
+
|
|
82
81
|
# Fallback if FrameworkLoader returns empty
|
|
83
|
-
self.logger.warning(
|
|
82
|
+
self.logger.warning(
|
|
83
|
+
"FrameworkLoader returned empty instructions, using fallback"
|
|
84
|
+
)
|
|
84
85
|
fallback = "# System Instructions\n\nNo specific system instructions found. Using default behavior."
|
|
85
86
|
self._loaded_instructions = fallback
|
|
86
87
|
return fallback
|
|
@@ -177,9 +178,7 @@ class SystemInstructionsService(BaseService, SystemInstructionsInterface):
|
|
|
177
178
|
cleaned = "\n".join(cleaned_lines)
|
|
178
179
|
|
|
179
180
|
# Also remove any leading blank lines that might result
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
return cleaned
|
|
181
|
+
return cleaned.lstrip("\n")
|
|
183
182
|
|
|
184
183
|
except Exception as e:
|
|
185
184
|
self.logger.warning(f"Error stripping metadata comments: {e}")
|
|
@@ -6,7 +6,7 @@ class TicketManager:
|
|
|
6
6
|
|
|
7
7
|
def create_task(self, *args, **kwargs):
|
|
8
8
|
"""Stub method."""
|
|
9
|
-
return
|
|
9
|
+
return
|
|
10
10
|
|
|
11
11
|
def list_recent_tickets(self, *args, **kwargs):
|
|
12
12
|
"""Stub method."""
|
|
@@ -14,7 +14,7 @@ class TicketManager:
|
|
|
14
14
|
|
|
15
15
|
def get_ticket(self, *args, **kwargs):
|
|
16
16
|
"""Stub method."""
|
|
17
|
-
return
|
|
17
|
+
return
|
|
18
18
|
|
|
19
19
|
def update_task(self, *args, **kwargs):
|
|
20
20
|
"""Stub method."""
|
|
@@ -30,11 +30,9 @@ class UtilityService(BaseService, UtilityServiceInterface):
|
|
|
30
30
|
|
|
31
31
|
async def _initialize(self) -> None:
|
|
32
32
|
"""Initialize the service. No special initialization needed."""
|
|
33
|
-
pass
|
|
34
33
|
|
|
35
34
|
async def _cleanup(self) -> None:
|
|
36
35
|
"""Cleanup service resources. No cleanup needed."""
|
|
37
|
-
pass
|
|
38
36
|
|
|
39
37
|
def contains_delegation(self, text: str) -> bool:
|
|
40
38
|
"""Check if text contains signs of agent delegation.
|
|
@@ -112,7 +110,7 @@ class UtilityService(BaseService, UtilityServiceInterface):
|
|
|
112
110
|
with open(log_file, "a") as f:
|
|
113
111
|
f.write(json.dumps(log_entry) + "\n")
|
|
114
112
|
|
|
115
|
-
except
|
|
113
|
+
except OSError as e:
|
|
116
114
|
self.logger.debug(f"IO error logging session event: {e}")
|
|
117
115
|
except Exception as e:
|
|
118
116
|
self.logger.debug(f"Failed to log session event: {e}")
|
|
@@ -130,10 +128,7 @@ class UtilityService(BaseService, UtilityServiceInterface):
|
|
|
130
128
|
return False
|
|
131
129
|
|
|
132
130
|
# Check for minimum length
|
|
133
|
-
|
|
134
|
-
return False
|
|
135
|
-
|
|
136
|
-
return True
|
|
131
|
+
return not len(prompt.strip()) < 3
|
|
137
132
|
|
|
138
133
|
def sanitize_filename(self, filename: str) -> str:
|
|
139
134
|
"""Sanitize a filename by removing invalid characters.
|
|
@@ -174,8 +169,7 @@ class UtilityService(BaseService, UtilityServiceInterface):
|
|
|
174
169
|
|
|
175
170
|
if context:
|
|
176
171
|
return f"{context}: {error_type}: {error_msg}"
|
|
177
|
-
|
|
178
|
-
return f"{error_type}: {error_msg}"
|
|
172
|
+
return f"{error_type}: {error_msg}"
|
|
179
173
|
|
|
180
174
|
def truncate_text(
|
|
181
175
|
self, text: str, max_length: int = 100, suffix: str = "..."
|
|
@@ -210,7 +204,7 @@ class UtilityService(BaseService, UtilityServiceInterface):
|
|
|
210
204
|
pattern = r'(\w+)=(["\']?)([^"\'\s]*)\2'
|
|
211
205
|
matches = re.findall(pattern, text)
|
|
212
206
|
|
|
213
|
-
for key,
|
|
207
|
+
for key, _quote, value in matches:
|
|
214
208
|
pairs[key] = value
|
|
215
209
|
|
|
216
210
|
return pairs
|
|
@@ -280,6 +274,4 @@ class UtilityService(BaseService, UtilityServiceInterface):
|
|
|
280
274
|
return False, "Path cannot be empty"
|
|
281
275
|
return True, None
|
|
282
276
|
except Exception as e:
|
|
283
|
-
return False, f"Path validation error: {
|
|
284
|
-
|
|
285
|
-
|
|
277
|
+
return False, f"Path validation error: {e!s}"
|
|
@@ -39,29 +39,29 @@ from .semantic_versioning import (
|
|
|
39
39
|
)
|
|
40
40
|
|
|
41
41
|
__all__ = [
|
|
42
|
-
|
|
43
|
-
"
|
|
44
|
-
"GitBranchInfo",
|
|
45
|
-
"GitOperationResult",
|
|
46
|
-
"GitOperationError",
|
|
47
|
-
# Semantic Versioning
|
|
48
|
-
"SemanticVersionManager",
|
|
49
|
-
"SemanticVersion",
|
|
50
|
-
"VersionBumpType",
|
|
51
|
-
"VersionMetadata",
|
|
52
|
-
"ChangeAnalysis",
|
|
42
|
+
"BranchLifecycleRule",
|
|
43
|
+
"BranchNamingRule",
|
|
53
44
|
# Branch Strategy
|
|
54
45
|
"BranchStrategyManager",
|
|
55
46
|
"BranchStrategyType",
|
|
56
47
|
"BranchType",
|
|
57
48
|
"BranchWorkflow",
|
|
58
|
-
"
|
|
59
|
-
"
|
|
49
|
+
"ChangeAnalysis",
|
|
50
|
+
"ConflictAnalysis",
|
|
51
|
+
"ConflictResolution",
|
|
60
52
|
# Conflict Resolution
|
|
61
53
|
"ConflictResolutionManager",
|
|
62
54
|
"ConflictType",
|
|
63
|
-
"ResolutionStrategy",
|
|
64
55
|
"FileConflict",
|
|
65
|
-
"
|
|
66
|
-
"
|
|
56
|
+
"GitBranchInfo",
|
|
57
|
+
"GitOperationError",
|
|
58
|
+
"GitOperationResult",
|
|
59
|
+
# Git Operations
|
|
60
|
+
"GitOperationsManager",
|
|
61
|
+
"ResolutionStrategy",
|
|
62
|
+
"SemanticVersion",
|
|
63
|
+
# Semantic Versioning
|
|
64
|
+
"SemanticVersionManager",
|
|
65
|
+
"VersionBumpType",
|
|
66
|
+
"VersionMetadata",
|
|
67
67
|
]
|
|
@@ -358,9 +358,8 @@ class BranchStrategyManager:
|
|
|
358
358
|
self.current_strategy = self.strategies[strategy_type]
|
|
359
359
|
self.logger.info(f"Set branch strategy to {strategy_type.value}")
|
|
360
360
|
return True
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
return False
|
|
361
|
+
self.logger.error(f"Unknown strategy type: {strategy_type}")
|
|
362
|
+
return False
|
|
364
363
|
|
|
365
364
|
def generate_branch_name(
|
|
366
365
|
self,
|
|
@@ -395,10 +394,9 @@ class BranchStrategyManager:
|
|
|
395
394
|
prefix = branch_type.value + "/"
|
|
396
395
|
if ticket_id:
|
|
397
396
|
return f"{prefix}{ticket_id}"
|
|
398
|
-
|
|
397
|
+
if description:
|
|
399
398
|
return f"{prefix}{self._sanitize_branch_name(description)}"
|
|
400
|
-
|
|
401
|
-
return f"{prefix}{datetime.now().strftime('%Y%m%d')}"
|
|
399
|
+
return f"{prefix}{datetime.now().strftime('%Y%m%d')}"
|
|
402
400
|
|
|
403
401
|
# Generate name based on rule
|
|
404
402
|
if strategy.strategy_type == BranchStrategyType.ISSUE_DRIVEN:
|
|
@@ -614,8 +612,7 @@ class BranchStrategyManager:
|
|
|
614
612
|
# Default merge message
|
|
615
613
|
if ticket_title:
|
|
616
614
|
return f"Merge {branch_name}: {ticket_title}"
|
|
617
|
-
|
|
618
|
-
return f"Merge {branch_name}"
|
|
615
|
+
return f"Merge {branch_name}"
|
|
619
616
|
|
|
620
617
|
def get_quality_gates(self) -> List[str]:
|
|
621
618
|
"""Get quality gates for the current strategy."""
|