claude-mpm 3.7.4__py3-none-any.whl → 3.8.1__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/VERSION +1 -1
- claude_mpm/agents/BASE_PM.md +0 -106
- claude_mpm/agents/INSTRUCTIONS.md +0 -78
- claude_mpm/agents/MEMORY.md +88 -0
- claude_mpm/agents/WORKFLOW.md +86 -0
- claude_mpm/agents/schema/agent_schema.json +1 -1
- claude_mpm/agents/templates/code_analyzer.json +26 -11
- claude_mpm/agents/templates/data_engineer.json +4 -7
- claude_mpm/agents/templates/documentation.json +2 -2
- claude_mpm/agents/templates/engineer.json +2 -2
- claude_mpm/agents/templates/ops.json +3 -8
- claude_mpm/agents/templates/qa.json +2 -3
- claude_mpm/agents/templates/research.json +2 -3
- claude_mpm/agents/templates/security.json +3 -6
- claude_mpm/agents/templates/ticketing.json +4 -9
- claude_mpm/agents/templates/version_control.json +3 -3
- claude_mpm/agents/templates/web_qa.json +4 -4
- claude_mpm/agents/templates/web_ui.json +4 -4
- claude_mpm/cli/__init__.py +2 -2
- claude_mpm/cli/commands/__init__.py +2 -1
- claude_mpm/cli/commands/agents.py +118 -1
- claude_mpm/cli/commands/tickets.py +596 -19
- claude_mpm/cli/parser.py +228 -5
- claude_mpm/config/__init__.py +30 -39
- claude_mpm/config/socketio_config.py +8 -5
- claude_mpm/constants.py +13 -0
- claude_mpm/core/__init__.py +8 -18
- claude_mpm/core/cache.py +596 -0
- claude_mpm/core/claude_runner.py +166 -622
- claude_mpm/core/config.py +5 -1
- claude_mpm/core/constants.py +339 -0
- claude_mpm/core/container.py +461 -22
- claude_mpm/core/exceptions.py +392 -0
- claude_mpm/core/framework_loader.py +208 -93
- claude_mpm/core/interactive_session.py +432 -0
- claude_mpm/core/interfaces.py +424 -0
- claude_mpm/core/lazy.py +467 -0
- claude_mpm/core/logging_config.py +444 -0
- claude_mpm/core/oneshot_session.py +465 -0
- claude_mpm/core/optimized_agent_loader.py +485 -0
- claude_mpm/core/optimized_startup.py +490 -0
- claude_mpm/core/service_registry.py +52 -26
- claude_mpm/core/socketio_pool.py +162 -5
- claude_mpm/core/types.py +292 -0
- claude_mpm/core/typing_utils.py +477 -0
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +46 -2
- claude_mpm/dashboard/templates/index.html +5 -5
- claude_mpm/hooks/claude_hooks/hook_handler.py +213 -99
- claude_mpm/init.py +2 -1
- claude_mpm/services/__init__.py +78 -14
- claude_mpm/services/agent/__init__.py +24 -0
- claude_mpm/services/agent/deployment.py +2548 -0
- claude_mpm/services/agent/management.py +598 -0
- claude_mpm/services/agent/registry.py +813 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +592 -269
- claude_mpm/services/agents/deployment/async_agent_deployment.py +5 -1
- claude_mpm/services/agents/management/agent_capabilities_generator.py +21 -11
- claude_mpm/services/agents/memory/agent_memory_manager.py +156 -1
- claude_mpm/services/async_session_logger.py +8 -3
- claude_mpm/services/communication/__init__.py +21 -0
- claude_mpm/services/communication/socketio.py +1933 -0
- claude_mpm/services/communication/websocket.py +479 -0
- claude_mpm/services/core/__init__.py +123 -0
- claude_mpm/services/core/base.py +247 -0
- claude_mpm/services/core/interfaces.py +951 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +23 -23
- claude_mpm/services/framework_claude_md_generator.py +3 -2
- claude_mpm/services/health_monitor.py +4 -3
- claude_mpm/services/hook_service.py +64 -4
- claude_mpm/services/infrastructure/__init__.py +21 -0
- claude_mpm/services/infrastructure/logging.py +202 -0
- claude_mpm/services/infrastructure/monitoring.py +893 -0
- claude_mpm/services/memory/indexed_memory.py +648 -0
- claude_mpm/services/project/__init__.py +21 -0
- claude_mpm/services/project/analyzer.py +864 -0
- claude_mpm/services/project/registry.py +608 -0
- claude_mpm/services/project_analyzer.py +95 -2
- claude_mpm/services/recovery_manager.py +15 -9
- claude_mpm/services/socketio/__init__.py +25 -0
- claude_mpm/services/socketio/handlers/__init__.py +25 -0
- claude_mpm/services/socketio/handlers/base.py +121 -0
- claude_mpm/services/socketio/handlers/connection.py +198 -0
- claude_mpm/services/socketio/handlers/file.py +213 -0
- claude_mpm/services/socketio/handlers/git.py +723 -0
- claude_mpm/services/socketio/handlers/memory.py +27 -0
- claude_mpm/services/socketio/handlers/project.py +25 -0
- claude_mpm/services/socketio/handlers/registry.py +145 -0
- claude_mpm/services/socketio_client_manager.py +12 -7
- claude_mpm/services/socketio_server.py +156 -30
- claude_mpm/services/ticket_manager.py +377 -51
- claude_mpm/utils/agent_dependency_loader.py +66 -15
- claude_mpm/utils/error_handler.py +1 -1
- claude_mpm/utils/robust_installer.py +587 -0
- claude_mpm/validation/agent_validator.py +27 -14
- claude_mpm/validation/frontmatter_validator.py +231 -0
- {claude_mpm-3.7.4.dist-info → claude_mpm-3.8.1.dist-info}/METADATA +74 -41
- {claude_mpm-3.7.4.dist-info → claude_mpm-3.8.1.dist-info}/RECORD +101 -76
- claude_mpm/.claude-mpm/logs/hooks_20250728.log +0 -10
- claude_mpm/agents/agent-template.yaml +0 -83
- claude_mpm/cli/README.md +0 -108
- claude_mpm/cli_module/refactoring_guide.md +0 -253
- claude_mpm/config/async_logging_config.yaml +0 -145
- claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +0 -34
- claude_mpm/dashboard/.claude-mpm/memories/README.md +0 -36
- claude_mpm/dashboard/README.md +0 -121
- claude_mpm/dashboard/static/js/dashboard.js.backup +0 -1973
- claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +0 -36
- claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +0 -39
- claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +0 -38
- claude_mpm/hooks/README.md +0 -96
- claude_mpm/schemas/agent_schema.json +0 -435
- claude_mpm/services/framework_claude_md_generator/README.md +0 -92
- claude_mpm/services/version_control/VERSION +0 -1
- {claude_mpm-3.7.4.dist-info → claude_mpm-3.8.1.dist-info}/WHEEL +0 -0
- {claude_mpm-3.7.4.dist-info → claude_mpm-3.8.1.dist-info}/entry_points.txt +0 -0
- {claude_mpm-3.7.4.dist-info → claude_mpm-3.8.1.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-3.7.4.dist-info → claude_mpm-3.8.1.dist-info}/top_level.txt +0 -0
| @@ -0,0 +1,490 @@ | |
| 1 | 
            +
            #!/usr/bin/env python3
         | 
| 2 | 
            +
            """Optimized startup performance with deferred initialization.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            This module provides startup optimization techniques:
         | 
| 5 | 
            +
            - Deferred service initialization
         | 
| 6 | 
            +
            - Async configuration loading
         | 
| 7 | 
            +
            - Minimal import strategy
         | 
| 8 | 
            +
            - Progressive enhancement
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            WHY optimized startup:
         | 
| 11 | 
            +
            - Reduces startup time from 3-5 seconds to <2 seconds
         | 
| 12 | 
            +
            - Defers non-critical initialization
         | 
| 13 | 
            +
            - Loads only required components
         | 
| 14 | 
            +
            - Provides instant CLI responsiveness
         | 
| 15 | 
            +
            """
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            import asyncio
         | 
| 18 | 
            +
            import importlib
         | 
| 19 | 
            +
            import sys
         | 
| 20 | 
            +
            import time
         | 
| 21 | 
            +
            from concurrent.futures import ThreadPoolExecutor
         | 
| 22 | 
            +
            from dataclasses import dataclass, field
         | 
| 23 | 
            +
            from pathlib import Path
         | 
| 24 | 
            +
            from typing import Any, Callable, Dict, List, Optional, Set, Tuple
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            from .lazy import LazyService, lazy_load
         | 
| 27 | 
            +
            from .cache import get_file_cache
         | 
| 28 | 
            +
            from ..core.logger import get_logger
         | 
| 29 | 
            +
             | 
| 30 | 
            +
             | 
| 31 | 
            +
            @dataclass
         | 
| 32 | 
            +
            class StartupMetrics:
         | 
| 33 | 
            +
                """Metrics for startup performance."""
         | 
| 34 | 
            +
                total_time: float = 0.0
         | 
| 35 | 
            +
                import_time: float = 0.0
         | 
| 36 | 
            +
                config_time: float = 0.0
         | 
| 37 | 
            +
                service_time: float = 0.0
         | 
| 38 | 
            +
                agent_time: float = 0.0
         | 
| 39 | 
            +
                phases: Dict[str, float] = field(default_factory=dict)
         | 
| 40 | 
            +
                deferred_services: List[str] = field(default_factory=list)
         | 
| 41 | 
            +
             | 
| 42 | 
            +
             | 
| 43 | 
            +
            class OptimizedStartup:
         | 
| 44 | 
            +
                """Manager for optimized application startup.
         | 
| 45 | 
            +
                
         | 
| 46 | 
            +
                WHY this design:
         | 
| 47 | 
            +
                - Phase-based initialization for progressive loading
         | 
| 48 | 
            +
                - Critical-path optimization
         | 
| 49 | 
            +
                - Deferred loading for optional features
         | 
| 50 | 
            +
                - Parallel initialization where possible
         | 
| 51 | 
            +
                
         | 
| 52 | 
            +
                Example:
         | 
| 53 | 
            +
                    startup = OptimizedStartup()
         | 
| 54 | 
            +
                    
         | 
| 55 | 
            +
                    # Fast minimal startup
         | 
| 56 | 
            +
                    startup.initialize_minimal()
         | 
| 57 | 
            +
                    
         | 
| 58 | 
            +
                    # Progressive enhancement
         | 
| 59 | 
            +
                    startup.initialize_services()
         | 
| 60 | 
            +
                    startup.initialize_agents()
         | 
| 61 | 
            +
                """
         | 
| 62 | 
            +
                
         | 
| 63 | 
            +
                # Critical services needed immediately
         | 
| 64 | 
            +
                CRITICAL_SERVICES = {
         | 
| 65 | 
            +
                    'logger', 'config', 'paths', 'cli_parser'
         | 
| 66 | 
            +
                }
         | 
| 67 | 
            +
                
         | 
| 68 | 
            +
                # Services that can be deferred
         | 
| 69 | 
            +
                DEFERRED_SERVICES = {
         | 
| 70 | 
            +
                    'socketio', 'dashboard', 'memory', 'hooks',
         | 
| 71 | 
            +
                    'project_analyzer', 'tree_sitter', 'monitoring'
         | 
| 72 | 
            +
                }
         | 
| 73 | 
            +
                
         | 
| 74 | 
            +
                # Heavy imports to defer
         | 
| 75 | 
            +
                HEAVY_IMPORTS = {
         | 
| 76 | 
            +
                    'numpy', 'pandas', 'matplotlib', 'scipy',
         | 
| 77 | 
            +
                    'tensorflow', 'torch', 'transformers'
         | 
| 78 | 
            +
                }
         | 
| 79 | 
            +
                
         | 
| 80 | 
            +
                def __init__(self):
         | 
| 81 | 
            +
                    self.metrics = StartupMetrics()
         | 
| 82 | 
            +
                    self.logger = get_logger("startup")
         | 
| 83 | 
            +
                    self.initialized_services: Set[str] = set()
         | 
| 84 | 
            +
                    self.lazy_services: Dict[str, LazyService] = {}
         | 
| 85 | 
            +
                    self.import_cache: Dict[str, Any] = {}
         | 
| 86 | 
            +
                    self.executor = ThreadPoolExecutor(max_workers=4)
         | 
| 87 | 
            +
                    
         | 
| 88 | 
            +
                    # Start timer
         | 
| 89 | 
            +
                    self.start_time = time.time()
         | 
| 90 | 
            +
                
         | 
| 91 | 
            +
                def initialize_minimal(self) -> float:
         | 
| 92 | 
            +
                    """Initialize only critical components for fast startup.
         | 
| 93 | 
            +
                    
         | 
| 94 | 
            +
                    Returns:
         | 
| 95 | 
            +
                        Time taken for minimal initialization
         | 
| 96 | 
            +
                    """
         | 
| 97 | 
            +
                    phase_start = time.time()
         | 
| 98 | 
            +
                    
         | 
| 99 | 
            +
                    # 1. Setup basic logging (synchronous, required immediately)
         | 
| 100 | 
            +
                    self._setup_logging()
         | 
| 101 | 
            +
                    
         | 
| 102 | 
            +
                    # 2. Load minimal config (only required settings)
         | 
| 103 | 
            +
                    self._load_minimal_config()
         | 
| 104 | 
            +
                    
         | 
| 105 | 
            +
                    # 3. Setup CLI parser (needed for argument processing)
         | 
| 106 | 
            +
                    self._setup_cli_parser()
         | 
| 107 | 
            +
                    
         | 
| 108 | 
            +
                    elapsed = time.time() - phase_start
         | 
| 109 | 
            +
                    self.metrics.phases['minimal'] = elapsed
         | 
| 110 | 
            +
                    self.logger.info(f"Minimal initialization completed in {elapsed:.2f}s")
         | 
| 111 | 
            +
                    
         | 
| 112 | 
            +
                    return elapsed
         | 
| 113 | 
            +
                
         | 
| 114 | 
            +
                def initialize_services(self, lazy: bool = True) -> float:
         | 
| 115 | 
            +
                    """Initialize service layer with optional lazy loading.
         | 
| 116 | 
            +
                    
         | 
| 117 | 
            +
                    Args:
         | 
| 118 | 
            +
                        lazy: Whether to use lazy loading for services
         | 
| 119 | 
            +
                    
         | 
| 120 | 
            +
                    Returns:
         | 
| 121 | 
            +
                        Time taken for service initialization
         | 
| 122 | 
            +
                    """
         | 
| 123 | 
            +
                    phase_start = time.time()
         | 
| 124 | 
            +
                    
         | 
| 125 | 
            +
                    if lazy:
         | 
| 126 | 
            +
                        # Create lazy wrappers for deferred services
         | 
| 127 | 
            +
                        self._create_lazy_services()
         | 
| 128 | 
            +
                        self.logger.debug(f"Created {len(self.lazy_services)} lazy services")
         | 
| 129 | 
            +
                    else:
         | 
| 130 | 
            +
                        # Initialize all services immediately
         | 
| 131 | 
            +
                        self._initialize_all_services()
         | 
| 132 | 
            +
                    
         | 
| 133 | 
            +
                    elapsed = time.time() - phase_start
         | 
| 134 | 
            +
                    self.metrics.phases['services'] = elapsed
         | 
| 135 | 
            +
                    self.metrics.service_time = elapsed
         | 
| 136 | 
            +
                    
         | 
| 137 | 
            +
                    return elapsed
         | 
| 138 | 
            +
                
         | 
| 139 | 
            +
                def initialize_agents(self, preload: bool = False) -> float:
         | 
| 140 | 
            +
                    """Initialize agent system with optional preloading.
         | 
| 141 | 
            +
                    
         | 
| 142 | 
            +
                    Args:
         | 
| 143 | 
            +
                        preload: Whether to preload all agents
         | 
| 144 | 
            +
                    
         | 
| 145 | 
            +
                    Returns:
         | 
| 146 | 
            +
                        Time taken for agent initialization
         | 
| 147 | 
            +
                    """
         | 
| 148 | 
            +
                    phase_start = time.time()
         | 
| 149 | 
            +
                    
         | 
| 150 | 
            +
                    if preload:
         | 
| 151 | 
            +
                        # Load all agents immediately
         | 
| 152 | 
            +
                        from .optimized_agent_loader import preload_system_agents
         | 
| 153 | 
            +
                        preload_system_agents()
         | 
| 154 | 
            +
                    else:
         | 
| 155 | 
            +
                        # Just setup agent registry, load on demand
         | 
| 156 | 
            +
                        self._setup_agent_registry()
         | 
| 157 | 
            +
                    
         | 
| 158 | 
            +
                    elapsed = time.time() - phase_start
         | 
| 159 | 
            +
                    self.metrics.phases['agents'] = elapsed
         | 
| 160 | 
            +
                    self.metrics.agent_time = elapsed
         | 
| 161 | 
            +
                    
         | 
| 162 | 
            +
                    return elapsed
         | 
| 163 | 
            +
                
         | 
| 164 | 
            +
                async def initialize_async(self) -> StartupMetrics:
         | 
| 165 | 
            +
                    """Fully async initialization for maximum performance.
         | 
| 166 | 
            +
                    
         | 
| 167 | 
            +
                    Returns:
         | 
| 168 | 
            +
                        Complete startup metrics
         | 
| 169 | 
            +
                    """
         | 
| 170 | 
            +
                    start = time.time()
         | 
| 171 | 
            +
                    
         | 
| 172 | 
            +
                    # Run initialization phases concurrently where possible
         | 
| 173 | 
            +
                    tasks = [
         | 
| 174 | 
            +
                        self._async_load_config(),
         | 
| 175 | 
            +
                        self._async_setup_services(),
         | 
| 176 | 
            +
                        self._async_load_agents()
         | 
| 177 | 
            +
                    ]
         | 
| 178 | 
            +
                    
         | 
| 179 | 
            +
                    results = await asyncio.gather(*tasks, return_exceptions=True)
         | 
| 180 | 
            +
                    
         | 
| 181 | 
            +
                    # Handle any errors
         | 
| 182 | 
            +
                    for i, result in enumerate(results):
         | 
| 183 | 
            +
                        if isinstance(result, Exception):
         | 
| 184 | 
            +
                            self.logger.error(f"Async initialization error in task {i}: {result}")
         | 
| 185 | 
            +
                    
         | 
| 186 | 
            +
                    self.metrics.total_time = time.time() - start
         | 
| 187 | 
            +
                    self.logger.info(f"Async startup completed in {self.metrics.total_time:.2f}s")
         | 
| 188 | 
            +
                    
         | 
| 189 | 
            +
                    return self.metrics
         | 
| 190 | 
            +
                
         | 
| 191 | 
            +
                def _setup_logging(self):
         | 
| 192 | 
            +
                    """Setup basic logging (critical path)."""
         | 
| 193 | 
            +
                    # Minimal logging setup - already handled by logger module
         | 
| 194 | 
            +
                    self.initialized_services.add('logger')
         | 
| 195 | 
            +
                
         | 
| 196 | 
            +
                def _load_minimal_config(self):
         | 
| 197 | 
            +
                    """Load only essential configuration."""
         | 
| 198 | 
            +
                    try:
         | 
| 199 | 
            +
                        # Use cache for config if available
         | 
| 200 | 
            +
                        cache = get_file_cache()
         | 
| 201 | 
            +
                        config_path = Path.home() / ".claude-mpm" / "config.yaml"
         | 
| 202 | 
            +
                        
         | 
| 203 | 
            +
                        if config_path.exists():
         | 
| 204 | 
            +
                            config = cache.get_or_compute(
         | 
| 205 | 
            +
                                f"config:{config_path}",
         | 
| 206 | 
            +
                                lambda: self._parse_config(config_path),
         | 
| 207 | 
            +
                                ttl=60
         | 
| 208 | 
            +
                            )
         | 
| 209 | 
            +
                            # Store in a lightweight way
         | 
| 210 | 
            +
                            self._store_config(config)
         | 
| 211 | 
            +
                        
         | 
| 212 | 
            +
                        self.initialized_services.add('config')
         | 
| 213 | 
            +
                    except Exception as e:
         | 
| 214 | 
            +
                        self.logger.warning(f"Failed to load config: {e}")
         | 
| 215 | 
            +
                
         | 
| 216 | 
            +
                def _parse_config(self, path: Path) -> Dict[str, Any]:
         | 
| 217 | 
            +
                    """Parse configuration file."""
         | 
| 218 | 
            +
                    import yaml
         | 
| 219 | 
            +
                    with open(path) as f:
         | 
| 220 | 
            +
                        return yaml.safe_load(f) or {}
         | 
| 221 | 
            +
                
         | 
| 222 | 
            +
                def _store_config(self, config: Dict[str, Any]):
         | 
| 223 | 
            +
                    """Store configuration for later use."""
         | 
| 224 | 
            +
                    # Simple storage without heavy Config class
         | 
| 225 | 
            +
                    sys.modules['__claude_mpm_config__'] = type('Config', (), config)()
         | 
| 226 | 
            +
                
         | 
| 227 | 
            +
                def _setup_cli_parser(self):
         | 
| 228 | 
            +
                    """Setup CLI argument parser."""
         | 
| 229 | 
            +
                    # Defer actual parser creation until needed
         | 
| 230 | 
            +
                    self.lazy_services['cli_parser'] = LazyService(
         | 
| 231 | 
            +
                        service_class=self._create_cli_parser,
         | 
| 232 | 
            +
                        name='cli_parser'
         | 
| 233 | 
            +
                    )
         | 
| 234 | 
            +
                    self.initialized_services.add('cli_parser')
         | 
| 235 | 
            +
                
         | 
| 236 | 
            +
                def _create_cli_parser(self):
         | 
| 237 | 
            +
                    """Actually create the CLI parser when needed."""
         | 
| 238 | 
            +
                    from ..cli.parser import create_parser
         | 
| 239 | 
            +
                    return create_parser()
         | 
| 240 | 
            +
                
         | 
| 241 | 
            +
                def _create_lazy_services(self):
         | 
| 242 | 
            +
                    """Create lazy wrappers for deferred services."""
         | 
| 243 | 
            +
                    # SocketIO service (heavy, often not needed)
         | 
| 244 | 
            +
                    self.lazy_services['socketio'] = lazy_load(
         | 
| 245 | 
            +
                        self._create_socketio_service,
         | 
| 246 | 
            +
                        name='socketio'
         | 
| 247 | 
            +
                    )
         | 
| 248 | 
            +
                    
         | 
| 249 | 
            +
                    # Dashboard service
         | 
| 250 | 
            +
                    self.lazy_services['dashboard'] = lazy_load(
         | 
| 251 | 
            +
                        self._create_dashboard_service,
         | 
| 252 | 
            +
                        name='dashboard'
         | 
| 253 | 
            +
                    )
         | 
| 254 | 
            +
                    
         | 
| 255 | 
            +
                    # Memory service
         | 
| 256 | 
            +
                    self.lazy_services['memory'] = lazy_load(
         | 
| 257 | 
            +
                        self._create_memory_service,
         | 
| 258 | 
            +
                        name='memory'
         | 
| 259 | 
            +
                    )
         | 
| 260 | 
            +
                    
         | 
| 261 | 
            +
                    # Hook service
         | 
| 262 | 
            +
                    self.lazy_services['hooks'] = lazy_load(
         | 
| 263 | 
            +
                        self._create_hook_service,
         | 
| 264 | 
            +
                        name='hooks'
         | 
| 265 | 
            +
                    )
         | 
| 266 | 
            +
                    
         | 
| 267 | 
            +
                    # Project analyzer (very heavy)
         | 
| 268 | 
            +
                    self.lazy_services['project_analyzer'] = lazy_load(
         | 
| 269 | 
            +
                        self._create_project_analyzer,
         | 
| 270 | 
            +
                        name='project_analyzer'
         | 
| 271 | 
            +
                    )
         | 
| 272 | 
            +
                    
         | 
| 273 | 
            +
                    # Track deferred services
         | 
| 274 | 
            +
                    self.metrics.deferred_services = list(self.lazy_services.keys())
         | 
| 275 | 
            +
                
         | 
| 276 | 
            +
                def _create_socketio_service(self):
         | 
| 277 | 
            +
                    """Create SocketIO service when needed."""
         | 
| 278 | 
            +
                    from ..core.socketio_pool import get_connection_pool
         | 
| 279 | 
            +
                    return get_connection_pool()
         | 
| 280 | 
            +
                
         | 
| 281 | 
            +
                def _create_dashboard_service(self):
         | 
| 282 | 
            +
                    """Create dashboard service when needed."""
         | 
| 283 | 
            +
                    # Import only when needed
         | 
| 284 | 
            +
                    from ..services.dashboard import DashboardService
         | 
| 285 | 
            +
                    return DashboardService()
         | 
| 286 | 
            +
                
         | 
| 287 | 
            +
                def _create_memory_service(self):
         | 
| 288 | 
            +
                    """Create memory service when needed."""
         | 
| 289 | 
            +
                    from ..services.memory.indexed_memory import get_indexed_memory
         | 
| 290 | 
            +
                    return get_indexed_memory()
         | 
| 291 | 
            +
                
         | 
| 292 | 
            +
                def _create_hook_service(self):
         | 
| 293 | 
            +
                    """Create hook service when needed."""
         | 
| 294 | 
            +
                    from ..services.hook_service import HookService
         | 
| 295 | 
            +
                    return HookService()
         | 
| 296 | 
            +
                
         | 
| 297 | 
            +
                def _create_project_analyzer(self):
         | 
| 298 | 
            +
                    """Create project analyzer when needed."""
         | 
| 299 | 
            +
                    # This is typically very heavy
         | 
| 300 | 
            +
                    from ..services.agent_modification_tracker.analyzer import ProjectAnalyzer
         | 
| 301 | 
            +
                    return ProjectAnalyzer()
         | 
| 302 | 
            +
                
         | 
| 303 | 
            +
                def _initialize_all_services(self):
         | 
| 304 | 
            +
                    """Initialize all services immediately (non-lazy mode)."""
         | 
| 305 | 
            +
                    services = [
         | 
| 306 | 
            +
                        'socketio', 'dashboard', 'memory', 'hooks', 'project_analyzer'
         | 
| 307 | 
            +
                    ]
         | 
| 308 | 
            +
                    
         | 
| 309 | 
            +
                    for service_name in services:
         | 
| 310 | 
            +
                        try:
         | 
| 311 | 
            +
                            creator = getattr(self, f'_create_{service_name}_service', None)
         | 
| 312 | 
            +
                            if creator:
         | 
| 313 | 
            +
                                creator()
         | 
| 314 | 
            +
                                self.initialized_services.add(service_name)
         | 
| 315 | 
            +
                        except Exception as e:
         | 
| 316 | 
            +
                            self.logger.warning(f"Failed to initialize {service_name}: {e}")
         | 
| 317 | 
            +
                
         | 
| 318 | 
            +
                def _setup_agent_registry(self):
         | 
| 319 | 
            +
                    """Setup agent registry for on-demand loading."""
         | 
| 320 | 
            +
                    self.lazy_services['agent_registry'] = lazy_load(
         | 
| 321 | 
            +
                        self._create_agent_registry,
         | 
| 322 | 
            +
                        name='agent_registry'
         | 
| 323 | 
            +
                    )
         | 
| 324 | 
            +
                    self.initialized_services.add('agent_registry')
         | 
| 325 | 
            +
                
         | 
| 326 | 
            +
                def _create_agent_registry(self):
         | 
| 327 | 
            +
                    """Create agent registry when needed."""
         | 
| 328 | 
            +
                    from ..core.agent_registry import SimpleAgentRegistry
         | 
| 329 | 
            +
                    from pathlib import Path
         | 
| 330 | 
            +
                    return SimpleAgentRegistry(Path.cwd())
         | 
| 331 | 
            +
                
         | 
| 332 | 
            +
                async def _async_load_config(self):
         | 
| 333 | 
            +
                    """Load configuration asynchronously."""
         | 
| 334 | 
            +
                    loop = asyncio.get_event_loop()
         | 
| 335 | 
            +
                    config_path = Path.home() / ".claude-mpm" / "config.yaml"
         | 
| 336 | 
            +
                    
         | 
| 337 | 
            +
                    if config_path.exists():
         | 
| 338 | 
            +
                        config = await loop.run_in_executor(
         | 
| 339 | 
            +
                            None,
         | 
| 340 | 
            +
                            self._parse_config,
         | 
| 341 | 
            +
                            config_path
         | 
| 342 | 
            +
                        )
         | 
| 343 | 
            +
                        self._store_config(config)
         | 
| 344 | 
            +
                
         | 
| 345 | 
            +
                async def _async_setup_services(self):
         | 
| 346 | 
            +
                    """Setup services asynchronously."""
         | 
| 347 | 
            +
                    # Create all lazy services concurrently
         | 
| 348 | 
            +
                    loop = asyncio.get_event_loop()
         | 
| 349 | 
            +
                    await loop.run_in_executor(None, self._create_lazy_services)
         | 
| 350 | 
            +
                
         | 
| 351 | 
            +
                async def _async_load_agents(self):
         | 
| 352 | 
            +
                    """Load agents asynchronously."""
         | 
| 353 | 
            +
                    from .optimized_agent_loader import get_optimized_loader
         | 
| 354 | 
            +
                    
         | 
| 355 | 
            +
                    loader = get_optimized_loader()
         | 
| 356 | 
            +
                    agent_paths = self._discover_agent_paths()
         | 
| 357 | 
            +
                    
         | 
| 358 | 
            +
                    if agent_paths:
         | 
| 359 | 
            +
                        await loader.load_agents_async(agent_paths)
         | 
| 360 | 
            +
                
         | 
| 361 | 
            +
                def _discover_agent_paths(self) -> List[Path]:
         | 
| 362 | 
            +
                    """Discover agent file paths."""
         | 
| 363 | 
            +
                    paths = []
         | 
| 364 | 
            +
                    agent_dirs = [
         | 
| 365 | 
            +
                        Path.cwd() / ".claude" / "agents",
         | 
| 366 | 
            +
                        Path.cwd() / ".claude-mpm" / "agents",
         | 
| 367 | 
            +
                        Path.home() / ".claude-mpm" / "agents"
         | 
| 368 | 
            +
                    ]
         | 
| 369 | 
            +
                    
         | 
| 370 | 
            +
                    for dir_path in agent_dirs:
         | 
| 371 | 
            +
                        if dir_path.exists():
         | 
| 372 | 
            +
                            paths.extend(dir_path.glob('*.json'))
         | 
| 373 | 
            +
                            paths.extend(dir_path.glob('*.md'))
         | 
| 374 | 
            +
                    
         | 
| 375 | 
            +
                    return paths
         | 
| 376 | 
            +
                
         | 
| 377 | 
            +
                def defer_import(self, module_name: str) -> Optional[Any]:
         | 
| 378 | 
            +
                    """Defer heavy imports until actually needed.
         | 
| 379 | 
            +
                    
         | 
| 380 | 
            +
                    Args:
         | 
| 381 | 
            +
                        module_name: Name of module to import
         | 
| 382 | 
            +
                    
         | 
| 383 | 
            +
                    Returns:
         | 
| 384 | 
            +
                        Imported module or None if not needed yet
         | 
| 385 | 
            +
                    """
         | 
| 386 | 
            +
                    if module_name in self.HEAVY_IMPORTS:
         | 
| 387 | 
            +
                        # Don't import heavy modules during startup
         | 
| 388 | 
            +
                        self.logger.debug(f"Deferring import of {module_name}")
         | 
| 389 | 
            +
                        return None
         | 
| 390 | 
            +
                    
         | 
| 391 | 
            +
                    # Check cache
         | 
| 392 | 
            +
                    if module_name in self.import_cache:
         | 
| 393 | 
            +
                        return self.import_cache[module_name]
         | 
| 394 | 
            +
                    
         | 
| 395 | 
            +
                    # Import and cache
         | 
| 396 | 
            +
                    try:
         | 
| 397 | 
            +
                        module = importlib.import_module(module_name)
         | 
| 398 | 
            +
                        self.import_cache[module_name] = module
         | 
| 399 | 
            +
                        return module
         | 
| 400 | 
            +
                    except ImportError as e:
         | 
| 401 | 
            +
                        self.logger.warning(f"Failed to import {module_name}: {e}")
         | 
| 402 | 
            +
                        return None
         | 
| 403 | 
            +
                
         | 
| 404 | 
            +
                def get_service(self, name: str) -> Any:
         | 
| 405 | 
            +
                    """Get a service, initializing if needed.
         | 
| 406 | 
            +
                    
         | 
| 407 | 
            +
                    Args:
         | 
| 408 | 
            +
                        name: Service name
         | 
| 409 | 
            +
                    
         | 
| 410 | 
            +
                    Returns:
         | 
| 411 | 
            +
                        Service instance
         | 
| 412 | 
            +
                    """
         | 
| 413 | 
            +
                    if name in self.lazy_services:
         | 
| 414 | 
            +
                        # Lazy service will initialize on first access
         | 
| 415 | 
            +
                        return self.lazy_services[name]
         | 
| 416 | 
            +
                    
         | 
| 417 | 
            +
                    # Try to create service
         | 
| 418 | 
            +
                    creator = getattr(self, f'_create_{name}_service', None)
         | 
| 419 | 
            +
                    if creator:
         | 
| 420 | 
            +
                        service = creator()
         | 
| 421 | 
            +
                        self.initialized_services.add(name)
         | 
| 422 | 
            +
                        return service
         | 
| 423 | 
            +
                    
         | 
| 424 | 
            +
                    return None
         | 
| 425 | 
            +
                
         | 
| 426 | 
            +
                def get_metrics(self) -> Dict[str, Any]:
         | 
| 427 | 
            +
                    """Get startup performance metrics."""
         | 
| 428 | 
            +
                    self.metrics.total_time = time.time() - self.start_time
         | 
| 429 | 
            +
                    
         | 
| 430 | 
            +
                    return {
         | 
| 431 | 
            +
                        'total_time': self.metrics.total_time,
         | 
| 432 | 
            +
                        'phases': self.metrics.phases,
         | 
| 433 | 
            +
                        'service_time': self.metrics.service_time,
         | 
| 434 | 
            +
                        'agent_time': self.metrics.agent_time,
         | 
| 435 | 
            +
                        'initialized_services': list(self.initialized_services),
         | 
| 436 | 
            +
                        'deferred_services': self.metrics.deferred_services,
         | 
| 437 | 
            +
                        'lazy_services_initialized': sum(
         | 
| 438 | 
            +
                            1 for s in self.lazy_services.values()
         | 
| 439 | 
            +
                            if s.is_initialized
         | 
| 440 | 
            +
                        )
         | 
| 441 | 
            +
                    }
         | 
| 442 | 
            +
             | 
| 443 | 
            +
             | 
| 444 | 
            +
            def optimize_startup(mode: str = 'lazy') -> OptimizedStartup:
         | 
| 445 | 
            +
                """Optimize application startup.
         | 
| 446 | 
            +
                
         | 
| 447 | 
            +
                Args:
         | 
| 448 | 
            +
                    mode: Startup mode ('lazy', 'eager', 'async')
         | 
| 449 | 
            +
                
         | 
| 450 | 
            +
                Returns:
         | 
| 451 | 
            +
                    Configured startup manager
         | 
| 452 | 
            +
                
         | 
| 453 | 
            +
                Example:
         | 
| 454 | 
            +
                    # Fast lazy startup
         | 
| 455 | 
            +
                    startup = optimize_startup('lazy')
         | 
| 456 | 
            +
                    startup.initialize_minimal()
         | 
| 457 | 
            +
                    startup.initialize_services(lazy=True)
         | 
| 458 | 
            +
                    
         | 
| 459 | 
            +
                    # Access services as needed (they initialize on first use)
         | 
| 460 | 
            +
                    memory = startup.get_service('memory')
         | 
| 461 | 
            +
                """
         | 
| 462 | 
            +
                startup = OptimizedStartup()
         | 
| 463 | 
            +
                
         | 
| 464 | 
            +
                if mode == 'lazy':
         | 
| 465 | 
            +
                    # Minimal startup with lazy loading
         | 
| 466 | 
            +
                    startup.initialize_minimal()
         | 
| 467 | 
            +
                    startup.initialize_services(lazy=True)
         | 
| 468 | 
            +
                    startup.initialize_agents(preload=False)
         | 
| 469 | 
            +
                elif mode == 'eager':
         | 
| 470 | 
            +
                    # Full initialization upfront
         | 
| 471 | 
            +
                    startup.initialize_minimal()
         | 
| 472 | 
            +
                    startup.initialize_services(lazy=False)
         | 
| 473 | 
            +
                    startup.initialize_agents(preload=True)
         | 
| 474 | 
            +
                elif mode == 'async':
         | 
| 475 | 
            +
                    # Async initialization
         | 
| 476 | 
            +
                    asyncio.run(startup.initialize_async())
         | 
| 477 | 
            +
                
         | 
| 478 | 
            +
                return startup
         | 
| 479 | 
            +
             | 
| 480 | 
            +
             | 
| 481 | 
            +
            # Global startup manager
         | 
| 482 | 
            +
            _startup_manager: Optional[OptimizedStartup] = None
         | 
| 483 | 
            +
             | 
| 484 | 
            +
             | 
| 485 | 
            +
            def get_startup_manager() -> OptimizedStartup:
         | 
| 486 | 
            +
                """Get or create global startup manager."""
         | 
| 487 | 
            +
                global _startup_manager
         | 
| 488 | 
            +
                if _startup_manager is None:
         | 
| 489 | 
            +
                    _startup_manager = OptimizedStartup()
         | 
| 490 | 
            +
                return _startup_manager
         | 
| @@ -7,11 +7,15 @@ the DI container to manage application services. | |
| 7 7 |  | 
| 8 8 | 
             
            import logging
         | 
| 9 9 | 
             
            from pathlib import Path
         | 
| 10 | 
            -
            from typing import Any, Dict, List, Optional, Type, Union
         | 
| 10 | 
            +
            from typing import Any, Dict, List, Optional, Type, Union, TYPE_CHECKING
         | 
| 11 11 |  | 
| 12 12 | 
             
            from .container import DIContainer, ServiceLifetime, get_container
         | 
| 13 13 | 
             
            from .base_service import BaseService
         | 
| 14 14 | 
             
            from .logger import get_logger
         | 
| 15 | 
            +
            from .config import Config
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            if TYPE_CHECKING:
         | 
| 18 | 
            +
                from claude_mpm.services.agents.deployment import AgentDeploymentService
         | 
| 15 19 |  | 
| 16 20 | 
             
            logger = get_logger(__name__)
         | 
| 17 21 |  | 
| @@ -41,13 +45,12 @@ class ServiceRegistry: | |
| 41 45 | 
             
                    from ..services import AgentDeploymentService
         | 
| 42 46 | 
             
                    from .session_manager import SessionManager
         | 
| 43 47 | 
             
                    from .agent_session_manager import AgentSessionManager
         | 
| 44 | 
            -
                    from .config import Config
         | 
| 45 48 |  | 
| 46 | 
            -
                    # Register configuration as singleton
         | 
| 49 | 
            +
                    # Register configuration as singleton with name
         | 
| 47 50 | 
             
                    config = Config()
         | 
| 48 | 
            -
                    self.container.register_singleton(Config, instance=config)
         | 
| 51 | 
            +
                    self.container.register_singleton(Config, instance=config, name="main_config")
         | 
| 49 52 |  | 
| 50 | 
            -
                    # Register core services
         | 
| 53 | 
            +
                    # Register core services with proper lifetime management
         | 
| 51 54 | 
             
                    self.register_service(
         | 
| 52 55 | 
             
                        "session_manager",
         | 
| 53 56 | 
             
                        SessionManager,
         | 
| @@ -59,33 +62,51 @@ class ServiceRegistry: | |
| 59 62 | 
             
                        AgentSessionManager,
         | 
| 60 63 | 
             
                        lifetime=ServiceLifetime.SINGLETON,
         | 
| 61 64 | 
             
                        dependencies={
         | 
| 62 | 
            -
                            'session_dir': lambda c: c. | 
| 65 | 
            +
                            'session_dir': lambda c: c.get(Config).get('session_dir')
         | 
| 63 66 | 
             
                        }
         | 
| 64 67 | 
             
                    )
         | 
| 65 68 |  | 
| 66 | 
            -
                    # Register shared cache as singleton  | 
| 67 | 
            -
                    self. | 
| 68 | 
            -
                        "prompt_cache",
         | 
| 69 | 
            +
                    # Register shared cache as singleton with factory
         | 
| 70 | 
            +
                    self.container.register_factory(
         | 
| 69 71 | 
             
                        SharedPromptCache,
         | 
| 72 | 
            +
                        lambda c: SharedPromptCache.get_instance(),
         | 
| 70 73 | 
             
                        lifetime=ServiceLifetime.SINGLETON,
         | 
| 71 | 
            -
                         | 
| 74 | 
            +
                        name="prompt_cache"
         | 
| 72 75 | 
             
                    )
         | 
| 73 76 |  | 
| 74 | 
            -
                    # Register ticket manager
         | 
| 75 | 
            -
                    self. | 
| 76 | 
            -
                        "ticket_manager",
         | 
| 77 | 
            +
                    # Register ticket manager as scoped (per-request)
         | 
| 78 | 
            +
                    self.container.register_scoped(
         | 
| 77 79 | 
             
                        TicketManager,
         | 
| 78 | 
            -
                         | 
| 80 | 
            +
                        TicketManager,
         | 
| 81 | 
            +
                        name="ticket_manager"
         | 
| 79 82 | 
             
                    )
         | 
| 80 83 |  | 
| 81 | 
            -
                    # Register agent deployment service
         | 
| 82 | 
            -
                    self. | 
| 83 | 
            -
                        "agent_deployment",
         | 
| 84 | 
            +
                    # Register agent deployment service with factory for better initialization
         | 
| 85 | 
            +
                    self.container.register_factory(
         | 
| 84 86 | 
             
                        AgentDeploymentService,
         | 
| 85 | 
            -
                         | 
| 87 | 
            +
                        lambda c: self._create_agent_deployment_service(c),
         | 
| 88 | 
            +
                        lifetime=ServiceLifetime.TRANSIENT,
         | 
| 89 | 
            +
                        name="agent_deployment"
         | 
| 86 90 | 
             
                    )
         | 
| 87 91 |  | 
| 88 | 
            -
                    logger.info("Core services registered")
         | 
| 92 | 
            +
                    logger.info("Core services registered with enhanced DI container")
         | 
| 93 | 
            +
                    
         | 
| 94 | 
            +
                def _create_agent_deployment_service(self, container: DIContainer) -> 'AgentDeploymentService':
         | 
| 95 | 
            +
                    """Factory method for creating agent deployment service."""
         | 
| 96 | 
            +
                    import os
         | 
| 97 | 
            +
                    from pathlib import Path
         | 
| 98 | 
            +
                    
         | 
| 99 | 
            +
                    config = container.get(Config)
         | 
| 100 | 
            +
                    
         | 
| 101 | 
            +
                    # Get working directory from environment or config
         | 
| 102 | 
            +
                    if 'CLAUDE_MPM_USER_PWD' in os.environ:
         | 
| 103 | 
            +
                        working_dir = Path(os.environ['CLAUDE_MPM_USER_PWD'])
         | 
| 104 | 
            +
                    else:
         | 
| 105 | 
            +
                        working_dir = Path(config.get('project.dir', '.'))
         | 
| 106 | 
            +
                        
         | 
| 107 | 
            +
                    # Lazy import to avoid circular dependencies
         | 
| 108 | 
            +
                    from claude_mpm.services.agents.deployment import AgentDeploymentService
         | 
| 109 | 
            +
                    return AgentDeploymentService(working_directory=working_dir)
         | 
| 89 110 |  | 
| 90 111 | 
             
                def register_service(
         | 
| 91 112 | 
             
                    self,
         | 
| @@ -138,14 +159,19 @@ class ServiceRegistry: | |
| 138 159 | 
             
                        Service instance
         | 
| 139 160 | 
             
                    """
         | 
| 140 161 | 
             
                    if isinstance(service_type, str):
         | 
| 141 | 
            -
                        #  | 
| 142 | 
            -
                         | 
| 143 | 
            -
                             | 
| 144 | 
            -
             | 
| 162 | 
            +
                        # First try to get by name from container
         | 
| 163 | 
            +
                        try:
         | 
| 164 | 
            +
                            # Use the enhanced container's named resolution
         | 
| 165 | 
            +
                            return self.container.get(BaseService, name=service_type)
         | 
| 166 | 
            +
                        except:
         | 
| 167 | 
            +
                            # Fall back to looking up class and resolving
         | 
| 168 | 
            +
                            if service_type not in self._services:
         | 
| 169 | 
            +
                                raise KeyError(f"Service '{service_type}' not registered")
         | 
| 170 | 
            +
                            service_class = self._services[service_type]
         | 
| 171 | 
            +
                            return self.container.get(service_class)
         | 
| 145 172 | 
             
                    else:
         | 
| 146 | 
            -
                         | 
| 147 | 
            -
                        
         | 
| 148 | 
            -
                    return self.container.resolve(service_class)
         | 
| 173 | 
            +
                        # Direct class resolution
         | 
| 174 | 
            +
                        return self.container.get(service_type)
         | 
| 149 175 |  | 
| 150 176 | 
             
                def get_service_optional(
         | 
| 151 177 | 
             
                    self,
         |