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.
Files changed (68) hide show
  1. claude_mpm/.claude-mpm/logs/hooks_20250728.log +10 -0
  2. claude_mpm/VERSION +1 -1
  3. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +96 -23
  4. claude_mpm/agents/BASE_PM.md +273 -0
  5. claude_mpm/agents/INSTRUCTIONS.md +114 -102
  6. claude_mpm/agents/agent-template.yaml +83 -0
  7. claude_mpm/agents/agent_loader.py +36 -1
  8. claude_mpm/agents/async_agent_loader.py +421 -0
  9. claude_mpm/agents/templates/code_analyzer.json +81 -0
  10. claude_mpm/agents/templates/data_engineer.json +18 -3
  11. claude_mpm/agents/templates/documentation.json +18 -3
  12. claude_mpm/agents/templates/engineer.json +19 -4
  13. claude_mpm/agents/templates/ops.json +18 -3
  14. claude_mpm/agents/templates/qa.json +20 -4
  15. claude_mpm/agents/templates/research.json +20 -4
  16. claude_mpm/agents/templates/security.json +18 -3
  17. claude_mpm/agents/templates/version_control.json +16 -3
  18. claude_mpm/cli/README.md +108 -0
  19. claude_mpm/cli/__init__.py +5 -1
  20. claude_mpm/cli/commands/__init__.py +5 -1
  21. claude_mpm/cli/commands/agents.py +233 -6
  22. claude_mpm/cli/commands/aggregate.py +462 -0
  23. claude_mpm/cli/commands/config.py +277 -0
  24. claude_mpm/cli/commands/run.py +228 -47
  25. claude_mpm/cli/parser.py +176 -1
  26. claude_mpm/cli/utils.py +9 -1
  27. claude_mpm/cli_module/refactoring_guide.md +253 -0
  28. claude_mpm/config/async_logging_config.yaml +145 -0
  29. claude_mpm/constants.py +19 -0
  30. claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +34 -0
  31. claude_mpm/core/claude_runner.py +413 -76
  32. claude_mpm/core/config.py +161 -4
  33. claude_mpm/core/config_paths.py +0 -1
  34. claude_mpm/core/factories.py +9 -3
  35. claude_mpm/core/framework_loader.py +81 -0
  36. claude_mpm/dashboard/.claude-mpm/memories/README.md +36 -0
  37. claude_mpm/dashboard/README.md +121 -0
  38. claude_mpm/dashboard/static/js/dashboard.js.backup +1973 -0
  39. claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +36 -0
  40. claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +39 -0
  41. claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +38 -0
  42. claude_mpm/hooks/README.md +96 -0
  43. claude_mpm/hooks/claude_hooks/hook_handler.py +391 -9
  44. claude_mpm/init.py +123 -18
  45. claude_mpm/models/agent_session.py +511 -0
  46. claude_mpm/schemas/agent_schema.json +435 -0
  47. claude_mpm/scripts/__init__.py +15 -0
  48. claude_mpm/scripts/start_activity_logging.py +86 -0
  49. claude_mpm/services/agents/deployment/agent_deployment.py +326 -24
  50. claude_mpm/services/agents/deployment/async_agent_deployment.py +461 -0
  51. claude_mpm/services/agents/management/agent_management_service.py +2 -1
  52. claude_mpm/services/event_aggregator.py +547 -0
  53. claude_mpm/services/framework_claude_md_generator/README.md +92 -0
  54. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +3 -3
  55. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +2 -2
  56. claude_mpm/services/version_control/VERSION +1 -0
  57. claude_mpm/utils/agent_dependency_loader.py +655 -0
  58. claude_mpm/utils/console.py +11 -0
  59. claude_mpm/utils/dependency_cache.py +376 -0
  60. claude_mpm/utils/dependency_strategies.py +343 -0
  61. claude_mpm/utils/environment_context.py +310 -0
  62. {claude_mpm-3.5.4.dist-info → claude_mpm-3.6.0.dist-info}/METADATA +87 -1
  63. {claude_mpm-3.5.4.dist-info → claude_mpm-3.6.0.dist-info}/RECORD +67 -37
  64. claude_mpm/agents/templates/pm.json +0 -122
  65. {claude_mpm-3.5.4.dist-info → claude_mpm-3.6.0.dist-info}/WHEEL +0 -0
  66. {claude_mpm-3.5.4.dist-info → claude_mpm-3.6.0.dist-info}/entry_points.txt +0 -0
  67. {claude_mpm-3.5.4.dist-info → claude_mpm-3.6.0.dist-info}/licenses/LICENSE +0 -0
  68. {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
- deployment_service = AgentDeploymentService()
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
- results = deployment_service.deploy_agents(args.target, force_rebuild=force)
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
- project_agents_dir = Path.cwd() / '.claude-mpm' / 'agents'
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")