claude-mpm 3.1.3__py3-none-any.whl → 3.2.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/__init__.py +3 -3
 - claude_mpm/__main__.py +0 -17
 - claude_mpm/agents/INSTRUCTIONS.md +81 -18
 - claude_mpm/agents/backups/INSTRUCTIONS.md +238 -0
 - claude_mpm/agents/base_agent.json +1 -1
 - claude_mpm/agents/templates/pm.json +25 -0
 - claude_mpm/agents/templates/research.json +2 -1
 - claude_mpm/cli/__init__.py +19 -23
 - claude_mpm/cli/commands/__init__.py +3 -1
 - claude_mpm/cli/commands/agents.py +7 -18
 - claude_mpm/cli/commands/info.py +5 -10
 - claude_mpm/cli/commands/memory.py +232 -0
 - claude_mpm/cli/commands/run.py +501 -28
 - claude_mpm/cli/commands/tickets.py +10 -17
 - claude_mpm/cli/commands/ui.py +15 -37
 - claude_mpm/cli/parser.py +91 -1
 - claude_mpm/cli/utils.py +9 -28
 - claude_mpm/config/socketio_config.py +256 -0
 - claude_mpm/constants.py +9 -0
 - claude_mpm/core/__init__.py +2 -2
 - claude_mpm/core/agent_registry.py +4 -4
 - claude_mpm/core/claude_runner.py +919 -0
 - claude_mpm/core/config.py +21 -1
 - claude_mpm/core/factories.py +1 -1
 - claude_mpm/core/hook_manager.py +196 -0
 - claude_mpm/core/pm_hook_interceptor.py +205 -0
 - claude_mpm/core/service_registry.py +1 -1
 - claude_mpm/core/simple_runner.py +323 -33
 - claude_mpm/core/socketio_pool.py +582 -0
 - claude_mpm/core/websocket_handler.py +233 -0
 - claude_mpm/deployment_paths.py +261 -0
 - claude_mpm/hooks/builtin/memory_hooks_example.py +67 -0
 - claude_mpm/hooks/claude_hooks/hook_handler.py +667 -679
 - claude_mpm/hooks/claude_hooks/hook_wrapper.sh +9 -4
 - claude_mpm/hooks/memory_integration_hook.py +312 -0
 - claude_mpm/models/__init__.py +9 -91
 - claude_mpm/orchestration/__init__.py +1 -1
 - claude_mpm/scripts/claude-mpm-socketio +32 -0
 - claude_mpm/scripts/claude_mpm_monitor.html +567 -0
 - claude_mpm/scripts/install_socketio_server.py +407 -0
 - claude_mpm/scripts/launch_monitor.py +132 -0
 - claude_mpm/scripts/manage_version.py +479 -0
 - claude_mpm/scripts/socketio_daemon.py +181 -0
 - claude_mpm/scripts/socketio_server_manager.py +428 -0
 - claude_mpm/services/__init__.py +5 -0
 - claude_mpm/services/agent_lifecycle_manager.py +76 -25
 - claude_mpm/services/agent_memory_manager.py +684 -0
 - claude_mpm/services/agent_modification_tracker.py +98 -17
 - claude_mpm/services/agent_persistence_service.py +33 -13
 - claude_mpm/services/agent_registry.py +82 -43
 - claude_mpm/services/hook_service.py +362 -0
 - claude_mpm/services/socketio_client_manager.py +474 -0
 - claude_mpm/services/socketio_server.py +698 -0
 - claude_mpm/services/standalone_socketio_server.py +631 -0
 - claude_mpm/services/ticket_manager.py +4 -5
 - claude_mpm/services/{ticket_manager_dependency_injection.py → ticket_manager_di.py} +12 -39
 - claude_mpm/services/{legacy_ticketing_service.py → ticketing_service_original.py} +9 -16
 - claude_mpm/services/version_control/semantic_versioning.py +9 -10
 - claude_mpm/services/websocket_server.py +376 -0
 - claude_mpm/utils/dependency_manager.py +211 -0
 - claude_mpm/utils/import_migration_example.py +80 -0
 - claude_mpm/utils/path_operations.py +0 -20
 - claude_mpm/web/open_dashboard.py +34 -0
 - {claude_mpm-3.1.3.dist-info → claude_mpm-3.2.1.dist-info}/METADATA +20 -9
 - {claude_mpm-3.1.3.dist-info → claude_mpm-3.2.1.dist-info}/RECORD +70 -50
 - claude_mpm-3.2.1.dist-info/entry_points.txt +7 -0
 - claude_mpm/cli_old.py +0 -728
 - claude_mpm/models/common.py +0 -41
 - claude_mpm/models/lifecycle.py +0 -97
 - claude_mpm/models/modification.py +0 -126
 - claude_mpm/models/persistence.py +0 -57
 - claude_mpm/models/registry.py +0 -91
 - claude_mpm/security/__init__.py +0 -8
 - claude_mpm/security/bash_validator.py +0 -393
 - claude_mpm-3.1.3.dist-info/entry_points.txt +0 -4
 - /claude_mpm/{cli_enhancements.py → experimental/cli_enhancements.py} +0 -0
 - {claude_mpm-3.1.3.dist-info → claude_mpm-3.2.1.dist-info}/WHEEL +0 -0
 - {claude_mpm-3.1.3.dist-info → claude_mpm-3.2.1.dist-info}/licenses/LICENSE +0 -0
 - {claude_mpm-3.1.3.dist-info → claude_mpm-3.2.1.dist-info}/top_level.txt +0 -0
 
| 
         @@ -28,8 +28,9 @@ import os 
     | 
|
| 
       28 
28 
     | 
    
         
             
            import shutil
         
     | 
| 
       29 
29 
     | 
    
         
             
            import time
         
     | 
| 
       30 
30 
     | 
    
         
             
            import uuid
         
     | 
| 
       31 
     | 
    
         
            -
            from dataclasses import asdict
         
     | 
| 
      
 31 
     | 
    
         
            +
            from dataclasses import dataclass, field, asdict
         
     | 
| 
       32 
32 
     | 
    
         
             
            from datetime import datetime
         
     | 
| 
      
 33 
     | 
    
         
            +
            from enum import Enum
         
     | 
| 
       33 
34 
     | 
    
         
             
            from pathlib import Path
         
     | 
| 
       34 
35 
     | 
    
         
             
            from typing import Dict, List, Optional, Any, Callable, Tuple, Set
         
     | 
| 
       35 
36 
     | 
    
         | 
| 
         @@ -39,25 +40,105 @@ from watchdog.events import FileSystemEventHandler, FileSystemEvent 
     | 
|
| 
       39 
40 
     | 
    
         
             
            from claude_mpm.core.base_service import BaseService
         
     | 
| 
       40 
41 
     | 
    
         
             
            from claude_mpm.services.shared_prompt_cache import SharedPromptCache
         
     | 
| 
       41 
42 
     | 
    
         
             
            from claude_mpm.services.agent_registry import AgentRegistry
         
     | 
| 
       42 
     | 
    
         
            -
            from claude_mpm.models.modification import (
         
     | 
| 
       43 
     | 
    
         
            -
                ModificationType,
         
     | 
| 
       44 
     | 
    
         
            -
                ModificationTier,
         
     | 
| 
       45 
     | 
    
         
            -
                AgentModification,
         
     | 
| 
       46 
     | 
    
         
            -
                ModificationHistory
         
     | 
| 
       47 
     | 
    
         
            -
            )
         
     | 
| 
       48 
43 
     | 
    
         
             
            from claude_mpm.utils.path_operations import path_ops
         
     | 
| 
       49 
44 
     | 
    
         
             
            from claude_mpm.utils.config_manager import ConfigurationManager
         
     | 
| 
       50 
45 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
            #  
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                 
     | 
| 
       58 
     | 
    
         
            -
                 
     | 
| 
       59 
     | 
    
         
            -
                 
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            # ============================================================================
         
     | 
| 
      
 48 
     | 
    
         
            +
            # Data Models
         
     | 
| 
      
 49 
     | 
    
         
            +
            # ============================================================================
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            class ModificationType(Enum):
         
     | 
| 
      
 52 
     | 
    
         
            +
                """Types of agent modifications."""
         
     | 
| 
      
 53 
     | 
    
         
            +
                CREATE = "create"
         
     | 
| 
      
 54 
     | 
    
         
            +
                MODIFY = "modify"
         
     | 
| 
      
 55 
     | 
    
         
            +
                DELETE = "delete"
         
     | 
| 
      
 56 
     | 
    
         
            +
                MOVE = "move"
         
     | 
| 
      
 57 
     | 
    
         
            +
                RESTORE = "restore"
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            class ModificationTier(Enum):
         
     | 
| 
      
 61 
     | 
    
         
            +
                """Agent hierarchy tiers for modification tracking."""
         
     | 
| 
      
 62 
     | 
    
         
            +
                PROJECT = "project"
         
     | 
| 
      
 63 
     | 
    
         
            +
                USER = "user"
         
     | 
| 
      
 64 
     | 
    
         
            +
                SYSTEM = "system"
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            @dataclass
         
     | 
| 
      
 68 
     | 
    
         
            +
            class AgentModification:
         
     | 
| 
      
 69 
     | 
    
         
            +
                """Agent modification record with comprehensive metadata."""
         
     | 
| 
      
 70 
     | 
    
         
            +
                
         
     | 
| 
      
 71 
     | 
    
         
            +
                modification_id: str
         
     | 
| 
      
 72 
     | 
    
         
            +
                agent_name: str
         
     | 
| 
      
 73 
     | 
    
         
            +
                modification_type: ModificationType
         
     | 
| 
      
 74 
     | 
    
         
            +
                tier: ModificationTier
         
     | 
| 
      
 75 
     | 
    
         
            +
                file_path: str
         
     | 
| 
      
 76 
     | 
    
         
            +
                timestamp: float
         
     | 
| 
      
 77 
     | 
    
         
            +
                user_id: Optional[str] = None
         
     | 
| 
      
 78 
     | 
    
         
            +
                modification_details: Dict[str, Any] = field(default_factory=dict)
         
     | 
| 
      
 79 
     | 
    
         
            +
                file_hash_before: Optional[str] = None
         
     | 
| 
      
 80 
     | 
    
         
            +
                file_hash_after: Optional[str] = None
         
     | 
| 
      
 81 
     | 
    
         
            +
                file_size_before: Optional[int] = None
         
     | 
| 
      
 82 
     | 
    
         
            +
                file_size_after: Optional[int] = None
         
     | 
| 
      
 83 
     | 
    
         
            +
                backup_path: Optional[str] = None
         
     | 
| 
      
 84 
     | 
    
         
            +
                validation_status: str = "pending"
         
     | 
| 
      
 85 
     | 
    
         
            +
                validation_errors: List[str] = field(default_factory=list)
         
     | 
| 
      
 86 
     | 
    
         
            +
                related_modifications: List[str] = field(default_factory=list)
         
     | 
| 
      
 87 
     | 
    
         
            +
                metadata: Dict[str, Any] = field(default_factory=dict)
         
     | 
| 
      
 88 
     | 
    
         
            +
                
         
     | 
| 
      
 89 
     | 
    
         
            +
                @property
         
     | 
| 
      
 90 
     | 
    
         
            +
                def modification_datetime(self) -> datetime:
         
     | 
| 
      
 91 
     | 
    
         
            +
                    """Get modification timestamp as datetime."""
         
     | 
| 
      
 92 
     | 
    
         
            +
                    return datetime.fromtimestamp(self.timestamp)
         
     | 
| 
      
 93 
     | 
    
         
            +
                
         
     | 
| 
      
 94 
     | 
    
         
            +
                @property
         
     | 
| 
      
 95 
     | 
    
         
            +
                def age_seconds(self) -> float:
         
     | 
| 
      
 96 
     | 
    
         
            +
                    """Get age of modification in seconds."""
         
     | 
| 
      
 97 
     | 
    
         
            +
                    return time.time() - self.timestamp
         
     | 
| 
      
 98 
     | 
    
         
            +
                
         
     | 
| 
      
 99 
     | 
    
         
            +
                def to_dict(self) -> Dict[str, Any]:
         
     | 
| 
      
 100 
     | 
    
         
            +
                    """Convert to dictionary for serialization."""
         
     | 
| 
      
 101 
     | 
    
         
            +
                    data = asdict(self)
         
     | 
| 
      
 102 
     | 
    
         
            +
                    data['modification_type'] = self.modification_type.value
         
     | 
| 
      
 103 
     | 
    
         
            +
                    data['tier'] = self.tier.value
         
     | 
| 
      
 104 
     | 
    
         
            +
                    return data
         
     | 
| 
      
 105 
     | 
    
         
            +
                
         
     | 
| 
      
 106 
     | 
    
         
            +
                @classmethod
         
     | 
| 
      
 107 
     | 
    
         
            +
                def from_dict(cls, data: Dict[str, Any]) -> 'AgentModification':
         
     | 
| 
      
 108 
     | 
    
         
            +
                    """Create from dictionary."""
         
     | 
| 
      
 109 
     | 
    
         
            +
                    data['modification_type'] = ModificationType(data['modification_type'])
         
     | 
| 
      
 110 
     | 
    
         
            +
                    data['tier'] = ModificationTier(data['tier'])
         
     | 
| 
      
 111 
     | 
    
         
            +
                    return cls(**data)
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
            @dataclass
         
     | 
| 
      
 115 
     | 
    
         
            +
            class ModificationHistory:
         
     | 
| 
      
 116 
     | 
    
         
            +
                """Complete modification history for an agent."""
         
     | 
| 
      
 117 
     | 
    
         
            +
                
         
     | 
| 
      
 118 
     | 
    
         
            +
                agent_name: str
         
     | 
| 
      
 119 
     | 
    
         
            +
                modifications: List[AgentModification] = field(default_factory=list)
         
     | 
| 
      
 120 
     | 
    
         
            +
                current_version: Optional[str] = None
         
     | 
| 
      
 121 
     | 
    
         
            +
                total_modifications: int = 0
         
     | 
| 
      
 122 
     | 
    
         
            +
                first_seen: Optional[float] = None
         
     | 
| 
      
 123 
     | 
    
         
            +
                last_modified: Optional[float] = None
         
     | 
| 
      
 124 
     | 
    
         
            +
                
         
     | 
| 
      
 125 
     | 
    
         
            +
                def add_modification(self, modification: AgentModification) -> None:
         
     | 
| 
      
 126 
     | 
    
         
            +
                    """Add a modification to history."""
         
     | 
| 
      
 127 
     | 
    
         
            +
                    self.modifications.append(modification)
         
     | 
| 
      
 128 
     | 
    
         
            +
                    self.total_modifications += 1
         
     | 
| 
      
 129 
     | 
    
         
            +
                    self.last_modified = modification.timestamp
         
     | 
| 
      
 130 
     | 
    
         
            +
                    
         
     | 
| 
      
 131 
     | 
    
         
            +
                    if self.first_seen is None:
         
     | 
| 
      
 132 
     | 
    
         
            +
                        self.first_seen = modification.timestamp
         
     | 
| 
      
 133 
     | 
    
         
            +
                
         
     | 
| 
      
 134 
     | 
    
         
            +
                def get_recent_modifications(self, hours: int = 24) -> List[AgentModification]:
         
     | 
| 
      
 135 
     | 
    
         
            +
                    """Get modifications within specified hours."""
         
     | 
| 
      
 136 
     | 
    
         
            +
                    cutoff = time.time() - (hours * 3600)
         
     | 
| 
      
 137 
     | 
    
         
            +
                    return [mod for mod in self.modifications if mod.timestamp >= cutoff]
         
     | 
| 
      
 138 
     | 
    
         
            +
                
         
     | 
| 
      
 139 
     | 
    
         
            +
                def get_modifications_by_type(self, mod_type: ModificationType) -> List[AgentModification]:
         
     | 
| 
      
 140 
     | 
    
         
            +
                    """Get modifications by type."""
         
     | 
| 
      
 141 
     | 
    
         
            +
                    return [mod for mod in self.modifications if mod.modification_type == mod_type]
         
     | 
| 
       61 
142 
     | 
    
         | 
| 
       62 
143 
     | 
    
         | 
| 
       63 
144 
     | 
    
         
             
            # ============================================================================
         
     | 
| 
         @@ -13,22 +13,42 @@ DESIGN DECISION: Creating a minimal stub because: 
     | 
|
| 
       13 
13 
     | 
    
         
             
            - Allows for future extension if needed
         
     | 
| 
       14 
14 
     | 
    
         
             
            """
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
            from  
     | 
| 
      
 16 
     | 
    
         
            +
            from dataclasses import dataclass
         
     | 
| 
      
 17 
     | 
    
         
            +
            from enum import Enum
         
     | 
| 
      
 18 
     | 
    
         
            +
            from typing import Optional, Any, Dict
         
     | 
| 
       17 
19 
     | 
    
         
             
            import time
         
     | 
| 
       18 
20 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
            from claude_mpm.models.persistence import (
         
     | 
| 
       20 
     | 
    
         
            -
                PersistenceStrategy,
         
     | 
| 
       21 
     | 
    
         
            -
                PersistenceOperation,
         
     | 
| 
       22 
     | 
    
         
            -
                PersistenceRecord
         
     | 
| 
       23 
     | 
    
         
            -
            )
         
     | 
| 
       24 
21 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                 
     | 
| 
       28 
     | 
    
         
            -
                 
     | 
| 
       29 
     | 
    
         
            -
                 
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
      
 22 
     | 
    
         
            +
            class PersistenceStrategy(Enum):
         
     | 
| 
      
 23 
     | 
    
         
            +
                """Agent persistence strategies."""
         
     | 
| 
      
 24 
     | 
    
         
            +
                USER_OVERRIDE = "user_override"
         
     | 
| 
      
 25 
     | 
    
         
            +
                PROJECT_SPECIFIC = "project_specific"
         
     | 
| 
      
 26 
     | 
    
         
            +
                SYSTEM_DEFAULT = "system_default"
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            class PersistenceOperation(Enum):
         
     | 
| 
      
 30 
     | 
    
         
            +
                """Persistence operation types."""
         
     | 
| 
      
 31 
     | 
    
         
            +
                CREATE = "create"
         
     | 
| 
      
 32 
     | 
    
         
            +
                UPDATE = "update"
         
     | 
| 
      
 33 
     | 
    
         
            +
                DELETE = "delete"
         
     | 
| 
      
 34 
     | 
    
         
            +
                BACKUP = "backup"
         
     | 
| 
      
 35 
     | 
    
         
            +
                RESTORE = "restore"
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            @dataclass
         
     | 
| 
      
 39 
     | 
    
         
            +
            class PersistenceRecord:
         
     | 
| 
      
 40 
     | 
    
         
            +
                """Record of a persistence operation."""
         
     | 
| 
      
 41 
     | 
    
         
            +
                operation_id: str
         
     | 
| 
      
 42 
     | 
    
         
            +
                operation_type: PersistenceOperation
         
     | 
| 
      
 43 
     | 
    
         
            +
                agent_name: str
         
     | 
| 
      
 44 
     | 
    
         
            +
                source_tier: Any
         
     | 
| 
      
 45 
     | 
    
         
            +
                target_tier: Optional[Any] = None
         
     | 
| 
      
 46 
     | 
    
         
            +
                strategy: Optional[PersistenceStrategy] = None
         
     | 
| 
      
 47 
     | 
    
         
            +
                success: bool = True
         
     | 
| 
      
 48 
     | 
    
         
            +
                timestamp: float = 0.0
         
     | 
| 
      
 49 
     | 
    
         
            +
                file_path: Optional[str] = None
         
     | 
| 
      
 50 
     | 
    
         
            +
                error_message: Optional[str] = None
         
     | 
| 
      
 51 
     | 
    
         
            +
                metadata: Dict[str, Any] = None
         
     | 
| 
       32 
52 
     | 
    
         | 
| 
       33 
53 
     | 
    
         | 
| 
       34 
54 
     | 
    
         
             
            class AgentPersistenceService:
         
     | 
| 
         @@ -25,35 +25,36 @@ import hashlib 
     | 
|
| 
       25 
25 
     | 
    
         
             
            import logging
         
     | 
| 
       26 
26 
     | 
    
         
             
            from pathlib import Path
         
     | 
| 
       27 
27 
     | 
    
         
             
            from typing import Dict, List, Optional, Set, Tuple, Any, Union
         
     | 
| 
       28 
     | 
    
         
            -
            from dataclasses import asdict
         
     | 
| 
      
 28 
     | 
    
         
            +
            from dataclasses import dataclass, field, asdict
         
     | 
| 
       29 
29 
     | 
    
         
             
            from datetime import datetime
         
     | 
| 
       30 
30 
     | 
    
         
             
            from enum import Enum
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
            from claude_mpm.models.registry import AgentTier, AgentRegistryMetadata
         
     | 
| 
       33 
     | 
    
         
            -
            from claude_mpm.models.common import (
         
     | 
| 
       34 
     | 
    
         
            -
                CORE_AGENT_TYPES,
         
     | 
| 
       35 
     | 
    
         
            -
                SPECIALIZED_AGENT_TYPES,
         
     | 
| 
       36 
     | 
    
         
            -
                ALL_AGENT_TYPES,
         
     | 
| 
       37 
     | 
    
         
            -
                AGENT_FILE_EXTENSIONS,
         
     | 
| 
       38 
     | 
    
         
            -
                AGENT_IGNORE_PATTERNS
         
     | 
| 
       39 
     | 
    
         
            -
            )
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
32 
     | 
    
         
             
            logger = logging.getLogger(__name__)
         
     | 
| 
       42 
33 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
            # Backward compatibility exports
         
     | 
| 
       44 
     | 
    
         
            -
            # Export AgentRegistryMetadata as AgentMetadata for existing code
         
     | 
| 
       45 
     | 
    
         
            -
            AgentMetadata = AgentRegistryMetadata
         
     | 
| 
       46 
34 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
                ' 
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
      
 35 
     | 
    
         
            +
            # ============================================================================
         
     | 
| 
      
 36 
     | 
    
         
            +
            # Constants and Types
         
     | 
| 
      
 37 
     | 
    
         
            +
            # ============================================================================
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            CORE_AGENT_TYPES = {
         
     | 
| 
      
 40 
     | 
    
         
            +
                'engineer', 'architect', 'qa', 'security', 'documentation',
         
     | 
| 
      
 41 
     | 
    
         
            +
                'ops', 'data', 'research', 'version_control'
         
     | 
| 
      
 42 
     | 
    
         
            +
            }
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            SPECIALIZED_AGENT_TYPES = {
         
     | 
| 
      
 45 
     | 
    
         
            +
                'pm_orchestrator', 'frontend', 'backend', 'devops', 'ml',
         
     | 
| 
      
 46 
     | 
    
         
            +
                'database', 'api', 'mobile', 'cloud', 'testing'
         
     | 
| 
      
 47 
     | 
    
         
            +
            }
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            ALL_AGENT_TYPES = CORE_AGENT_TYPES | SPECIALIZED_AGENT_TYPES
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            class AgentTier(Enum):
         
     | 
| 
      
 53 
     | 
    
         
            +
                """Agent hierarchy tiers."""
         
     | 
| 
      
 54 
     | 
    
         
            +
                USER = "user"
         
     | 
| 
      
 55 
     | 
    
         
            +
                SYSTEM = "system"
         
     | 
| 
       54 
56 
     | 
    
         | 
| 
       55 
57 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
            # Keep local AgentType enum for internal classification logic
         
     | 
| 
       57 
58 
     | 
    
         
             
            class AgentType(Enum):
         
     | 
| 
       58 
59 
     | 
    
         
             
                """Agent classification types."""
         
     | 
| 
       59 
60 
     | 
    
         
             
                CORE = "core"
         
     | 
| 
         @@ -62,6 +63,44 @@ class AgentType(Enum): 
     | 
|
| 
       62 
63 
     | 
    
         
             
                UNKNOWN = "unknown"
         
     | 
| 
       63 
64 
     | 
    
         | 
| 
       64 
65 
     | 
    
         | 
| 
      
 66 
     | 
    
         
            +
            # ============================================================================
         
     | 
| 
      
 67 
     | 
    
         
            +
            # Data Models
         
     | 
| 
      
 68 
     | 
    
         
            +
            # ============================================================================
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            @dataclass
         
     | 
| 
      
 71 
     | 
    
         
            +
            class AgentMetadata:
         
     | 
| 
      
 72 
     | 
    
         
            +
                """Complete metadata for discovered agent."""
         
     | 
| 
      
 73 
     | 
    
         
            +
                name: str
         
     | 
| 
      
 74 
     | 
    
         
            +
                path: str
         
     | 
| 
      
 75 
     | 
    
         
            +
                tier: AgentTier
         
     | 
| 
      
 76 
     | 
    
         
            +
                agent_type: AgentType
         
     | 
| 
      
 77 
     | 
    
         
            +
                description: str = ""
         
     | 
| 
      
 78 
     | 
    
         
            +
                version: str = "0.0.0"
         
     | 
| 
      
 79 
     | 
    
         
            +
                dependencies: List[str] = field(default_factory=list)
         
     | 
| 
      
 80 
     | 
    
         
            +
                capabilities: List[str] = field(default_factory=list)
         
     | 
| 
      
 81 
     | 
    
         
            +
                created_at: float = field(default_factory=time.time)
         
     | 
| 
      
 82 
     | 
    
         
            +
                last_modified: float = field(default_factory=time.time)
         
     | 
| 
      
 83 
     | 
    
         
            +
                file_size: int = 0
         
     | 
| 
      
 84 
     | 
    
         
            +
                checksum: str = ""
         
     | 
| 
      
 85 
     | 
    
         
            +
                is_valid: bool = True
         
     | 
| 
      
 86 
     | 
    
         
            +
                validation_errors: List[str] = field(default_factory=list)
         
     | 
| 
      
 87 
     | 
    
         
            +
                metadata: Dict[str, Any] = field(default_factory=dict)
         
     | 
| 
      
 88 
     | 
    
         
            +
                
         
     | 
| 
      
 89 
     | 
    
         
            +
                def to_dict(self) -> Dict[str, Any]:
         
     | 
| 
      
 90 
     | 
    
         
            +
                    """Convert to dictionary for serialization."""
         
     | 
| 
      
 91 
     | 
    
         
            +
                    data = asdict(self)
         
     | 
| 
      
 92 
     | 
    
         
            +
                    data['tier'] = self.tier.value
         
     | 
| 
      
 93 
     | 
    
         
            +
                    data['agent_type'] = self.agent_type.value
         
     | 
| 
      
 94 
     | 
    
         
            +
                    return data
         
     | 
| 
      
 95 
     | 
    
         
            +
                
         
     | 
| 
      
 96 
     | 
    
         
            +
                @classmethod
         
     | 
| 
      
 97 
     | 
    
         
            +
                def from_dict(cls, data: Dict[str, Any]) -> 'AgentMetadata':
         
     | 
| 
      
 98 
     | 
    
         
            +
                    """Create from dictionary."""
         
     | 
| 
      
 99 
     | 
    
         
            +
                    data['tier'] = AgentTier(data['tier'])
         
     | 
| 
      
 100 
     | 
    
         
            +
                    data['agent_type'] = AgentType(data['agent_type'])
         
     | 
| 
      
 101 
     | 
    
         
            +
                    return cls(**data)
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
       65 
104 
     | 
    
         
             
            # ============================================================================
         
     | 
| 
       66 
105 
     | 
    
         
             
            # Main Registry Class
         
     | 
| 
       67 
106 
     | 
    
         
             
            # ============================================================================
         
     | 
| 
         @@ -80,7 +119,7 @@ class AgentRegistry: 
     | 
|
| 
       80 
119 
     | 
    
         
             
                    self.model_selector = model_selector
         
     | 
| 
       81 
120 
     | 
    
         | 
| 
       82 
121 
     | 
    
         
             
                    # Registry storage
         
     | 
| 
       83 
     | 
    
         
            -
                    self.registry: Dict[str,  
     | 
| 
      
 122 
     | 
    
         
            +
                    self.registry: Dict[str, AgentMetadata] = {}
         
     | 
| 
       84 
123 
     | 
    
         
             
                    self.discovery_paths: List[Path] = []
         
     | 
| 
       85 
124 
     | 
    
         | 
| 
       86 
125 
     | 
    
         
             
                    # Cache configuration
         
     | 
| 
         @@ -89,8 +128,8 @@ class AgentRegistry: 
     | 
|
| 
       89 
128 
     | 
    
         
             
                    self.cache_prefix = "agent_registry"
         
     | 
| 
       90 
129 
     | 
    
         | 
| 
       91 
130 
     | 
    
         
             
                    # Discovery configuration
         
     | 
| 
       92 
     | 
    
         
            -
                    self.file_extensions =  
     | 
| 
       93 
     | 
    
         
            -
                    self.ignore_patterns =  
     | 
| 
      
 131 
     | 
    
         
            +
                    self.file_extensions = {'.md', '.json', '.yaml', '.yml'}
         
     | 
| 
      
 132 
     | 
    
         
            +
                    self.ignore_patterns = {'__pycache__', '.git', 'node_modules', '.pytest_cache'}
         
     | 
| 
       94 
133 
     | 
    
         | 
| 
       95 
134 
     | 
    
         
             
                    # Statistics
         
     | 
| 
       96 
135 
     | 
    
         
             
                    self.discovery_stats = {
         
     | 
| 
         @@ -130,7 +169,7 @@ class AgentRegistry: 
     | 
|
| 
       130 
169 
     | 
    
         
             
                # Discovery Methods
         
     | 
| 
       131 
170 
     | 
    
         
             
                # ========================================================================
         
     | 
| 
       132 
171 
     | 
    
         | 
| 
       133 
     | 
    
         
            -
                def discover_agents(self, force_refresh: bool = False) -> Dict[str,  
     | 
| 
      
 172 
     | 
    
         
            +
                def discover_agents(self, force_refresh: bool = False) -> Dict[str, AgentMetadata]:
         
     | 
| 
       134 
173 
     | 
    
         
             
                    """
         
     | 
| 
       135 
174 
     | 
    
         
             
                    Discover all available agents across configured paths.
         
     | 
| 
       136 
175 
     | 
    
         | 
| 
         @@ -230,7 +269,7 @@ class AgentRegistry: 
     | 
|
| 
       230 
269 
     | 
    
         | 
| 
       231 
270 
     | 
    
         
             
                    return name
         
     | 
| 
       232 
271 
     | 
    
         | 
| 
       233 
     | 
    
         
            -
                def _create_agent_metadata(self, file_path: Path, agent_name: str, tier: AgentTier) ->  
     | 
| 
      
 272 
     | 
    
         
            +
                def _create_agent_metadata(self, file_path: Path, agent_name: str, tier: AgentTier) -> AgentMetadata:
         
     | 
| 
       234 
273 
     | 
    
         
             
                    """Create agent metadata from file."""
         
     | 
| 
       235 
274 
     | 
    
         
             
                    # Get file stats
         
     | 
| 
       236 
275 
     | 
    
         
             
                    stat = file_path.stat()
         
     | 
| 
         @@ -285,11 +324,11 @@ class AgentRegistry: 
     | 
|
| 
       285 
324 
     | 
    
         
             
                    except Exception as e:
         
     | 
| 
       286 
325 
     | 
    
         
             
                        logger.warning(f"Failed to parse {file_path}: {e}")
         
     | 
| 
       287 
326 
     | 
    
         | 
| 
       288 
     | 
    
         
            -
                    return  
     | 
| 
      
 327 
     | 
    
         
            +
                    return AgentMetadata(
         
     | 
| 
       289 
328 
     | 
    
         
             
                        name=agent_name,
         
     | 
| 
       290 
329 
     | 
    
         
             
                        path=str(file_path),
         
     | 
| 
       291 
330 
     | 
    
         
             
                        tier=tier,
         
     | 
| 
       292 
     | 
    
         
            -
                        agent_type=agent_type 
     | 
| 
      
 331 
     | 
    
         
            +
                        agent_type=agent_type,
         
     | 
| 
       293 
332 
     | 
    
         
             
                        description=description,
         
     | 
| 
       294 
333 
     | 
    
         
             
                        version=version,
         
     | 
| 
       295 
334 
     | 
    
         
             
                        capabilities=capabilities,
         
     | 
| 
         @@ -340,7 +379,7 @@ class AgentRegistry: 
     | 
|
| 
       340 
379 
     | 
    
         
             
                def _apply_tier_precedence(self) -> None:
         
     | 
| 
       341 
380 
     | 
    
         
             
                    """Apply tier precedence rules to discovered agents."""
         
     | 
| 
       342 
381 
     | 
    
         
             
                    # Group agents by name
         
     | 
| 
       343 
     | 
    
         
            -
                    agents_by_name: Dict[str, List[ 
     | 
| 
      
 382 
     | 
    
         
            +
                    agents_by_name: Dict[str, List[AgentMetadata]] = {}
         
     | 
| 
       344 
383 
     | 
    
         | 
| 
       345 
384 
     | 
    
         
             
                    for agent in self.registry.values():
         
     | 
| 
       346 
385 
     | 
    
         
             
                        if agent.name not in agents_by_name:
         
     | 
| 
         @@ -364,7 +403,7 @@ class AgentRegistry: 
     | 
|
| 
       364 
403 
     | 
    
         
             
                # Validation Methods
         
     | 
| 
       365 
404 
     | 
    
         
             
                # ========================================================================
         
     | 
| 
       366 
405 
     | 
    
         | 
| 
       367 
     | 
    
         
            -
                def _validate_agent(self, metadata:  
     | 
| 
      
 406 
     | 
    
         
            +
                def _validate_agent(self, metadata: AgentMetadata) -> bool:
         
     | 
| 
       368 
407 
     | 
    
         
             
                    """Validate agent metadata and file."""
         
     | 
| 
       369 
408 
     | 
    
         
             
                    errors = []
         
     | 
| 
       370 
409 
     | 
    
         | 
| 
         @@ -398,7 +437,7 @@ class AgentRegistry: 
     | 
|
| 
       398 
437 
     | 
    
         
             
                # Cache Methods
         
     | 
| 
       399 
438 
     | 
    
         
             
                # ========================================================================
         
     | 
| 
       400 
439 
     | 
    
         | 
| 
       401 
     | 
    
         
            -
                def _get_cached_registry(self) -> Optional[Dict[str,  
     | 
| 
      
 440 
     | 
    
         
            +
                def _get_cached_registry(self) -> Optional[Dict[str, AgentMetadata]]:
         
     | 
| 
       402 
441 
     | 
    
         
             
                    """Get registry from cache if available."""
         
     | 
| 
       403 
442 
     | 
    
         
             
                    if not self.cache_service:
         
     | 
| 
       404 
443 
     | 
    
         
             
                        return None
         
     | 
| 
         @@ -411,7 +450,7 @@ class AgentRegistry: 
     | 
|
| 
       411 
450 
     | 
    
         
             
                            # Deserialize metadata
         
     | 
| 
       412 
451 
     | 
    
         
             
                            registry = {}
         
     | 
| 
       413 
452 
     | 
    
         
             
                            for name, data in cached_data.items():
         
     | 
| 
       414 
     | 
    
         
            -
                                registry[name] =  
     | 
| 
      
 453 
     | 
    
         
            +
                                registry[name] = AgentMetadata.from_dict(data)
         
     | 
| 
       415 
454 
     | 
    
         
             
                            return registry
         
     | 
| 
       416 
455 
     | 
    
         | 
| 
       417 
456 
     | 
    
         
             
                    except Exception as e:
         
     | 
| 
         @@ -452,7 +491,7 @@ class AgentRegistry: 
     | 
|
| 
       452 
491 
     | 
    
         
             
                # Query Methods
         
     | 
| 
       453 
492 
     | 
    
         
             
                # ========================================================================
         
     | 
| 
       454 
493 
     | 
    
         | 
| 
       455 
     | 
    
         
            -
                def get_agent(self, name: str) -> Optional[ 
     | 
| 
      
 494 
     | 
    
         
            +
                def get_agent(self, name: str) -> Optional[AgentMetadata]:
         
     | 
| 
       456 
495 
     | 
    
         
             
                    """Get metadata for a specific agent."""
         
     | 
| 
       457 
496 
     | 
    
         
             
                    # Ensure registry is populated
         
     | 
| 
       458 
497 
     | 
    
         
             
                    if not self.registry:
         
     | 
| 
         @@ -461,7 +500,7 @@ class AgentRegistry: 
     | 
|
| 
       461 
500 
     | 
    
         
             
                    return self.registry.get(name)
         
     | 
| 
       462 
501 
     | 
    
         | 
| 
       463 
502 
     | 
    
         
             
                def list_agents(self, tier: Optional[AgentTier] = None, 
         
     | 
| 
       464 
     | 
    
         
            -
                               agent_type: Optional[ 
     | 
| 
      
 503 
     | 
    
         
            +
                               agent_type: Optional[AgentType] = None) -> List[AgentMetadata]:
         
     | 
| 
       465 
504 
     | 
    
         
             
                    """List agents with optional filtering."""
         
     | 
| 
       466 
505 
     | 
    
         
             
                    # Ensure registry is populated
         
     | 
| 
       467 
506 
     | 
    
         
             
                    if not self.registry:
         
     | 
| 
         @@ -485,19 +524,19 @@ class AgentRegistry: 
     | 
|
| 
       485 
524 
     | 
    
         | 
| 
       486 
525 
     | 
    
         
             
                    return sorted(self.registry.keys())
         
     | 
| 
       487 
526 
     | 
    
         | 
| 
       488 
     | 
    
         
            -
                def get_core_agents(self) -> List[ 
     | 
| 
      
 527 
     | 
    
         
            +
                def get_core_agents(self) -> List[AgentMetadata]:
         
     | 
| 
       489 
528 
     | 
    
         
             
                    """Get all core framework agents."""
         
     | 
| 
       490 
     | 
    
         
            -
                    return self.list_agents(agent_type=AgentType.CORE 
     | 
| 
      
 529 
     | 
    
         
            +
                    return self.list_agents(agent_type=AgentType.CORE)
         
     | 
| 
       491 
530 
     | 
    
         | 
| 
       492 
     | 
    
         
            -
                def get_specialized_agents(self) -> List[ 
     | 
| 
      
 531 
     | 
    
         
            +
                def get_specialized_agents(self) -> List[AgentMetadata]:
         
     | 
| 
       493 
532 
     | 
    
         
             
                    """Get all specialized agents."""
         
     | 
| 
       494 
     | 
    
         
            -
                    return self.list_agents(agent_type=AgentType.SPECIALIZED 
     | 
| 
      
 533 
     | 
    
         
            +
                    return self.list_agents(agent_type=AgentType.SPECIALIZED)
         
     | 
| 
       495 
534 
     | 
    
         | 
| 
       496 
     | 
    
         
            -
                def get_custom_agents(self) -> List[ 
     | 
| 
      
 535 
     | 
    
         
            +
                def get_custom_agents(self) -> List[AgentMetadata]:
         
     | 
| 
       497 
536 
     | 
    
         
             
                    """Get all custom user-defined agents."""
         
     | 
| 
       498 
     | 
    
         
            -
                    return self.list_agents(agent_type=AgentType.CUSTOM 
     | 
| 
      
 537 
     | 
    
         
            +
                    return self.list_agents(agent_type=AgentType.CUSTOM)
         
     | 
| 
       499 
538 
     | 
    
         | 
| 
       500 
     | 
    
         
            -
                def search_agents(self, query: str) -> List[ 
     | 
| 
      
 539 
     | 
    
         
            +
                def search_agents(self, query: str) -> List[AgentMetadata]:
         
     | 
| 
       501 
540 
     | 
    
         
             
                    """Search agents by name or description."""
         
     | 
| 
       502 
541 
     | 
    
         
             
                    if not self.registry:
         
     | 
| 
       503 
542 
     | 
    
         
             
                        self.discover_agents()
         
     | 
| 
         @@ -540,7 +579,7 @@ class AgentRegistry: 
     | 
|
| 
       540 
579 
     | 
    
         | 
| 
       541 
580 
     | 
    
         
             
                    # Count by type
         
     | 
| 
       542 
581 
     | 
    
         
             
                    for agent in self.registry.values():
         
     | 
| 
       543 
     | 
    
         
            -
                        agent_type = agent.agent_type 
     | 
| 
      
 582 
     | 
    
         
            +
                        agent_type = agent.agent_type.value
         
     | 
| 
       544 
583 
     | 
    
         
             
                        stats['agents_by_type'][agent_type] = stats['agents_by_type'].get(agent_type, 0) + 1
         
     | 
| 
       545 
584 
     | 
    
         | 
| 
       546 
585 
     | 
    
         
             
                    # Validation stats
         
     | 
| 
         @@ -628,7 +667,7 @@ class AgentRegistry: 
     | 
|
| 
       628 
667 
     | 
    
         | 
| 
       629 
668 
     | 
    
         
             
                    # Import agents
         
     | 
| 
       630 
669 
     | 
    
         
             
                    for name, agent_data in data.get('agents', {}).items():
         
     | 
| 
       631 
     | 
    
         
            -
                        self.registry[name] =  
     | 
| 
      
 670 
     | 
    
         
            +
                        self.registry[name] = AgentMetadata.from_dict(agent_data)
         
     | 
| 
       632 
671 
     | 
    
         | 
| 
       633 
672 
     | 
    
         
             
                    # Cache imported registry
         
     | 
| 
       634 
673 
     | 
    
         
             
                    if self.cache_enabled:
         
     |