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,477 @@ | |
| 1 | 
            +
            """Type definitions and utilities for Claude MPM.
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            This module provides common type aliases, protocols, and TypedDict definitions
         | 
| 4 | 
            +
            used throughout the codebase to ensure consistent type safety.
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            WHY: Centralizing type definitions reduces duplication, improves IDE support,
         | 
| 7 | 
            +
            and makes the codebase more maintainable by providing a single source of truth
         | 
| 8 | 
            +
            for complex type definitions.
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            DESIGN DECISION: Uses protocols and TypedDict to provide structural typing
         | 
| 11 | 
            +
            that allows for more flexible and maintainable type checking while maintaining
         | 
| 12 | 
            +
            strict type safety.
         | 
| 13 | 
            +
            """
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            from typing import (
         | 
| 16 | 
            +
                Any, Callable, Dict, List, Optional, Union, TypeVar, Protocol,
         | 
| 17 | 
            +
                TYPE_CHECKING, Literal, Tuple, Set, Awaitable, Iterator, AsyncIterator
         | 
| 18 | 
            +
            )
         | 
| 19 | 
            +
            from typing_extensions import TypedDict, NotRequired, TypeAlias
         | 
| 20 | 
            +
            from pathlib import Path
         | 
| 21 | 
            +
            from datetime import datetime
         | 
| 22 | 
            +
            from enum import Enum
         | 
| 23 | 
            +
            import logging
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            if TYPE_CHECKING:
         | 
| 26 | 
            +
                from claude_mpm.core.claude_runner import ClaudeRunner
         | 
| 27 | 
            +
                from claude_mpm.services.socketio_server import SocketIOClientProxy
         | 
| 28 | 
            +
             | 
| 29 | 
            +
             | 
| 30 | 
            +
            # Generic type variables
         | 
| 31 | 
            +
            T = TypeVar('T')
         | 
| 32 | 
            +
            TSession = TypeVar('TSession')  # Generic session type
         | 
| 33 | 
            +
            TAgent = TypeVar('TAgent')  # Generic agent type
         | 
| 34 | 
            +
            TService = TypeVar('TService')  # Generic service type
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            # Basic type aliases
         | 
| 37 | 
            +
            PathLike: TypeAlias = Union[str, Path]
         | 
| 38 | 
            +
            JSONValue: TypeAlias = Union[str, int, float, bool, None, Dict[str, Any], List[Any]]
         | 
| 39 | 
            +
            JSONDict: TypeAlias = Dict[str, JSONValue]
         | 
| 40 | 
            +
            Headers: TypeAlias = Dict[str, str]
         | 
| 41 | 
            +
            ErrorCode: TypeAlias = Union[int, str]
         | 
| 42 | 
            +
            LogLevel: TypeAlias = Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            # Session types
         | 
| 45 | 
            +
            SessionId: TypeAlias = str
         | 
| 46 | 
            +
            SessionStatus: TypeAlias = Literal["initializing", "running", "stopped", "error", "completed"]
         | 
| 47 | 
            +
            LaunchMethod: TypeAlias = Literal["exec", "subprocess", "oneshot"]
         | 
| 48 | 
            +
             | 
| 49 | 
            +
             | 
| 50 | 
            +
            class SessionConfig(TypedDict):
         | 
| 51 | 
            +
                """Configuration for a Claude session."""
         | 
| 52 | 
            +
                session_id: SessionId
         | 
| 53 | 
            +
                launch_method: LaunchMethod
         | 
| 54 | 
            +
                working_dir: str
         | 
| 55 | 
            +
                enable_websocket: NotRequired[bool]
         | 
| 56 | 
            +
                websocket_port: NotRequired[int]
         | 
| 57 | 
            +
                enable_tickets: NotRequired[bool]
         | 
| 58 | 
            +
                claude_args: NotRequired[List[str]]
         | 
| 59 | 
            +
                context: NotRequired[str]
         | 
| 60 | 
            +
                system_prompt: NotRequired[str]
         | 
| 61 | 
            +
             | 
| 62 | 
            +
             | 
| 63 | 
            +
            class SessionResult(TypedDict):
         | 
| 64 | 
            +
                """Result from a session execution."""
         | 
| 65 | 
            +
                success: bool
         | 
| 66 | 
            +
                session_id: SessionId
         | 
| 67 | 
            +
                response: NotRequired[str]
         | 
| 68 | 
            +
                error: NotRequired[str]
         | 
| 69 | 
            +
                execution_time: NotRequired[float]
         | 
| 70 | 
            +
                exit_code: NotRequired[int]
         | 
| 71 | 
            +
                metadata: NotRequired[Dict[str, Any]]
         | 
| 72 | 
            +
             | 
| 73 | 
            +
             | 
| 74 | 
            +
            class SessionEvent(TypedDict):
         | 
| 75 | 
            +
                """Event logged during session execution."""
         | 
| 76 | 
            +
                event: str
         | 
| 77 | 
            +
                timestamp: datetime
         | 
| 78 | 
            +
                session_id: NotRequired[SessionId]
         | 
| 79 | 
            +
                success: NotRequired[bool]
         | 
| 80 | 
            +
                error: NotRequired[str]
         | 
| 81 | 
            +
                exception_type: NotRequired[str]
         | 
| 82 | 
            +
                metadata: NotRequired[Dict[str, Any]]
         | 
| 83 | 
            +
             | 
| 84 | 
            +
             | 
| 85 | 
            +
            # Agent types
         | 
| 86 | 
            +
            AgentId: TypeAlias = str
         | 
| 87 | 
            +
            AgentVersion: TypeAlias = str
         | 
| 88 | 
            +
            AgentTier: TypeAlias = Literal["SYSTEM", "USER", "PROJECT"]
         | 
| 89 | 
            +
            ModelName: TypeAlias = str
         | 
| 90 | 
            +
            ResourceTier: TypeAlias = Literal["standard", "premium", "enterprise"]
         | 
| 91 | 
            +
             | 
| 92 | 
            +
             | 
| 93 | 
            +
            class AgentCapabilities(TypedDict):
         | 
| 94 | 
            +
                """Capabilities of an agent."""
         | 
| 95 | 
            +
                model: ModelName
         | 
| 96 | 
            +
                tools: NotRequired[List[str]]
         | 
| 97 | 
            +
                resource_tier: NotRequired[ResourceTier]
         | 
| 98 | 
            +
                max_tokens: NotRequired[int]
         | 
| 99 | 
            +
                temperature: NotRequired[float]
         | 
| 100 | 
            +
                system_prompt: NotRequired[str]
         | 
| 101 | 
            +
             | 
| 102 | 
            +
             | 
| 103 | 
            +
            class AgentMetadata(TypedDict):
         | 
| 104 | 
            +
                """Metadata for an agent."""
         | 
| 105 | 
            +
                name: str
         | 
| 106 | 
            +
                description: str
         | 
| 107 | 
            +
                tags: NotRequired[List[str]]
         | 
| 108 | 
            +
                author: NotRequired[str]
         | 
| 109 | 
            +
                created_at: NotRequired[str]
         | 
| 110 | 
            +
                updated_at: NotRequired[str]
         | 
| 111 | 
            +
             | 
| 112 | 
            +
             | 
| 113 | 
            +
            class AgentDefinition(TypedDict):
         | 
| 114 | 
            +
                """Complete agent definition."""
         | 
| 115 | 
            +
                agent_id: AgentId
         | 
| 116 | 
            +
                version: AgentVersion
         | 
| 117 | 
            +
                metadata: AgentMetadata
         | 
| 118 | 
            +
                capabilities: AgentCapabilities
         | 
| 119 | 
            +
                instructions: str
         | 
| 120 | 
            +
                tier: NotRequired[AgentTier]
         | 
| 121 | 
            +
                file_path: NotRequired[PathLike]
         | 
| 122 | 
            +
             | 
| 123 | 
            +
             | 
| 124 | 
            +
            # WebSocket/SocketIO types
         | 
| 125 | 
            +
            EventName: TypeAlias = str
         | 
| 126 | 
            +
            EventData: TypeAlias = Dict[str, Any]
         | 
| 127 | 
            +
            SocketId: TypeAlias = str
         | 
| 128 | 
            +
             | 
| 129 | 
            +
             | 
| 130 | 
            +
            class WebSocketMessage(TypedDict):
         | 
| 131 | 
            +
                """WebSocket message structure."""
         | 
| 132 | 
            +
                event: EventName
         | 
| 133 | 
            +
                data: EventData
         | 
| 134 | 
            +
                timestamp: NotRequired[datetime]
         | 
| 135 | 
            +
                session_id: NotRequired[SessionId]
         | 
| 136 | 
            +
             | 
| 137 | 
            +
             | 
| 138 | 
            +
            class ClaudeStatus(TypedDict):
         | 
| 139 | 
            +
                """Claude process status."""
         | 
| 140 | 
            +
                status: Literal["starting", "running", "stopped", "error"]
         | 
| 141 | 
            +
                message: str
         | 
| 142 | 
            +
                timestamp: NotRequired[datetime]
         | 
| 143 | 
            +
                pid: NotRequired[int]
         | 
| 144 | 
            +
             | 
| 145 | 
            +
             | 
| 146 | 
            +
            class DelegationInfo(TypedDict):
         | 
| 147 | 
            +
                """Agent delegation information."""
         | 
| 148 | 
            +
                agent: AgentId
         | 
| 149 | 
            +
                task: str
         | 
| 150 | 
            +
                status: Literal["detected", "started", "completed", "failed"]
         | 
| 151 | 
            +
                timestamp: NotRequired[datetime]
         | 
| 152 | 
            +
                result: NotRequired[str]
         | 
| 153 | 
            +
             | 
| 154 | 
            +
             | 
| 155 | 
            +
            # Hook types
         | 
| 156 | 
            +
            HookName: TypeAlias = str
         | 
| 157 | 
            +
            HookPriority: TypeAlias = int
         | 
| 158 | 
            +
            HookResult: TypeAlias = Any
         | 
| 159 | 
            +
             | 
| 160 | 
            +
             | 
| 161 | 
            +
            class HookConfig(TypedDict):
         | 
| 162 | 
            +
                """Hook configuration."""
         | 
| 163 | 
            +
                name: HookName
         | 
| 164 | 
            +
                enabled: NotRequired[bool]
         | 
| 165 | 
            +
                priority: NotRequired[HookPriority]
         | 
| 166 | 
            +
                config: NotRequired[Dict[str, Any]]
         | 
| 167 | 
            +
             | 
| 168 | 
            +
             | 
| 169 | 
            +
            class HookContext(TypedDict):
         | 
| 170 | 
            +
                """Context passed to hook handlers."""
         | 
| 171 | 
            +
                hook_name: HookName
         | 
| 172 | 
            +
                session_id: NotRequired[SessionId]
         | 
| 173 | 
            +
                agent_id: NotRequired[AgentId]
         | 
| 174 | 
            +
                data: NotRequired[Dict[str, Any]]
         | 
| 175 | 
            +
             | 
| 176 | 
            +
             | 
| 177 | 
            +
            # Service types
         | 
| 178 | 
            +
            ServiceName: TypeAlias = str
         | 
| 179 | 
            +
            ServiceStatus: TypeAlias = Literal["idle", "running", "stopped", "error"]
         | 
| 180 | 
            +
             | 
| 181 | 
            +
             | 
| 182 | 
            +
            class ServiceConfig(TypedDict):
         | 
| 183 | 
            +
                """Service configuration."""
         | 
| 184 | 
            +
                name: ServiceName
         | 
| 185 | 
            +
                enabled: NotRequired[bool]
         | 
| 186 | 
            +
                port: NotRequired[int]
         | 
| 187 | 
            +
                host: NotRequired[str]
         | 
| 188 | 
            +
                config: NotRequired[Dict[str, Any]]
         | 
| 189 | 
            +
             | 
| 190 | 
            +
             | 
| 191 | 
            +
            class ServiceInfo(TypedDict):
         | 
| 192 | 
            +
                """Service information."""
         | 
| 193 | 
            +
                name: ServiceName
         | 
| 194 | 
            +
                status: ServiceStatus
         | 
| 195 | 
            +
                uptime: NotRequired[float]
         | 
| 196 | 
            +
                requests_handled: NotRequired[int]
         | 
| 197 | 
            +
                errors: NotRequired[int]
         | 
| 198 | 
            +
                last_error: NotRequired[str]
         | 
| 199 | 
            +
             | 
| 200 | 
            +
             | 
| 201 | 
            +
            # Memory types
         | 
| 202 | 
            +
            MemoryType: TypeAlias = Literal[
         | 
| 203 | 
            +
                "pattern", "architecture", "guideline", "mistake", 
         | 
| 204 | 
            +
                "strategy", "integration", "performance", "context"
         | 
| 205 | 
            +
            ]
         | 
| 206 | 
            +
            MemoryId: TypeAlias = str
         | 
| 207 | 
            +
             | 
| 208 | 
            +
             | 
| 209 | 
            +
            class Memory(TypedDict):
         | 
| 210 | 
            +
                """Agent memory entry."""
         | 
| 211 | 
            +
                id: MemoryId
         | 
| 212 | 
            +
                type: MemoryType
         | 
| 213 | 
            +
                content: str
         | 
| 214 | 
            +
                agent_id: AgentId
         | 
| 215 | 
            +
                timestamp: datetime
         | 
| 216 | 
            +
                relevance_score: NotRequired[float]
         | 
| 217 | 
            +
                usage_count: NotRequired[int]
         | 
| 218 | 
            +
                tags: NotRequired[List[str]]
         | 
| 219 | 
            +
             | 
| 220 | 
            +
             | 
| 221 | 
            +
            class MemorySearchResult(TypedDict):
         | 
| 222 | 
            +
                """Result from memory search."""
         | 
| 223 | 
            +
                memory: Memory
         | 
| 224 | 
            +
                score: float
         | 
| 225 | 
            +
                matches: NotRequired[List[str]]
         | 
| 226 | 
            +
             | 
| 227 | 
            +
             | 
| 228 | 
            +
            # Project and deployment types
         | 
| 229 | 
            +
            class ProjectConfig(TypedDict):
         | 
| 230 | 
            +
                """Project-specific configuration."""
         | 
| 231 | 
            +
                project_name: NotRequired[str]
         | 
| 232 | 
            +
                agent_deployment: NotRequired[Dict[str, Any]]
         | 
| 233 | 
            +
                excluded_agents: NotRequired[List[AgentId]]
         | 
| 234 | 
            +
                included_agents: NotRequired[List[AgentId]]
         | 
| 235 | 
            +
                custom_agents_path: NotRequired[PathLike]
         | 
| 236 | 
            +
                memory_enabled: NotRequired[bool]
         | 
| 237 | 
            +
                websocket_enabled: NotRequired[bool]
         | 
| 238 | 
            +
             | 
| 239 | 
            +
             | 
| 240 | 
            +
            class DeploymentResult(TypedDict):
         | 
| 241 | 
            +
                """Result from agent deployment."""
         | 
| 242 | 
            +
                deployed: List[AgentId]
         | 
| 243 | 
            +
                failed: List[Tuple[AgentId, str]]
         | 
| 244 | 
            +
                skipped: List[AgentId]
         | 
| 245 | 
            +
                total_time: float
         | 
| 246 | 
            +
             | 
| 247 | 
            +
             | 
| 248 | 
            +
            # Response logging types
         | 
| 249 | 
            +
            class ResponseLogEntry(TypedDict):
         | 
| 250 | 
            +
                """Entry in response log."""
         | 
| 251 | 
            +
                timestamp: datetime
         | 
| 252 | 
            +
                request_summary: str
         | 
| 253 | 
            +
                response_content: str
         | 
| 254 | 
            +
                metadata: Dict[str, Any]
         | 
| 255 | 
            +
                agent: AgentId
         | 
| 256 | 
            +
                session_id: NotRequired[SessionId]
         | 
| 257 | 
            +
                execution_time: NotRequired[float]
         | 
| 258 | 
            +
             | 
| 259 | 
            +
             | 
| 260 | 
            +
            # Command/CLI types
         | 
| 261 | 
            +
            CommandName: TypeAlias = str
         | 
| 262 | 
            +
            CommandArgs: TypeAlias = List[str]
         | 
| 263 | 
            +
             | 
| 264 | 
            +
             | 
| 265 | 
            +
            class CommandResult(TypedDict):
         | 
| 266 | 
            +
                """Result from command execution."""
         | 
| 267 | 
            +
                success: bool
         | 
| 268 | 
            +
                output: NotRequired[str]
         | 
| 269 | 
            +
                error: NotRequired[str]
         | 
| 270 | 
            +
                exit_code: int
         | 
| 271 | 
            +
             | 
| 272 | 
            +
             | 
| 273 | 
            +
            # Protocols for structural typing
         | 
| 274 | 
            +
             | 
| 275 | 
            +
            class SessionProtocol(Protocol):
         | 
| 276 | 
            +
                """Protocol for session handlers."""
         | 
| 277 | 
            +
                
         | 
| 278 | 
            +
                def initialize_session(self, prompt: str) -> Tuple[bool, Optional[str]]:
         | 
| 279 | 
            +
                    """Initialize the session."""
         | 
| 280 | 
            +
                    ...
         | 
| 281 | 
            +
                
         | 
| 282 | 
            +
                def execute_command(self, prompt: str, context: Optional[str], 
         | 
| 283 | 
            +
                                    infrastructure: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
         | 
| 284 | 
            +
                    """Execute a command."""
         | 
| 285 | 
            +
                    ...
         | 
| 286 | 
            +
                
         | 
| 287 | 
            +
                def cleanup_session(self) -> None:
         | 
| 288 | 
            +
                    """Clean up the session."""
         | 
| 289 | 
            +
                    ...
         | 
| 290 | 
            +
             | 
| 291 | 
            +
             | 
| 292 | 
            +
            class LoggerProtocol(Protocol):
         | 
| 293 | 
            +
                """Protocol for loggers."""
         | 
| 294 | 
            +
                
         | 
| 295 | 
            +
                def log_system(self, message: str, level: LogLevel = "INFO", 
         | 
| 296 | 
            +
                               component: Optional[str] = None) -> None:
         | 
| 297 | 
            +
                    """Log a system message."""
         | 
| 298 | 
            +
                    ...
         | 
| 299 | 
            +
                
         | 
| 300 | 
            +
                def log_agent(self, agent: AgentId, message: str, 
         | 
| 301 | 
            +
                              level: LogLevel = "INFO") -> None:
         | 
| 302 | 
            +
                    """Log an agent message."""
         | 
| 303 | 
            +
                    ...
         | 
| 304 | 
            +
                
         | 
| 305 | 
            +
                def get_session_summary(self) -> Dict[str, Any]:
         | 
| 306 | 
            +
                    """Get session summary."""
         | 
| 307 | 
            +
                    ...
         | 
| 308 | 
            +
             | 
| 309 | 
            +
             | 
| 310 | 
            +
            class WebSocketServerProtocol(Protocol):
         | 
| 311 | 
            +
                """Protocol for WebSocket server."""
         | 
| 312 | 
            +
                
         | 
| 313 | 
            +
                def start(self) -> None:
         | 
| 314 | 
            +
                    """Start the server."""
         | 
| 315 | 
            +
                    ...
         | 
| 316 | 
            +
                
         | 
| 317 | 
            +
                def session_started(self, session_id: SessionId, launch_method: LaunchMethod,
         | 
| 318 | 
            +
                                   working_dir: str) -> None:
         | 
| 319 | 
            +
                    """Notify session start."""
         | 
| 320 | 
            +
                    ...
         | 
| 321 | 
            +
                
         | 
| 322 | 
            +
                def session_ended(self) -> None:
         | 
| 323 | 
            +
                    """Notify session end."""
         | 
| 324 | 
            +
                    ...
         | 
| 325 | 
            +
                
         | 
| 326 | 
            +
                def claude_status_changed(self, status: str, message: str) -> None:
         | 
| 327 | 
            +
                    """Update Claude status."""
         | 
| 328 | 
            +
                    ...
         | 
| 329 | 
            +
                
         | 
| 330 | 
            +
                def claude_output(self, output: str, stream: Literal["stdout", "stderr"]) -> None:
         | 
| 331 | 
            +
                    """Send Claude output."""
         | 
| 332 | 
            +
                    ...
         | 
| 333 | 
            +
                
         | 
| 334 | 
            +
                def agent_delegated(self, agent: AgentId, task: str, status: str) -> None:
         | 
| 335 | 
            +
                    """Notify agent delegation."""
         | 
| 336 | 
            +
                    ...
         | 
| 337 | 
            +
             | 
| 338 | 
            +
             | 
| 339 | 
            +
            class AgentServiceProtocol(Protocol):
         | 
| 340 | 
            +
                """Protocol for agent service."""
         | 
| 341 | 
            +
                
         | 
| 342 | 
            +
                def deploy_agents(self, agents: List[AgentDefinition], 
         | 
| 343 | 
            +
                                 target_dir: PathLike) -> DeploymentResult:
         | 
| 344 | 
            +
                    """Deploy agents to target directory."""
         | 
| 345 | 
            +
                    ...
         | 
| 346 | 
            +
                
         | 
| 347 | 
            +
                def discover_agents(self, tier: AgentTier) -> List[AgentDefinition]:
         | 
| 348 | 
            +
                    """Discover agents at specified tier."""
         | 
| 349 | 
            +
                    ...
         | 
| 350 | 
            +
                
         | 
| 351 | 
            +
                def get_agent(self, agent_id: AgentId, tier: Optional[AgentTier] = None) -> Optional[AgentDefinition]:
         | 
| 352 | 
            +
                    """Get specific agent."""
         | 
| 353 | 
            +
                    ...
         | 
| 354 | 
            +
             | 
| 355 | 
            +
             | 
| 356 | 
            +
            class MemoryServiceProtocol(Protocol):
         | 
| 357 | 
            +
                """Protocol for memory service."""
         | 
| 358 | 
            +
                
         | 
| 359 | 
            +
                def add_memory(self, memory: Memory) -> bool:
         | 
| 360 | 
            +
                    """Add a memory entry."""
         | 
| 361 | 
            +
                    ...
         | 
| 362 | 
            +
                
         | 
| 363 | 
            +
                def search_memories(self, query: str, agent_id: Optional[AgentId] = None,
         | 
| 364 | 
            +
                                    memory_type: Optional[MemoryType] = None,
         | 
| 365 | 
            +
                                    limit: int = 10) -> List[MemorySearchResult]:
         | 
| 366 | 
            +
                    """Search memories."""
         | 
| 367 | 
            +
                    ...
         | 
| 368 | 
            +
                
         | 
| 369 | 
            +
                def get_relevant_memories(self, context: str, agent_id: AgentId,
         | 
| 370 | 
            +
                                         limit: int = 5) -> List[Memory]:
         | 
| 371 | 
            +
                    """Get relevant memories for context."""
         | 
| 372 | 
            +
                    ...
         | 
| 373 | 
            +
             | 
| 374 | 
            +
             | 
| 375 | 
            +
            # Factory function types
         | 
| 376 | 
            +
            SessionFactory = Callable[[Any], SessionProtocol]
         | 
| 377 | 
            +
            ServiceFactory = Callable[[ServiceConfig], Any]
         | 
| 378 | 
            +
            LoggerFactory = Callable[[str], logging.Logger]
         | 
| 379 | 
            +
             | 
| 380 | 
            +
             | 
| 381 | 
            +
            # Validation function types
         | 
| 382 | 
            +
            Validator = Callable[[Any], bool]
         | 
| 383 | 
            +
            Transformer = Callable[[T], T]
         | 
| 384 | 
            +
            ErrorHandler = Callable[[Exception], None]
         | 
| 385 | 
            +
             | 
| 386 | 
            +
             | 
| 387 | 
            +
            # Async types for future use
         | 
| 388 | 
            +
            AsyncSessionResult = Awaitable[SessionResult]
         | 
| 389 | 
            +
            AsyncCommandResult = Awaitable[CommandResult]
         | 
| 390 | 
            +
            AsyncDeploymentResult = Awaitable[DeploymentResult]
         | 
| 391 | 
            +
             | 
| 392 | 
            +
             | 
| 393 | 
            +
            # Container/Dependency injection types
         | 
| 394 | 
            +
            class ServiceContainer(Protocol):
         | 
| 395 | 
            +
                """Protocol for service container."""
         | 
| 396 | 
            +
                
         | 
| 397 | 
            +
                def register(self, name: str, factory: ServiceFactory) -> None:
         | 
| 398 | 
            +
                    """Register a service."""
         | 
| 399 | 
            +
                    ...
         | 
| 400 | 
            +
                
         | 
| 401 | 
            +
                def get(self, name: str) -> Any:
         | 
| 402 | 
            +
                    """Get a service instance."""
         | 
| 403 | 
            +
                    ...
         | 
| 404 | 
            +
                
         | 
| 405 | 
            +
                def has(self, name: str) -> bool:
         | 
| 406 | 
            +
                    """Check if service is registered."""
         | 
| 407 | 
            +
                    ...
         | 
| 408 | 
            +
             | 
| 409 | 
            +
             | 
| 410 | 
            +
            # Event system types
         | 
| 411 | 
            +
            EventHandler = Callable[[EventData], None]
         | 
| 412 | 
            +
            EventFilter = Callable[[EventData], bool]
         | 
| 413 | 
            +
             | 
| 414 | 
            +
             | 
| 415 | 
            +
            class EventSubscription(TypedDict):
         | 
| 416 | 
            +
                """Event subscription details."""
         | 
| 417 | 
            +
                event: EventName
         | 
| 418 | 
            +
                handler: EventHandler
         | 
| 419 | 
            +
                filter: NotRequired[EventFilter]
         | 
| 420 | 
            +
                priority: NotRequired[int]
         | 
| 421 | 
            +
             | 
| 422 | 
            +
             | 
| 423 | 
            +
            # Testing types (for test files)
         | 
| 424 | 
            +
            class TestFixture(TypedDict):
         | 
| 425 | 
            +
                """Test fixture data."""
         | 
| 426 | 
            +
                name: str
         | 
| 427 | 
            +
                data: Any
         | 
| 428 | 
            +
                setup: NotRequired[Callable[[], None]]
         | 
| 429 | 
            +
                teardown: NotRequired[Callable[[], None]]
         | 
| 430 | 
            +
             | 
| 431 | 
            +
             | 
| 432 | 
            +
            # Export commonly used type combinations
         | 
| 433 | 
            +
            CommonTypes = Union[str, int, float, bool, None, List[Any], Dict[str, Any]]
         | 
| 434 | 
            +
            ConfigDict = Dict[str, CommonTypes]
         | 
| 435 | 
            +
            ErrorResult = Tuple[bool, Optional[str]]
         | 
| 436 | 
            +
            SuccessResult = Tuple[bool, Any]
         | 
| 437 | 
            +
             | 
| 438 | 
            +
             | 
| 439 | 
            +
            __all__ = [
         | 
| 440 | 
            +
                # Basic type aliases
         | 
| 441 | 
            +
                'PathLike', 'JSONValue', 'JSONDict', 'Headers', 'ErrorCode', 'LogLevel',
         | 
| 442 | 
            +
                
         | 
| 443 | 
            +
                # Session types
         | 
| 444 | 
            +
                'SessionId', 'SessionStatus', 'LaunchMethod', 'SessionConfig', 
         | 
| 445 | 
            +
                'SessionResult', 'SessionEvent',
         | 
| 446 | 
            +
                
         | 
| 447 | 
            +
                # Agent types
         | 
| 448 | 
            +
                'AgentId', 'AgentVersion', 'AgentTier', 'ModelName', 'ResourceTier',
         | 
| 449 | 
            +
                'AgentCapabilities', 'AgentMetadata', 'AgentDefinition',
         | 
| 450 | 
            +
                
         | 
| 451 | 
            +
                # WebSocket types
         | 
| 452 | 
            +
                'EventName', 'EventData', 'SocketId', 'WebSocketMessage', 
         | 
| 453 | 
            +
                'ClaudeStatus', 'DelegationInfo',
         | 
| 454 | 
            +
                
         | 
| 455 | 
            +
                # Hook types
         | 
| 456 | 
            +
                'HookName', 'HookPriority', 'HookResult', 'HookConfig', 'HookContext',
         | 
| 457 | 
            +
                
         | 
| 458 | 
            +
                # Service types
         | 
| 459 | 
            +
                'ServiceName', 'ServiceStatus', 'ServiceConfig', 'ServiceInfo',
         | 
| 460 | 
            +
                
         | 
| 461 | 
            +
                # Memory types
         | 
| 462 | 
            +
                'MemoryType', 'MemoryId', 'Memory', 'MemorySearchResult',
         | 
| 463 | 
            +
                
         | 
| 464 | 
            +
                # Other types
         | 
| 465 | 
            +
                'ProjectConfig', 'DeploymentResult', 'ResponseLogEntry',
         | 
| 466 | 
            +
                'CommandName', 'CommandArgs', 'CommandResult',
         | 
| 467 | 
            +
                
         | 
| 468 | 
            +
                # Protocols
         | 
| 469 | 
            +
                'SessionProtocol', 'LoggerProtocol', 'WebSocketServerProtocol',
         | 
| 470 | 
            +
                'AgentServiceProtocol', 'MemoryServiceProtocol', 'ServiceContainer',
         | 
| 471 | 
            +
                
         | 
| 472 | 
            +
                # Generic type variables
         | 
| 473 | 
            +
                'T', 'TSession', 'TAgent', 'TService',
         | 
| 474 | 
            +
                
         | 
| 475 | 
            +
                # Common combinations
         | 
| 476 | 
            +
                'CommonTypes', 'ConfigDict', 'ErrorResult', 'SuccessResult',
         | 
| 477 | 
            +
            ]
         | 
| @@ -328,8 +328,20 @@ class FileToolTracker { | |
| 328 328 | 
             
                 */
         | 
| 329 329 | 
             
                isFileOperation(event) {
         | 
| 330 330 | 
             
                    // File operations are tool events with tools that operate on files
         | 
| 331 | 
            -
                     | 
| 332 | 
            -
                     | 
| 331 | 
            +
                    // Check case-insensitively since tool names can come in different cases
         | 
| 332 | 
            +
                    const fileTools = ['read', 'write', 'edit', 'grep', 'multiedit', 'glob', 'ls', 'bash', 'notebookedit'];
         | 
| 333 | 
            +
                    const toolName = event.tool_name ? event.tool_name.toLowerCase() : '';
         | 
| 334 | 
            +
                    
         | 
| 335 | 
            +
                    // Also check if Bash commands involve file operations
         | 
| 336 | 
            +
                    if (toolName === 'bash' && event.tool_parameters) {
         | 
| 337 | 
            +
                        const command = event.tool_parameters.command || '';
         | 
| 338 | 
            +
                        // Check for common file operations in bash commands
         | 
| 339 | 
            +
                        if (command.match(/\b(cat|less|more|head|tail|touch|mv|cp|rm|mkdir|ls|find)\b/)) {
         | 
| 340 | 
            +
                            return true;
         | 
| 341 | 
            +
                        }
         | 
| 342 | 
            +
                    }
         | 
| 343 | 
            +
                    
         | 
| 344 | 
            +
                    return toolName && fileTools.includes(toolName);
         | 
| 333 345 | 
             
                }
         | 
| 334 346 |  | 
| 335 347 | 
             
                /**
         | 
| @@ -341,11 +353,28 @@ class FileToolTracker { | |
| 341 353 | 
             
                    // Try various locations where file path might be stored
         | 
| 342 354 | 
             
                    if (event.tool_parameters?.file_path) return event.tool_parameters.file_path;
         | 
| 343 355 | 
             
                    if (event.tool_parameters?.path) return event.tool_parameters.path;
         | 
| 356 | 
            +
                    if (event.tool_parameters?.notebook_path) return event.tool_parameters.notebook_path;
         | 
| 344 357 | 
             
                    if (event.data?.tool_parameters?.file_path) return event.data.tool_parameters.file_path;
         | 
| 345 358 | 
             
                    if (event.data?.tool_parameters?.path) return event.data.tool_parameters.path;
         | 
| 359 | 
            +
                    if (event.data?.tool_parameters?.notebook_path) return event.data.tool_parameters.notebook_path;
         | 
| 346 360 | 
             
                    if (event.file_path) return event.file_path;
         | 
| 347 361 | 
             
                    if (event.path) return event.path;
         | 
| 348 362 |  | 
| 363 | 
            +
                    // For Glob tool, use the pattern as a pseudo-path
         | 
| 364 | 
            +
                    if (event.tool_name?.toLowerCase() === 'glob' && event.tool_parameters?.pattern) {
         | 
| 365 | 
            +
                        return `[glob] ${event.tool_parameters.pattern}`;
         | 
| 366 | 
            +
                    }
         | 
| 367 | 
            +
                    
         | 
| 368 | 
            +
                    // For Bash commands, try to extract file paths from the command
         | 
| 369 | 
            +
                    if (event.tool_name?.toLowerCase() === 'bash' && event.tool_parameters?.command) {
         | 
| 370 | 
            +
                        const command = event.tool_parameters.command;
         | 
| 371 | 
            +
                        // Try to extract file paths from common patterns
         | 
| 372 | 
            +
                        const fileMatch = command.match(/(?:cat|less|more|head|tail|touch|mv|cp|rm|mkdir|ls|find|echo.*>|sed|awk|grep)\s+([^\s;|&]+)/);
         | 
| 373 | 
            +
                        if (fileMatch && fileMatch[1]) {
         | 
| 374 | 
            +
                            return fileMatch[1];
         | 
| 375 | 
            +
                        }
         | 
| 376 | 
            +
                    }
         | 
| 377 | 
            +
                    
         | 
| 349 378 | 
             
                    return null;
         | 
| 350 379 | 
             
                }
         | 
| 351 380 |  | 
| @@ -383,7 +412,22 @@ class FileToolTracker { | |
| 383 412 | 
             
                        case 'write': return 'write';
         | 
| 384 413 | 
             
                        case 'edit': return 'edit';
         | 
| 385 414 | 
             
                        case 'multiedit': return 'edit';
         | 
| 415 | 
            +
                        case 'notebookedit': return 'edit';
         | 
| 386 416 | 
             
                        case 'grep': return 'search';
         | 
| 417 | 
            +
                        case 'glob': return 'search';
         | 
| 418 | 
            +
                        case 'ls': return 'list';
         | 
| 419 | 
            +
                        case 'bash': 
         | 
| 420 | 
            +
                            // Check bash command for file operation type
         | 
| 421 | 
            +
                            const command = event.tool_parameters?.command || '';
         | 
| 422 | 
            +
                            if (command.match(/\b(cat|less|more|head|tail)\b/)) return 'read';
         | 
| 423 | 
            +
                            if (command.match(/\b(touch|echo.*>|tee)\b/)) return 'write';
         | 
| 424 | 
            +
                            if (command.match(/\b(sed|awk)\b/)) return 'edit';
         | 
| 425 | 
            +
                            if (command.match(/\b(grep|find)\b/)) return 'search';
         | 
| 426 | 
            +
                            if (command.match(/\b(ls|dir)\b/)) return 'list';
         | 
| 427 | 
            +
                            if (command.match(/\b(mv|cp)\b/)) return 'copy/move';
         | 
| 428 | 
            +
                            if (command.match(/\b(rm|rmdir)\b/)) return 'delete';
         | 
| 429 | 
            +
                            if (command.match(/\b(mkdir)\b/)) return 'create';
         | 
| 430 | 
            +
                            return 'bash';
         | 
| 387 431 | 
             
                        default: return toolName;
         | 
| 388 432 | 
             
                    }
         | 
| 389 433 | 
             
                }
         | 
| @@ -334,11 +334,11 @@ | |
| 334 334 | 
             
                <!-- New modular components -->
         | 
| 335 335 | 
             
                <script src="/static/js/components/socket-manager.js"></script>
         | 
| 336 336 | 
             
                <script src="/static/js/components/agent-inference.js"></script>
         | 
| 337 | 
            -
                <script src="/static/js/components/ui-state-manager.js"></script>
         | 
| 338 | 
            -
                <script src="/static/js/components/working-directory.js"></script>
         | 
| 339 | 
            -
                <script src="/static/js/components/file-tool-tracker.js"></script>
         | 
| 340 | 
            -
                <script src="/static/js/components/event-processor.js"></script>
         | 
| 341 | 
            -
                <script src="/static/js/components/export-manager.js"></script>
         | 
| 337 | 
            +
                <script src="/static/js/components/ui-state-manager.js?v=1.0"></script>
         | 
| 338 | 
            +
                <script src="/static/js/components/working-directory.js?v=1.0"></script>
         | 
| 339 | 
            +
                <script src="/static/js/components/file-tool-tracker.js?v=1.1"></script>
         | 
| 340 | 
            +
                <script src="/static/js/components/event-processor.js?v=1.0"></script>
         | 
| 341 | 
            +
                <script src="/static/js/components/export-manager.js?v=1.0"></script>
         | 
| 342 342 |  | 
| 343 343 | 
             
                <!-- Main dashboard coordinator -->
         | 
| 344 344 | 
             
                <script src="/static/js/dashboard.js"></script>
         |