claude-mpm 3.5.4__py3-none-any.whl → 3.5.6__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/.claude-mpm/logs/hooks_20250728.log +10 -0
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/INSTRUCTIONS.md +12 -11
- claude_mpm/agents/agent-template.yaml +83 -0
- claude_mpm/cli/README.md +108 -0
- claude_mpm/cli/commands/agents.py +21 -3
- claude_mpm/cli/commands/run.py +4 -11
- claude_mpm/cli/utils.py +9 -1
- claude_mpm/cli_module/refactoring_guide.md +253 -0
- claude_mpm/config/async_logging_config.yaml +145 -0
- claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +34 -0
- claude_mpm/core/claude_runner.py +94 -33
- claude_mpm/core/config_paths.py +0 -1
- claude_mpm/core/factories.py +9 -3
- claude_mpm/dashboard/.claude-mpm/memories/README.md +36 -0
- claude_mpm/dashboard/README.md +121 -0
- claude_mpm/dashboard/static/js/dashboard.js.backup +1973 -0
- claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +36 -0
- claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +39 -0
- claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +38 -0
- claude_mpm/hooks/README.md +96 -0
- claude_mpm/init.py +83 -13
- claude_mpm/schemas/agent_schema.json +435 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +165 -9
- claude_mpm/services/agents/management/agent_management_service.py +2 -1
- claude_mpm/services/framework_claude_md_generator/README.md +92 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +3 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +2 -2
- claude_mpm/services/version_control/VERSION +1 -0
- {claude_mpm-3.5.4.dist-info → claude_mpm-3.5.6.dist-info}/METADATA +43 -1
- {claude_mpm-3.5.4.dist-info → claude_mpm-3.5.6.dist-info}/RECORD +35 -19
- {claude_mpm-3.5.4.dist-info → claude_mpm-3.5.6.dist-info}/WHEEL +0 -0
- {claude_mpm-3.5.4.dist-info → claude_mpm-3.5.6.dist-info}/entry_points.txt +0 -0
- {claude_mpm-3.5.4.dist-info → claude_mpm-3.5.6.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-3.5.4.dist-info → claude_mpm-3.5.6.dist-info}/top_level.txt +0 -0
| @@ -0,0 +1,145 @@ | |
| 1 | 
            +
            # Async Logging Configuration
         | 
| 2 | 
            +
            # Optimized logging configuration for high-performance scenarios
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            logging:
         | 
| 5 | 
            +
              # Enable async logging for improved performance
         | 
| 6 | 
            +
              async:
         | 
| 7 | 
            +
                enabled: true
         | 
| 8 | 
            +
                
         | 
| 9 | 
            +
                # Log format options: json, syslog, journald
         | 
| 10 | 
            +
                format: json
         | 
| 11 | 
            +
                
         | 
| 12 | 
            +
                # Maximum queue size for async writes
         | 
| 13 | 
            +
                max_queue_size: 10000
         | 
| 14 | 
            +
                
         | 
| 15 | 
            +
                # Enable compression for JSON logs (reduces disk usage)
         | 
| 16 | 
            +
                compression: false
         | 
| 17 | 
            +
                
         | 
| 18 | 
            +
                # Worker threads for async processing
         | 
| 19 | 
            +
                worker_threads: 4
         | 
| 20 | 
            +
                
         | 
| 21 | 
            +
                # Flush timeout in seconds
         | 
| 22 | 
            +
                flush_timeout: 5.0
         | 
| 23 | 
            +
              
         | 
| 24 | 
            +
              # Session logger settings
         | 
| 25 | 
            +
              session:
         | 
| 26 | 
            +
                # Base directory for logs
         | 
| 27 | 
            +
                base_dir: ".claude-mpm/responses"
         | 
| 28 | 
            +
                
         | 
| 29 | 
            +
                # Use timestamp-based filenames (eliminates race conditions)
         | 
| 30 | 
            +
                timestamp_filenames: true
         | 
| 31 | 
            +
                
         | 
| 32 | 
            +
                # Include microseconds in timestamps for uniqueness
         | 
| 33 | 
            +
                microsecond_precision: true
         | 
| 34 | 
            +
                
         | 
| 35 | 
            +
                # Filename format with available variables:
         | 
| 36 | 
            +
                # {agent} - Agent name
         | 
| 37 | 
            +
                # {timestamp} - ISO timestamp
         | 
| 38 | 
            +
                # {microseconds} - Microsecond component
         | 
| 39 | 
            +
                # {session} - Session ID
         | 
| 40 | 
            +
                filename_format: "{agent}_{timestamp}_{microseconds}.json"
         | 
| 41 | 
            +
              
         | 
| 42 | 
            +
              # OS-native logging options (for extreme performance)
         | 
| 43 | 
            +
              syslog:
         | 
| 44 | 
            +
                # Syslog address (auto-detected by default)
         | 
| 45 | 
            +
                # address: /var/run/syslog  # macOS
         | 
| 46 | 
            +
                # address: /dev/log         # Linux
         | 
| 47 | 
            +
                # address: ["localhost", 514]  # Network
         | 
| 48 | 
            +
                
         | 
| 49 | 
            +
                # Syslog facility
         | 
| 50 | 
            +
                facility: local0
         | 
| 51 | 
            +
                
         | 
| 52 | 
            +
                # Include structured data
         | 
| 53 | 
            +
                structured_data: true
         | 
| 54 | 
            +
              
         | 
| 55 | 
            +
              # Performance tuning
         | 
| 56 | 
            +
              performance:
         | 
| 57 | 
            +
                # Fire-and-forget mode (don't wait for write confirmation)
         | 
| 58 | 
            +
                fire_and_forget: true
         | 
| 59 | 
            +
                
         | 
| 60 | 
            +
                # Drop logs if queue is full (prevents blocking)
         | 
| 61 | 
            +
                drop_on_full: true
         | 
| 62 | 
            +
                
         | 
| 63 | 
            +
                # Batch writes for efficiency
         | 
| 64 | 
            +
                batch_writes: true
         | 
| 65 | 
            +
                batch_size: 10
         | 
| 66 | 
            +
                batch_timeout_ms: 100
         | 
| 67 | 
            +
             | 
| 68 | 
            +
            # Hook system optimization
         | 
| 69 | 
            +
            hooks:
         | 
| 70 | 
            +
              # Enable hook system
         | 
| 71 | 
            +
              enabled: true
         | 
| 72 | 
            +
              
         | 
| 73 | 
            +
              # Optimization settings
         | 
| 74 | 
            +
              optimization:
         | 
| 75 | 
            +
                # Cache hook configurations at startup
         | 
| 76 | 
            +
                cache_configs: true
         | 
| 77 | 
            +
                
         | 
| 78 | 
            +
                # Lazy load hook implementations
         | 
| 79 | 
            +
                lazy_loading: true
         | 
| 80 | 
            +
                
         | 
| 81 | 
            +
                # Use singleton pattern for hook service
         | 
| 82 | 
            +
                singleton: true
         | 
| 83 | 
            +
                
         | 
| 84 | 
            +
                # Enable async hook execution
         | 
| 85 | 
            +
                async_execution: true
         | 
| 86 | 
            +
                
         | 
| 87 | 
            +
                # Maximum workers for parallel hook execution
         | 
| 88 | 
            +
                max_workers: 4
         | 
| 89 | 
            +
              
         | 
| 90 | 
            +
              # Pre-delegation hooks
         | 
| 91 | 
            +
              pre_delegation:
         | 
| 92 | 
            +
                enabled: true
         | 
| 93 | 
            +
                
         | 
| 94 | 
            +
                # Parallel execution for independent hooks
         | 
| 95 | 
            +
                parallel_safe_hooks:
         | 
| 96 | 
            +
                  - memory_context_hook
         | 
| 97 | 
            +
                  - validation_hook
         | 
| 98 | 
            +
                  - auth_hook
         | 
| 99 | 
            +
              
         | 
| 100 | 
            +
              # Post-delegation hooks
         | 
| 101 | 
            +
              post_delegation:
         | 
| 102 | 
            +
                enabled: true
         | 
| 103 | 
            +
                
         | 
| 104 | 
            +
                # Parallel execution for independent hooks
         | 
| 105 | 
            +
                parallel_safe_hooks:
         | 
| 106 | 
            +
                  - logging_hook
         | 
| 107 | 
            +
                  - metrics_hook
         | 
| 108 | 
            +
                  - cleanup_hook
         | 
| 109 | 
            +
              
         | 
| 110 | 
            +
              # Registered hooks with lazy loading
         | 
| 111 | 
            +
              registered:
         | 
| 112 | 
            +
                # NOTE: The builtin hooks have been deprecated and removed
         | 
| 113 | 
            +
                # These references are kept commented for historical reference
         | 
| 114 | 
            +
                # memory_context_hook:
         | 
| 115 | 
            +
                #   module: claude_mpm.hooks.builtin.memory_hooks
         | 
| 116 | 
            +
                #   class: MemoryContextHook
         | 
| 117 | 
            +
                #   priority: 10
         | 
| 118 | 
            +
                #   enabled: true
         | 
| 119 | 
            +
                #   params:
         | 
| 120 | 
            +
                #     cache_size: 1000
         | 
| 121 | 
            +
                # 
         | 
| 122 | 
            +
                # response_logger_hook:
         | 
| 123 | 
            +
                #   module: claude_mpm.hooks.builtin.logging_hooks
         | 
| 124 | 
            +
                #   class: ResponseLoggerHook
         | 
| 125 | 
            +
                #   priority: 90
         | 
| 126 | 
            +
                #   enabled: true
         | 
| 127 | 
            +
                #   params:
         | 
| 128 | 
            +
                #     async: true
         | 
| 129 | 
            +
                # 
         | 
| 130 | 
            +
                # metrics_hook:
         | 
| 131 | 
            +
                #   module: claude_mpm.hooks.builtin.metrics_hooks
         | 
| 132 | 
            +
                #   class: MetricsCollectorHook
         | 
| 133 | 
            +
                #   priority: 95
         | 
| 134 | 
            +
                #   enabled: true
         | 
| 135 | 
            +
                #   params:
         | 
| 136 | 
            +
                #     buffer_size: 100
         | 
| 137 | 
            +
             | 
| 138 | 
            +
            # Environment variable overrides
         | 
| 139 | 
            +
            # These can override any setting above:
         | 
| 140 | 
            +
            #
         | 
| 141 | 
            +
            # CLAUDE_USE_ASYNC_LOG=true        # Enable async logging
         | 
| 142 | 
            +
            # CLAUDE_LOG_FORMAT=syslog         # Use syslog format
         | 
| 143 | 
            +
            # CLAUDE_LOG_SYNC=true             # Disable async (for debugging)
         | 
| 144 | 
            +
            # CLAUDE_HOOKS_CACHE=true          # Enable hook caching
         | 
| 145 | 
            +
            # CLAUDE_HOOKS_ASYNC=true          # Enable async hooks
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            2025-07-30 12:40:20,992 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PostToolUse (session: df539357)
         | 
| 2 | 
            +
            2025-07-30 12:40:20,992 - claude_mpm_hooks_core - INFO - hook_handler.py:254 - PostToolUse: Bash (exit code: N/A)
         | 
| 3 | 
            +
            2025-07-30 12:40:33,117 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
         | 
| 4 | 
            +
            2025-07-30 12:40:33,117 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Edit
         | 
| 5 | 
            +
            2025-07-30 12:40:33,276 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PostToolUse (session: df539357)
         | 
| 6 | 
            +
            2025-07-30 12:40:33,276 - claude_mpm_hooks_core - INFO - hook_handler.py:254 - PostToolUse: Edit (exit code: N/A)
         | 
| 7 | 
            +
            2025-07-30 12:40:39,276 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
         | 
| 8 | 
            +
            2025-07-30 12:40:39,276 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Bash
         | 
| 9 | 
            +
            2025-07-30 12:40:39,541 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PostToolUse (session: df539357)
         | 
| 10 | 
            +
            2025-07-30 12:40:39,541 - claude_mpm_hooks_core - INFO - hook_handler.py:254 - PostToolUse: Bash (exit code: N/A)
         | 
| 11 | 
            +
            2025-07-30 12:40:48,610 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
         | 
| 12 | 
            +
            2025-07-30 12:40:48,610 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Bash
         | 
| 13 | 
            +
            2025-07-30 12:40:49,941 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PostToolUse (session: df539357)
         | 
| 14 | 
            +
            2025-07-30 12:40:49,941 - claude_mpm_hooks_core - INFO - hook_handler.py:254 - PostToolUse: Bash (exit code: N/A)
         | 
| 15 | 
            +
            2025-07-30 12:44:50,358 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: UserPromptSubmit (session: df539357)
         | 
| 16 | 
            +
            2025-07-30 12:44:50,358 - claude_mpm_hooks_core - INFO - hook_handler.py:244 - UserPromptSubmit: OK. Let's make the subprocess the default method
         | 
| 17 | 
            +
            2025-07-30 13:05:35,872 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: UserPromptSubmit (session: df539357)
         | 
| 18 | 
            +
            2025-07-30 13:05:35,872 - claude_mpm_hooks_core - INFO - hook_handler.py:244 - UserPromptSubmit: actually leave as is.  I want to figure out a simple test to trigger the terminal flow.  Use docs/de...
         | 
| 19 | 
            +
            2025-07-30 13:05:42,930 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
         | 
| 20 | 
            +
            2025-07-30 13:05:42,930 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Read
         | 
| 21 | 
            +
            2025-07-30 13:05:43,133 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PostToolUse (session: df539357)
         | 
| 22 | 
            +
            2025-07-30 13:05:43,133 - claude_mpm_hooks_core - INFO - hook_handler.py:254 - PostToolUse: Read (exit code: N/A)
         | 
| 23 | 
            +
            2025-07-30 13:05:49,996 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
         | 
| 24 | 
            +
            2025-07-30 13:05:49,996 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Grep
         | 
| 25 | 
            +
            2025-07-30 13:05:50,548 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PostToolUse (session: df539357)
         | 
| 26 | 
            +
            2025-07-30 13:05:50,548 - claude_mpm_hooks_core - INFO - hook_handler.py:254 - PostToolUse: Grep (exit code: N/A)
         | 
| 27 | 
            +
            2025-07-30 13:05:56,341 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
         | 
| 28 | 
            +
            2025-07-30 13:05:56,341 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Read
         | 
| 29 | 
            +
            2025-07-30 13:05:56,527 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PostToolUse (session: df539357)
         | 
| 30 | 
            +
            2025-07-30 13:05:56,528 - claude_mpm_hooks_core - INFO - hook_handler.py:254 - PostToolUse: Read (exit code: N/A)
         | 
| 31 | 
            +
            2025-07-30 13:06:01,890 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
         | 
| 32 | 
            +
            2025-07-30 13:06:01,890 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Bash
         | 
| 33 | 
            +
            2025-07-30 13:06:08,115 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
         | 
| 34 | 
            +
            2025-07-30 13:06:08,115 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Bash
         | 
    
        claude_mpm/core/claude_runner.py
    CHANGED
    
    | @@ -74,8 +74,16 @@ class ClaudeRunner: | |
| 74 74 | 
             
                            self.logger.warning(f"Failed to initialize project logger: {e}")
         | 
| 75 75 |  | 
| 76 76 | 
             
                    # Initialize services with proper error handling
         | 
| 77 | 
            +
                    # Determine the user's working directory from environment
         | 
| 78 | 
            +
                    user_working_dir = None
         | 
| 79 | 
            +
                    if 'CLAUDE_MPM_USER_PWD' in os.environ:
         | 
| 80 | 
            +
                        user_working_dir = Path(os.environ['CLAUDE_MPM_USER_PWD'])
         | 
| 81 | 
            +
                        self.logger.info(f"Using user working directory from CLAUDE_MPM_USER_PWD: {user_working_dir}")
         | 
| 82 | 
            +
                    
         | 
| 77 83 | 
             
                    try:
         | 
| 78 | 
            -
                         | 
| 84 | 
            +
                        # Pass the user working directory to the deployment service
         | 
| 85 | 
            +
                        # This ensures agents are deployed to the correct user directory, not the framework directory
         | 
| 86 | 
            +
                        self.deployment_service = AgentDeploymentService(working_directory=user_working_dir)
         | 
| 79 87 | 
             
                    except ImportError as e:
         | 
| 80 88 | 
             
                        self.logger.error(f"Failed to import AgentDeploymentService: {e}")
         | 
| 81 89 | 
             
                        raise RuntimeError("Required module AgentDeploymentService not available. Please reinstall claude-mpm.") from e
         | 
| @@ -253,8 +261,12 @@ class ClaudeRunner: | |
| 253 261 | 
             
                        bool: True if agents are available, False on error
         | 
| 254 262 | 
             
                    """
         | 
| 255 263 | 
             
                    try:
         | 
| 256 | 
            -
                        #  | 
| 257 | 
            -
                         | 
| 264 | 
            +
                        # Use the correct user directory, not the framework directory
         | 
| 265 | 
            +
                        if 'CLAUDE_MPM_USER_PWD' in os.environ:
         | 
| 266 | 
            +
                            project_dir = Path(os.environ['CLAUDE_MPM_USER_PWD'])
         | 
| 267 | 
            +
                        else:
         | 
| 268 | 
            +
                            project_dir = Path.cwd()
         | 
| 269 | 
            +
                        
         | 
| 258 270 | 
             
                        project_agents_dir = project_dir / ".claude-mpm" / "agents"
         | 
| 259 271 |  | 
| 260 272 | 
             
                        # Create directory if it doesn't exist
         | 
| @@ -321,7 +333,12 @@ class ClaudeRunner: | |
| 321 333 | 
             
                        bool: True if deployment successful or no agents to deploy, False on error
         | 
| 322 334 | 
             
                    """
         | 
| 323 335 | 
             
                    try:
         | 
| 324 | 
            -
                         | 
| 336 | 
            +
                        # Use the correct user directory, not the framework directory
         | 
| 337 | 
            +
                        if 'CLAUDE_MPM_USER_PWD' in os.environ:
         | 
| 338 | 
            +
                            project_dir = Path(os.environ['CLAUDE_MPM_USER_PWD'])
         | 
| 339 | 
            +
                        else:
         | 
| 340 | 
            +
                            project_dir = Path.cwd()
         | 
| 341 | 
            +
                        
         | 
| 325 342 | 
             
                        project_agents_dir = project_dir / ".claude-mpm" / "agents"
         | 
| 326 343 | 
             
                        claude_agents_dir = project_dir / ".claude" / "agents"
         | 
| 327 344 |  | 
| @@ -352,9 +369,41 @@ class ClaudeRunner: | |
| 352 369 | 
             
                        errors = []
         | 
| 353 370 |  | 
| 354 371 | 
             
                        # Deploy each JSON agent
         | 
| 372 | 
            +
                        # CRITICAL: PM (Project Manager) must NEVER be deployed as it's the main Claude instance
         | 
| 373 | 
            +
                        EXCLUDED_AGENTS = {'pm', 'project_manager'}
         | 
| 374 | 
            +
                        
         | 
| 375 | 
            +
                        # Initialize deployment service with proper base agent path
         | 
| 376 | 
            +
                        # Use the existing deployment service's base agent path if available
         | 
| 377 | 
            +
                        base_agent_path = project_agents_dir / "base_agent.json"
         | 
| 378 | 
            +
                        if not base_agent_path.exists():
         | 
| 379 | 
            +
                            # Fall back to system base agent
         | 
| 380 | 
            +
                            base_agent_path = self.deployment_service.base_agent_path
         | 
| 381 | 
            +
                        
         | 
| 382 | 
            +
                        # Create a single deployment service instance for all agents
         | 
| 383 | 
            +
                        project_deployment = AgentDeploymentService(
         | 
| 384 | 
            +
                            templates_dir=project_agents_dir,
         | 
| 385 | 
            +
                            base_agent_path=base_agent_path,
         | 
| 386 | 
            +
                            working_directory=project_dir  # Pass the project directory
         | 
| 387 | 
            +
                        )
         | 
| 388 | 
            +
                        
         | 
| 389 | 
            +
                        # Load base agent data once
         | 
| 390 | 
            +
                        base_agent_data = {}
         | 
| 391 | 
            +
                        if base_agent_path and base_agent_path.exists():
         | 
| 392 | 
            +
                            try:
         | 
| 393 | 
            +
                                import json
         | 
| 394 | 
            +
                                base_agent_data = json.loads(base_agent_path.read_text())
         | 
| 395 | 
            +
                            except Exception as e:
         | 
| 396 | 
            +
                                self.logger.warning(f"Could not load base agent: {e}")
         | 
| 397 | 
            +
                        
         | 
| 355 398 | 
             
                        for json_file in json_files:
         | 
| 356 399 | 
             
                            try:
         | 
| 357 400 | 
             
                                agent_name = json_file.stem
         | 
| 401 | 
            +
                                
         | 
| 402 | 
            +
                                # Skip PM agent - it's the main Claude instance, not a subagent
         | 
| 403 | 
            +
                                if agent_name.lower() in EXCLUDED_AGENTS:
         | 
| 404 | 
            +
                                    self.logger.info(f"Skipping {agent_name} (PM is the main Claude instance)")
         | 
| 405 | 
            +
                                    continue
         | 
| 406 | 
            +
                                
         | 
| 358 407 | 
             
                                target_file = claude_agents_dir / f"{agent_name}.md"
         | 
| 359 408 |  | 
| 360 409 | 
             
                                # Check if agent needs update
         | 
| @@ -369,26 +418,7 @@ class ClaudeRunner: | |
| 369 418 | 
             
                                            self.logger.debug(f"Project agent {agent_name} is up to date")
         | 
| 370 419 |  | 
| 371 420 | 
             
                                if needs_update:
         | 
| 372 | 
            -
                                    #  | 
| 373 | 
            -
                                    from claude_mpm.services.agents.deployment.agent_deployment import AgentDeploymentService
         | 
| 374 | 
            -
                                    
         | 
| 375 | 
            -
                                    # Create a temporary deployment service for this specific task
         | 
| 376 | 
            -
                                    project_deployment = AgentDeploymentService(
         | 
| 377 | 
            -
                                        templates_dir=project_agents_dir,
         | 
| 378 | 
            -
                                        base_agent_path=project_dir / ".claude-mpm" / "agents" / "base_agent.json"
         | 
| 379 | 
            -
                                    )
         | 
| 380 | 
            -
                                    
         | 
| 381 | 
            -
                                    # Load base agent data if available
         | 
| 382 | 
            -
                                    base_agent_data = {}
         | 
| 383 | 
            -
                                    base_agent_path = project_dir / ".claude-mpm" / "agents" / "base_agent.json"
         | 
| 384 | 
            -
                                    if base_agent_path.exists():
         | 
| 385 | 
            -
                                        import json
         | 
| 386 | 
            -
                                        try:
         | 
| 387 | 
            -
                                            base_agent_data = json.loads(base_agent_path.read_text())
         | 
| 388 | 
            -
                                        except Exception as e:
         | 
| 389 | 
            -
                                            self.logger.warning(f"Could not load project base agent: {e}")
         | 
| 390 | 
            -
                                    
         | 
| 391 | 
            -
                                    # Build the agent markdown
         | 
| 421 | 
            +
                                    # Build the agent markdown using the pre-initialized service and base agent data
         | 
| 392 422 | 
             
                                    agent_content = project_deployment._build_agent_markdown(
         | 
| 393 423 | 
             
                                        agent_name, json_file, base_agent_data
         | 
| 394 424 | 
             
                                    )
         | 
| @@ -1063,17 +1093,46 @@ class ClaudeRunner: | |
| 1063 1093 | 
             
                def _load_system_instructions(self) -> Optional[str]:
         | 
| 1064 1094 | 
             
                    """Load and process system instructions from agents/INSTRUCTIONS.md.
         | 
| 1065 1095 |  | 
| 1066 | 
            -
                     | 
| 1067 | 
            -
                     | 
| 1096 | 
            +
                    Implements project > framework precedence:
         | 
| 1097 | 
            +
                    1. First check for project-specific instructions in .claude-mpm/agents/INSTRUCTIONS.md
         | 
| 1098 | 
            +
                    2. If not found, fall back to framework instructions in src/claude_mpm/agents/INSTRUCTIONS.md
         | 
| 1099 | 
            +
                    
         | 
| 1100 | 
            +
                    WHY: Allows projects to override the default PM instructions with project-specific
         | 
| 1101 | 
            +
                    guidance, while maintaining backward compatibility with the framework defaults.
         | 
| 1102 | 
            +
                    
         | 
| 1103 | 
            +
                    DESIGN DECISION: Using CLAUDE_MPM_USER_PWD environment variable to locate the
         | 
| 1104 | 
            +
                    correct project directory, ensuring we check the right location even when
         | 
| 1105 | 
            +
                    claude-mpm is invoked from a different directory.
         | 
| 1068 1106 | 
             
                    """
         | 
| 1069 1107 | 
             
                    try:
         | 
| 1070 | 
            -
                        #  | 
| 1071 | 
            -
                         | 
| 1072 | 
            -
             | 
| 1108 | 
            +
                        # Determine the user's project directory
         | 
| 1109 | 
            +
                        if 'CLAUDE_MPM_USER_PWD' in os.environ:
         | 
| 1110 | 
            +
                            project_dir = Path(os.environ['CLAUDE_MPM_USER_PWD'])
         | 
| 1111 | 
            +
                        else:
         | 
| 1112 | 
            +
                            project_dir = Path.cwd()
         | 
| 1113 | 
            +
                        
         | 
| 1114 | 
            +
                        # Check for project-specific INSTRUCTIONS.md first
         | 
| 1115 | 
            +
                        project_instructions_path = project_dir / ".claude-mpm" / "agents" / "INSTRUCTIONS.md"
         | 
| 1116 | 
            +
                        
         | 
| 1117 | 
            +
                        instructions_path = None
         | 
| 1118 | 
            +
                        instructions_source = None
         | 
| 1073 1119 |  | 
| 1074 | 
            -
                        if  | 
| 1075 | 
            -
                             | 
| 1076 | 
            -
                             | 
| 1120 | 
            +
                        if project_instructions_path.exists():
         | 
| 1121 | 
            +
                            instructions_path = project_instructions_path
         | 
| 1122 | 
            +
                            instructions_source = "PROJECT"
         | 
| 1123 | 
            +
                            self.logger.info(f"Found project-specific INSTRUCTIONS.md: {instructions_path}")
         | 
| 1124 | 
            +
                        else:
         | 
| 1125 | 
            +
                            # Fall back to framework instructions
         | 
| 1126 | 
            +
                            module_path = Path(__file__).parent.parent
         | 
| 1127 | 
            +
                            framework_instructions_path = module_path / "agents" / "INSTRUCTIONS.md"
         | 
| 1128 | 
            +
                            
         | 
| 1129 | 
            +
                            if framework_instructions_path.exists():
         | 
| 1130 | 
            +
                                instructions_path = framework_instructions_path
         | 
| 1131 | 
            +
                                instructions_source = "FRAMEWORK"
         | 
| 1132 | 
            +
                                self.logger.info(f"Using framework INSTRUCTIONS.md: {instructions_path}")
         | 
| 1133 | 
            +
                            else:
         | 
| 1134 | 
            +
                                self.logger.warning(f"No INSTRUCTIONS.md found in project or framework")
         | 
| 1135 | 
            +
                                return None
         | 
| 1077 1136 |  | 
| 1078 1137 | 
             
                        # Read raw instructions
         | 
| 1079 1138 | 
             
                        raw_instructions = instructions_path.read_text()
         | 
| @@ -1083,13 +1142,15 @@ class ClaudeRunner: | |
| 1083 1142 | 
             
                            from claude_mpm.services.framework_claude_md_generator.content_assembler import ContentAssembler
         | 
| 1084 1143 | 
             
                            assembler = ContentAssembler()
         | 
| 1085 1144 | 
             
                            processed_instructions = assembler.apply_template_variables(raw_instructions)
         | 
| 1086 | 
            -
                            self.logger.info("Loaded and processed PM  | 
| 1145 | 
            +
                            self.logger.info(f"Loaded and processed {instructions_source} PM instructions with dynamic capabilities")
         | 
| 1087 1146 | 
             
                            return processed_instructions
         | 
| 1088 1147 | 
             
                        except ImportError:
         | 
| 1089 1148 | 
             
                            self.logger.warning("ContentAssembler not available, using raw instructions")
         | 
| 1149 | 
            +
                            self.logger.info(f"Loaded {instructions_source} PM instructions (raw)")
         | 
| 1090 1150 | 
             
                            return raw_instructions
         | 
| 1091 1151 | 
             
                        except Exception as e:
         | 
| 1092 1152 | 
             
                            self.logger.warning(f"Failed to process template variables: {e}, using raw instructions")
         | 
| 1153 | 
            +
                            self.logger.info(f"Loaded {instructions_source} PM instructions (raw, processing failed)")
         | 
| 1093 1154 | 
             
                            return raw_instructions
         | 
| 1094 1155 |  | 
| 1095 1156 | 
             
                    except Exception as e:
         | 
    
        claude_mpm/core/config_paths.py
    CHANGED
    
    
    
        claude_mpm/core/factories.py
    CHANGED
    
    | @@ -57,14 +57,20 @@ class AgentServiceFactory(ServiceFactory): | |
| 57 57 | 
             
                    config = container.resolve(Config)
         | 
| 58 58 |  | 
| 59 59 | 
             
                    # Get directories from config if not provided
         | 
| 60 | 
            +
                    import os
         | 
| 61 | 
            +
                    
         | 
| 60 62 | 
             
                    if framework_dir is None:
         | 
| 61 63 | 
             
                        framework_dir = Path(config.get('framework.dir', 'framework'))
         | 
| 62 64 |  | 
| 63 65 | 
             
                    if project_dir is None:
         | 
| 64 | 
            -
                         | 
| 66 | 
            +
                        # Check for user working directory from environment
         | 
| 67 | 
            +
                        if 'CLAUDE_MPM_USER_PWD' in os.environ:
         | 
| 68 | 
            +
                            project_dir = Path(os.environ['CLAUDE_MPM_USER_PWD'])
         | 
| 69 | 
            +
                        else:
         | 
| 70 | 
            +
                            project_dir = Path(config.get('project.dir', '.'))
         | 
| 65 71 |  | 
| 66 | 
            -
                    # Create service with  | 
| 67 | 
            -
                    service = AgentDeploymentService()
         | 
| 72 | 
            +
                    # Create service with proper working directory
         | 
| 73 | 
            +
                    service = AgentDeploymentService(working_directory=project_dir)
         | 
| 68 74 |  | 
| 69 75 | 
             
                    # Inject any required dependencies
         | 
| 70 76 | 
             
                    if hasattr(service, 'set_directories'):
         | 
| @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            # Agent Memory System
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            ## Purpose
         | 
| 4 | 
            +
            Each agent maintains project-specific knowledge in these files. Agents read their memory file before tasks and update it when they learn something new.
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            ## Manual Editing
         | 
| 7 | 
            +
            Feel free to edit these files to:
         | 
| 8 | 
            +
            - Add project-specific guidelines
         | 
| 9 | 
            +
            - Remove outdated information  
         | 
| 10 | 
            +
            - Reorganize for better clarity
         | 
| 11 | 
            +
            - Add domain-specific knowledge
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            ## Memory Limits
         | 
| 14 | 
            +
            - Max file size: 8KB (~2000 tokens)
         | 
| 15 | 
            +
            - Max sections: 10
         | 
| 16 | 
            +
            - Max items per section: 15
         | 
| 17 | 
            +
            - Files auto-truncate when limits exceeded
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            ## File Format
         | 
| 20 | 
            +
            Standard markdown with structured sections. Agents expect:
         | 
| 21 | 
            +
            - Project Architecture
         | 
| 22 | 
            +
            - Implementation Guidelines
         | 
| 23 | 
            +
            - Common Mistakes to Avoid
         | 
| 24 | 
            +
            - Current Technical Context
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            ## How It Works
         | 
| 27 | 
            +
            1. Agents read their memory file before starting tasks
         | 
| 28 | 
            +
            2. Agents add learnings during or after task completion
         | 
| 29 | 
            +
            3. Files automatically enforce size limits
         | 
| 30 | 
            +
            4. Developers can manually edit for accuracy
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            ## Memory File Lifecycle
         | 
| 33 | 
            +
            - Created automatically when agent first runs
         | 
| 34 | 
            +
            - Updated through hook system after delegations
         | 
| 35 | 
            +
            - Manually editable by developers
         | 
| 36 | 
            +
            - Version controlled with project
         | 
| @@ -0,0 +1,121 @@ | |
| 1 | 
            +
            # Claude MPM Web Dashboard
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            This directory contains the modular web dashboard for Claude MPM monitoring and management.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            ## Structure
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            ```
         | 
| 8 | 
            +
            src/claude_mpm/dashboard/
         | 
| 9 | 
            +
            ├── static/
         | 
| 10 | 
            +
            │   ├── css/
         | 
| 11 | 
            +
            │   │   └── dashboard.css          # Main stylesheet
         | 
| 12 | 
            +
            │   └── js/
         | 
| 13 | 
            +
            │       ├── socket-client.js       # Socket.IO connection management
         | 
| 14 | 
            +
            │       ├── dashboard.js          # Main dashboard application
         | 
| 15 | 
            +
            │       └── components/
         | 
| 16 | 
            +
            │           ├── event-viewer.js    # Event display and filtering
         | 
| 17 | 
            +
            │           ├── module-viewer.js   # Event detail viewer
         | 
| 18 | 
            +
            │           └── session-manager.js # Session management
         | 
| 19 | 
            +
            ├── templates/
         | 
| 20 | 
            +
            │   └── index.html               # Main dashboard HTML
         | 
| 21 | 
            +
            ├── index.html                   # Root index with redirect
         | 
| 22 | 
            +
            ├── test_dashboard.html          # Test version for verification
         | 
| 23 | 
            +
            └── README.md                    # This file
         | 
| 24 | 
            +
            ```
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            ## Components
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            ### SocketClient (`socket-client.js`)
         | 
| 29 | 
            +
            - Manages WebSocket connections to the Claude MPM server
         | 
| 30 | 
            +
            - Handles event reception and processing
         | 
| 31 | 
            +
            - Provides callbacks for connection state changes
         | 
| 32 | 
            +
            - Maintains event history and session tracking
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            ### EventViewer (`components/event-viewer.js`)
         | 
| 35 | 
            +
            - Displays events in a filterable list
         | 
| 36 | 
            +
            - Supports search, type filtering, and session filtering
         | 
| 37 | 
            +
            - Handles event selection and keyboard navigation
         | 
| 38 | 
            +
            - Updates metrics display (total events, events per minute, etc.)
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            ### ModuleViewer (`components/module-viewer.js`)
         | 
| 41 | 
            +
            - Shows detailed information about selected events
         | 
| 42 | 
            +
            - Provides structured views for different event types
         | 
| 43 | 
            +
            - Displays raw JSON data for debugging
         | 
| 44 | 
            +
            - Organizes events by class/category
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            ### SessionManager (`components/session-manager.js`)
         | 
| 47 | 
            +
            - Manages session selection and filtering
         | 
| 48 | 
            +
            - Updates session dropdown with available sessions
         | 
| 49 | 
            +
            - Tracks current active session
         | 
| 50 | 
            +
            - Updates footer information
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            ### Dashboard (`dashboard.js`)
         | 
| 53 | 
            +
            - Main application coordinator
         | 
| 54 | 
            +
            - Handles tab switching between Events, Agents, Tools, and Files
         | 
| 55 | 
            +
            - Manages component interactions
         | 
| 56 | 
            +
            - Provides global functions for backward compatibility
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            ## Features
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            ### File-Centric Files Tab
         | 
| 61 | 
            +
            The Files tab now shows a file-centric view where:
         | 
| 62 | 
            +
            - Each file appears only once in the list
         | 
| 63 | 
            +
            - Files show read/write icons based on operations performed
         | 
| 64 | 
            +
            - Most recently accessed files appear at the bottom
         | 
| 65 | 
            +
            - Clicking a file shows all operations performed on it with timestamps and agent information
         | 
| 66 | 
            +
             | 
| 67 | 
            +
            ### Tab Organization
         | 
| 68 | 
            +
            - **Events**: All events with filtering and search
         | 
| 69 | 
            +
            - **Agents**: Agent-specific events and operations
         | 
| 70 | 
            +
            - **Tools**: Tool usage and parameters
         | 
| 71 | 
            +
            - **Files**: File operations organized by file path
         | 
| 72 | 
            +
             | 
| 73 | 
            +
            ### Enhanced Event Details
         | 
| 74 | 
            +
            - Structured views for different event types
         | 
| 75 | 
            +
            - Todo checklists with status indicators
         | 
| 76 | 
            +
            - Agent and tool information
         | 
| 77 | 
            +
            - Session tracking and filtering
         | 
| 78 | 
            +
             | 
| 79 | 
            +
            ## Usage
         | 
| 80 | 
            +
             | 
| 81 | 
            +
            ### Development
         | 
| 82 | 
            +
            For development and testing, use `test_dashboard.html` which includes module verification.
         | 
| 83 | 
            +
             | 
| 84 | 
            +
            ### Production
         | 
| 85 | 
            +
            Use `templates/dashboard.html` as the main template, ensuring all static files are served correctly.
         | 
| 86 | 
            +
             | 
| 87 | 
            +
            ### Integration
         | 
| 88 | 
            +
            The dashboard can be integrated into a Flask/FastAPI application by serving the static files and using the template.
         | 
| 89 | 
            +
             | 
| 90 | 
            +
            ## Migration from Original
         | 
| 91 | 
            +
             | 
| 92 | 
            +
            The original monolithic `claude_mpm_socketio_dashboard.html` has been replaced with a modular structure:
         | 
| 93 | 
            +
             | 
| 94 | 
            +
            1. **CSS**: Extracted to `static/css/dashboard.css`
         | 
| 95 | 
            +
            2. **JavaScript**: Split into logical modules in `static/js/`
         | 
| 96 | 
            +
            3. **HTML**: Clean template in `templates/dashboard.html`
         | 
| 97 | 
            +
             | 
| 98 | 
            +
            All original functionality has been preserved while improving:
         | 
| 99 | 
            +
            - Code organization and maintainability
         | 
| 100 | 
            +
            - Module reusability
         | 
| 101 | 
            +
            - Easier debugging and development
         | 
| 102 | 
            +
            - Better separation of concerns
         | 
| 103 | 
            +
             | 
| 104 | 
            +
            ## Backward Compatibility
         | 
| 105 | 
            +
             | 
| 106 | 
            +
            Global functions are maintained for compatibility:
         | 
| 107 | 
            +
            - `connectSocket()`
         | 
| 108 | 
            +
            - `disconnectSocket()`
         | 
| 109 | 
            +
            - `clearEvents()`
         | 
| 110 | 
            +
            - `exportEvents()`
         | 
| 111 | 
            +
            - `clearSelection()`
         | 
| 112 | 
            +
            - `switchTab(tabName)`
         | 
| 113 | 
            +
             | 
| 114 | 
            +
            ## Browser Support
         | 
| 115 | 
            +
             | 
| 116 | 
            +
            Requires modern browsers with support for:
         | 
| 117 | 
            +
            - ES6 Classes
         | 
| 118 | 
            +
            - Fetch API
         | 
| 119 | 
            +
            - Custom Events
         | 
| 120 | 
            +
            - CSS Grid/Flexbox
         | 
| 121 | 
            +
            - Socket.IO 4.x
         |