claude-mpm 3.5.4__py3-none-any.whl → 3.6.0__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/BASE_AGENT_TEMPLATE.md +96 -23
- claude_mpm/agents/BASE_PM.md +273 -0
- claude_mpm/agents/INSTRUCTIONS.md +114 -102
- claude_mpm/agents/agent-template.yaml +83 -0
- claude_mpm/agents/agent_loader.py +36 -1
- claude_mpm/agents/async_agent_loader.py +421 -0
- claude_mpm/agents/templates/code_analyzer.json +81 -0
- claude_mpm/agents/templates/data_engineer.json +18 -3
- claude_mpm/agents/templates/documentation.json +18 -3
- claude_mpm/agents/templates/engineer.json +19 -4
- claude_mpm/agents/templates/ops.json +18 -3
- claude_mpm/agents/templates/qa.json +20 -4
- claude_mpm/agents/templates/research.json +20 -4
- claude_mpm/agents/templates/security.json +18 -3
- claude_mpm/agents/templates/version_control.json +16 -3
- claude_mpm/cli/README.md +108 -0
- claude_mpm/cli/__init__.py +5 -1
- claude_mpm/cli/commands/__init__.py +5 -1
- claude_mpm/cli/commands/agents.py +233 -6
- claude_mpm/cli/commands/aggregate.py +462 -0
- claude_mpm/cli/commands/config.py +277 -0
- claude_mpm/cli/commands/run.py +228 -47
- claude_mpm/cli/parser.py +176 -1
- 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/constants.py +19 -0
- claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +34 -0
- claude_mpm/core/claude_runner.py +413 -76
- claude_mpm/core/config.py +161 -4
- claude_mpm/core/config_paths.py +0 -1
- claude_mpm/core/factories.py +9 -3
- claude_mpm/core/framework_loader.py +81 -0
- 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/hooks/claude_hooks/hook_handler.py +391 -9
- claude_mpm/init.py +123 -18
- claude_mpm/models/agent_session.py +511 -0
- claude_mpm/schemas/agent_schema.json +435 -0
- claude_mpm/scripts/__init__.py +15 -0
- claude_mpm/scripts/start_activity_logging.py +86 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +326 -24
- claude_mpm/services/agents/deployment/async_agent_deployment.py +461 -0
- claude_mpm/services/agents/management/agent_management_service.py +2 -1
- claude_mpm/services/event_aggregator.py +547 -0
- 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/utils/agent_dependency_loader.py +655 -0
- claude_mpm/utils/console.py +11 -0
- claude_mpm/utils/dependency_cache.py +376 -0
- claude_mpm/utils/dependency_strategies.py +343 -0
- claude_mpm/utils/environment_context.py +310 -0
- {claude_mpm-3.5.4.dist-info → claude_mpm-3.6.0.dist-info}/METADATA +87 -1
- {claude_mpm-3.5.4.dist-info → claude_mpm-3.6.0.dist-info}/RECORD +67 -37
- claude_mpm/agents/templates/pm.json +0 -122
- {claude_mpm-3.5.4.dist-info → claude_mpm-3.6.0.dist-info}/WHEEL +0 -0
- {claude_mpm-3.5.4.dist-info → claude_mpm-3.6.0.dist-info}/entry_points.txt +0 -0
- {claude_mpm-3.5.4.dist-info → claude_mpm-3.6.0.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-3.5.4.dist-info → claude_mpm-3.6.0.dist-info}/top_level.txt +0 -0
| @@ -15,6 +15,7 @@ from ...constants import AgentCommands | |
| 15 15 | 
             
            from ..utils import get_agent_versions_display
         | 
| 16 16 | 
             
            from ...core.agent_registry import AgentRegistryAdapter
         | 
| 17 17 | 
             
            from ...agents.frontmatter_validator import FrontmatterValidator
         | 
| 18 | 
            +
            from ...core.config import Config
         | 
| 18 19 |  | 
| 19 20 |  | 
| 20 21 | 
             
            def manage_agents(args):
         | 
| @@ -34,7 +35,16 @@ def manage_agents(args): | |
| 34 35 |  | 
| 35 36 | 
             
                try:
         | 
| 36 37 | 
             
                    from ...services import AgentDeploymentService
         | 
| 37 | 
            -
                     | 
| 38 | 
            +
                    import os
         | 
| 39 | 
            +
                    from pathlib import Path
         | 
| 40 | 
            +
                    
         | 
| 41 | 
            +
                    # Determine the user's working directory from environment
         | 
| 42 | 
            +
                    # This ensures agents are deployed to the correct directory
         | 
| 43 | 
            +
                    user_working_dir = None
         | 
| 44 | 
            +
                    if 'CLAUDE_MPM_USER_PWD' in os.environ:
         | 
| 45 | 
            +
                        user_working_dir = Path(os.environ['CLAUDE_MPM_USER_PWD'])
         | 
| 46 | 
            +
                    
         | 
| 47 | 
            +
                    deployment_service = AgentDeploymentService(working_directory=user_working_dir)
         | 
| 38 48 |  | 
| 39 49 | 
             
                    if not args.agents_command:
         | 
| 40 50 | 
             
                        # No subcommand - show agent versions
         | 
| @@ -66,6 +76,15 @@ def manage_agents(args): | |
| 66 76 | 
             
                    elif args.agents_command == AgentCommands.FIX.value:
         | 
| 67 77 | 
             
                        _fix_agents(args)
         | 
| 68 78 |  | 
| 79 | 
            +
                    elif args.agents_command == 'deps-check':
         | 
| 80 | 
            +
                        _check_agent_dependencies(args)
         | 
| 81 | 
            +
                    
         | 
| 82 | 
            +
                    elif args.agents_command == 'deps-install':
         | 
| 83 | 
            +
                        _install_agent_dependencies(args)
         | 
| 84 | 
            +
                    
         | 
| 85 | 
            +
                    elif args.agents_command == 'deps-list':
         | 
| 86 | 
            +
                        _list_agent_dependencies(args)
         | 
| 87 | 
            +
                    
         | 
| 69 88 | 
             
                except ImportError:
         | 
| 70 89 | 
             
                    logger.error("Agent deployment service not available")
         | 
| 71 90 | 
             
                    print("Error: Agent deployment service not available")
         | 
| @@ -143,17 +162,50 @@ def _deploy_agents(args, deployment_service, force=False): | |
| 143 162 | 
             
                    deployment_service: Agent deployment service instance
         | 
| 144 163 | 
             
                    force: Whether to force rebuild all agents
         | 
| 145 164 | 
             
                """
         | 
| 165 | 
            +
                # Load configuration to get exclusion settings
         | 
| 166 | 
            +
                config = Config()
         | 
| 167 | 
            +
                
         | 
| 168 | 
            +
                # Check if user wants to override exclusions
         | 
| 169 | 
            +
                if hasattr(args, 'include_all') and args.include_all:
         | 
| 170 | 
            +
                    # Clear exclusion list if --include-all flag is set
         | 
| 171 | 
            +
                    config.set('agent_deployment.excluded_agents', [])
         | 
| 172 | 
            +
                    print("✅ Including all agents (exclusion configuration overridden)\n")
         | 
| 173 | 
            +
                else:
         | 
| 174 | 
            +
                    excluded_agents = config.get('agent_deployment.excluded_agents', [])
         | 
| 175 | 
            +
                    
         | 
| 176 | 
            +
                    # Display exclusion information if agents are being excluded
         | 
| 177 | 
            +
                    if excluded_agents:
         | 
| 178 | 
            +
                        logger = get_logger("cli")
         | 
| 179 | 
            +
                        logger.info(f"Configured agent exclusions: {excluded_agents}")
         | 
| 180 | 
            +
                        print(f"\n⚠️  Excluding agents from deployment: {', '.join(excluded_agents)}")
         | 
| 181 | 
            +
                        
         | 
| 182 | 
            +
                        # Warn if commonly used agents are being excluded
         | 
| 183 | 
            +
                        common_agents = {'engineer', 'qa', 'security', 'documentation'}
         | 
| 184 | 
            +
                        excluded_common = set(a.lower() for a in excluded_agents) & common_agents
         | 
| 185 | 
            +
                        if excluded_common:
         | 
| 186 | 
            +
                            print(f"⚠️  Warning: Common agents are being excluded: {', '.join(excluded_common)}")
         | 
| 187 | 
            +
                            print("   This may affect normal operations. Use 'claude-mpm agents deploy --include-all' to override.\n")
         | 
| 188 | 
            +
                
         | 
| 146 189 | 
             
                # Deploy system agents first
         | 
| 147 190 | 
             
                if force:
         | 
| 148 191 | 
             
                    print("Force deploying all system agents...")
         | 
| 149 192 | 
             
                else:
         | 
| 150 193 | 
             
                    print("Deploying system agents...")
         | 
| 151 194 |  | 
| 152 | 
            -
                 | 
| 195 | 
            +
                # Pass configuration to deployment service
         | 
| 196 | 
            +
                results = deployment_service.deploy_agents(args.target, force_rebuild=force, config=config)
         | 
| 153 197 |  | 
| 154 198 | 
             
                # Also deploy project agents if they exist
         | 
| 155 199 | 
             
                from pathlib import Path
         | 
| 156 | 
            -
                 | 
| 200 | 
            +
                import os
         | 
| 201 | 
            +
                
         | 
| 202 | 
            +
                # Use the user's working directory if available
         | 
| 203 | 
            +
                if 'CLAUDE_MPM_USER_PWD' in os.environ:
         | 
| 204 | 
            +
                    project_dir = Path(os.environ['CLAUDE_MPM_USER_PWD'])
         | 
| 205 | 
            +
                else:
         | 
| 206 | 
            +
                    project_dir = Path.cwd()
         | 
| 207 | 
            +
                
         | 
| 208 | 
            +
                project_agents_dir = project_dir / '.claude-mpm' / 'agents'
         | 
| 157 209 | 
             
                if project_agents_dir.exists():
         | 
| 158 210 | 
             
                    json_files = list(project_agents_dir.glob('*.json'))
         | 
| 159 211 | 
             
                    if json_files:
         | 
| @@ -161,12 +213,15 @@ def _deploy_agents(args, deployment_service, force=False): | |
| 161 213 | 
             
                        from claude_mpm.services.agents.deployment.agent_deployment import AgentDeploymentService
         | 
| 162 214 | 
             
                        project_service = AgentDeploymentService(
         | 
| 163 215 | 
             
                            templates_dir=project_agents_dir,
         | 
| 164 | 
            -
                            base_agent_path=project_agents_dir / 'base_agent.json' if (project_agents_dir / 'base_agent.json').exists() else None
         | 
| 216 | 
            +
                            base_agent_path=project_agents_dir / 'base_agent.json' if (project_agents_dir / 'base_agent.json').exists() else None,
         | 
| 217 | 
            +
                            working_directory=project_dir  # Pass the project directory
         | 
| 165 218 | 
             
                        )
         | 
| 219 | 
            +
                        # Pass the same configuration to project agent deployment
         | 
| 166 220 | 
             
                        project_results = project_service.deploy_agents(
         | 
| 167 221 | 
             
                            target_dir=args.target if args.target else Path.cwd() / '.claude' / 'agents',
         | 
| 168 222 | 
             
                            force_rebuild=force,
         | 
| 169 | 
            -
                            deployment_mode='project'
         | 
| 223 | 
            +
                            deployment_mode='project',
         | 
| 224 | 
            +
                            config=config
         | 
| 170 225 | 
             
                        )
         | 
| 171 226 |  | 
| 172 227 | 
             
                        # Merge project results into main results
         | 
| @@ -536,4 +591,176 @@ def _fix_agents(args): | |
| 536 591 | 
             
                    print("=" * 80 + "\n")
         | 
| 537 592 |  | 
| 538 593 | 
             
                except Exception as e:
         | 
| 539 | 
            -
                    print(f"❌ Error fixing agents: {e}")
         | 
| 594 | 
            +
                    print(f"❌ Error fixing agents: {e}")
         | 
| 595 | 
            +
             | 
| 596 | 
            +
             | 
| 597 | 
            +
            def _check_agent_dependencies(args):
         | 
| 598 | 
            +
                """
         | 
| 599 | 
            +
                Check dependencies for deployed agents.
         | 
| 600 | 
            +
                
         | 
| 601 | 
            +
                Args:
         | 
| 602 | 
            +
                    args: Parsed command line arguments
         | 
| 603 | 
            +
                """
         | 
| 604 | 
            +
                from ...utils.agent_dependency_loader import AgentDependencyLoader
         | 
| 605 | 
            +
                
         | 
| 606 | 
            +
                verbose = getattr(args, 'verbose', False)
         | 
| 607 | 
            +
                specific_agent = getattr(args, 'agent', None)
         | 
| 608 | 
            +
                
         | 
| 609 | 
            +
                loader = AgentDependencyLoader(auto_install=False)
         | 
| 610 | 
            +
                
         | 
| 611 | 
            +
                # Discover deployed agents
         | 
| 612 | 
            +
                loader.discover_deployed_agents()
         | 
| 613 | 
            +
                
         | 
| 614 | 
            +
                # Filter to specific agent if requested
         | 
| 615 | 
            +
                if specific_agent:
         | 
| 616 | 
            +
                    if specific_agent not in loader.deployed_agents:
         | 
| 617 | 
            +
                        print(f"❌ Agent '{specific_agent}' is not deployed")
         | 
| 618 | 
            +
                        print(f"   Available agents: {', '.join(loader.deployed_agents.keys())}")
         | 
| 619 | 
            +
                        return
         | 
| 620 | 
            +
                    # Keep only the specified agent
         | 
| 621 | 
            +
                    loader.deployed_agents = {specific_agent: loader.deployed_agents[specific_agent]}
         | 
| 622 | 
            +
                
         | 
| 623 | 
            +
                # Load dependencies and check
         | 
| 624 | 
            +
                loader.load_agent_dependencies()
         | 
| 625 | 
            +
                results = loader.analyze_dependencies()
         | 
| 626 | 
            +
                
         | 
| 627 | 
            +
                # Print report
         | 
| 628 | 
            +
                report = loader.format_report(results)
         | 
| 629 | 
            +
                print(report)
         | 
| 630 | 
            +
             | 
| 631 | 
            +
             | 
| 632 | 
            +
            def _install_agent_dependencies(args):
         | 
| 633 | 
            +
                """
         | 
| 634 | 
            +
                Install missing dependencies for deployed agents.
         | 
| 635 | 
            +
                
         | 
| 636 | 
            +
                Args:
         | 
| 637 | 
            +
                    args: Parsed command line arguments
         | 
| 638 | 
            +
                """
         | 
| 639 | 
            +
                from ...utils.agent_dependency_loader import AgentDependencyLoader
         | 
| 640 | 
            +
                import sys
         | 
| 641 | 
            +
                
         | 
| 642 | 
            +
                specific_agent = getattr(args, 'agent', None)
         | 
| 643 | 
            +
                dry_run = getattr(args, 'dry_run', False)
         | 
| 644 | 
            +
                
         | 
| 645 | 
            +
                loader = AgentDependencyLoader(auto_install=not dry_run)
         | 
| 646 | 
            +
                
         | 
| 647 | 
            +
                # Discover deployed agents
         | 
| 648 | 
            +
                loader.discover_deployed_agents()
         | 
| 649 | 
            +
                
         | 
| 650 | 
            +
                # Filter to specific agent if requested
         | 
| 651 | 
            +
                if specific_agent:
         | 
| 652 | 
            +
                    if specific_agent not in loader.deployed_agents:
         | 
| 653 | 
            +
                        print(f"❌ Agent '{specific_agent}' is not deployed")
         | 
| 654 | 
            +
                        print(f"   Available agents: {', '.join(loader.deployed_agents.keys())}")
         | 
| 655 | 
            +
                        return
         | 
| 656 | 
            +
                    loader.deployed_agents = {specific_agent: loader.deployed_agents[specific_agent]}
         | 
| 657 | 
            +
                
         | 
| 658 | 
            +
                # Load dependencies
         | 
| 659 | 
            +
                loader.load_agent_dependencies()
         | 
| 660 | 
            +
                results = loader.analyze_dependencies()
         | 
| 661 | 
            +
                
         | 
| 662 | 
            +
                missing_deps = results['summary']['missing_python']
         | 
| 663 | 
            +
                
         | 
| 664 | 
            +
                if not missing_deps:
         | 
| 665 | 
            +
                    print("✅ All Python dependencies are already installed")
         | 
| 666 | 
            +
                    return
         | 
| 667 | 
            +
                
         | 
| 668 | 
            +
                print(f"Found {len(missing_deps)} missing dependencies:")
         | 
| 669 | 
            +
                for dep in missing_deps:
         | 
| 670 | 
            +
                    print(f"  - {dep}")
         | 
| 671 | 
            +
                
         | 
| 672 | 
            +
                if dry_run:
         | 
| 673 | 
            +
                    print("\n--dry-run specified, not installing anything")
         | 
| 674 | 
            +
                    print(f"Would install: pip install {' '.join(missing_deps)}")
         | 
| 675 | 
            +
                else:
         | 
| 676 | 
            +
                    print(f"\nInstalling {len(missing_deps)} dependencies...")
         | 
| 677 | 
            +
                    success, error = loader.install_missing_dependencies(missing_deps)
         | 
| 678 | 
            +
                    
         | 
| 679 | 
            +
                    if success:
         | 
| 680 | 
            +
                        print("✅ Successfully installed all dependencies")
         | 
| 681 | 
            +
                        
         | 
| 682 | 
            +
                        # Re-check after installation
         | 
| 683 | 
            +
                        loader.checked_packages.clear()
         | 
| 684 | 
            +
                        results = loader.analyze_dependencies()
         | 
| 685 | 
            +
                        
         | 
| 686 | 
            +
                        if results['summary']['missing_python']:
         | 
| 687 | 
            +
                            print(f"⚠️  {len(results['summary']['missing_python'])} dependencies still missing after installation")
         | 
| 688 | 
            +
                        else:
         | 
| 689 | 
            +
                            print("✅ All dependencies verified after installation")
         | 
| 690 | 
            +
                    else:
         | 
| 691 | 
            +
                        print(f"❌ Failed to install dependencies: {error}")
         | 
| 692 | 
            +
             | 
| 693 | 
            +
             | 
| 694 | 
            +
            def _list_agent_dependencies(args):
         | 
| 695 | 
            +
                """
         | 
| 696 | 
            +
                List all dependencies from deployed agents.
         | 
| 697 | 
            +
                
         | 
| 698 | 
            +
                Args:
         | 
| 699 | 
            +
                    args: Parsed command line arguments
         | 
| 700 | 
            +
                """
         | 
| 701 | 
            +
                from ...utils.agent_dependency_loader import AgentDependencyLoader
         | 
| 702 | 
            +
                import json
         | 
| 703 | 
            +
                
         | 
| 704 | 
            +
                output_format = getattr(args, 'format', 'text')
         | 
| 705 | 
            +
                
         | 
| 706 | 
            +
                loader = AgentDependencyLoader(auto_install=False)
         | 
| 707 | 
            +
                
         | 
| 708 | 
            +
                # Discover and load
         | 
| 709 | 
            +
                loader.discover_deployed_agents()
         | 
| 710 | 
            +
                loader.load_agent_dependencies()
         | 
| 711 | 
            +
                
         | 
| 712 | 
            +
                # Collect all unique dependencies
         | 
| 713 | 
            +
                all_python_deps = set()
         | 
| 714 | 
            +
                all_system_deps = set()
         | 
| 715 | 
            +
                
         | 
| 716 | 
            +
                for agent_id, deps in loader.agent_dependencies.items():
         | 
| 717 | 
            +
                    if 'python' in deps:
         | 
| 718 | 
            +
                        all_python_deps.update(deps['python'])
         | 
| 719 | 
            +
                    if 'system' in deps:
         | 
| 720 | 
            +
                        all_system_deps.update(deps['system'])
         | 
| 721 | 
            +
                
         | 
| 722 | 
            +
                # Format output based on requested format
         | 
| 723 | 
            +
                if output_format == 'pip':
         | 
| 724 | 
            +
                    # Output pip-installable format
         | 
| 725 | 
            +
                    for dep in sorted(all_python_deps):
         | 
| 726 | 
            +
                        print(dep)
         | 
| 727 | 
            +
                        
         | 
| 728 | 
            +
                elif output_format == 'json':
         | 
| 729 | 
            +
                    # Output JSON format
         | 
| 730 | 
            +
                    output = {
         | 
| 731 | 
            +
                        'python': sorted(list(all_python_deps)),
         | 
| 732 | 
            +
                        'system': sorted(list(all_system_deps)),
         | 
| 733 | 
            +
                        'agents': {}
         | 
| 734 | 
            +
                    }
         | 
| 735 | 
            +
                    for agent_id, deps in loader.agent_dependencies.items():
         | 
| 736 | 
            +
                        output['agents'][agent_id] = deps
         | 
| 737 | 
            +
                    print(json.dumps(output, indent=2))
         | 
| 738 | 
            +
                    
         | 
| 739 | 
            +
                else:  # text format
         | 
| 740 | 
            +
                    print("=" * 60)
         | 
| 741 | 
            +
                    print("DEPENDENCIES FROM DEPLOYED AGENTS")
         | 
| 742 | 
            +
                    print("=" * 60)
         | 
| 743 | 
            +
                    print()
         | 
| 744 | 
            +
                    
         | 
| 745 | 
            +
                    if all_python_deps:
         | 
| 746 | 
            +
                        print(f"Python Dependencies ({len(all_python_deps)}):")
         | 
| 747 | 
            +
                        print("-" * 30)
         | 
| 748 | 
            +
                        for dep in sorted(all_python_deps):
         | 
| 749 | 
            +
                            print(f"  {dep}")
         | 
| 750 | 
            +
                        print()
         | 
| 751 | 
            +
                        
         | 
| 752 | 
            +
                    if all_system_deps:
         | 
| 753 | 
            +
                        print(f"System Dependencies ({len(all_system_deps)}):")
         | 
| 754 | 
            +
                        print("-" * 30)
         | 
| 755 | 
            +
                        for dep in sorted(all_system_deps):
         | 
| 756 | 
            +
                            print(f"  {dep}")
         | 
| 757 | 
            +
                        print()
         | 
| 758 | 
            +
                        
         | 
| 759 | 
            +
                    print("Per-Agent Dependencies:")
         | 
| 760 | 
            +
                    print("-" * 30)
         | 
| 761 | 
            +
                    for agent_id in sorted(loader.agent_dependencies.keys()):
         | 
| 762 | 
            +
                        deps = loader.agent_dependencies[agent_id]
         | 
| 763 | 
            +
                        python_count = len(deps.get('python', []))
         | 
| 764 | 
            +
                        system_count = len(deps.get('system', []))
         | 
| 765 | 
            +
                        if python_count or system_count:
         | 
| 766 | 
            +
                            print(f"  {agent_id}: {python_count} Python, {system_count} System")
         |