claude-mpm 5.0.2__py3-none-any.whl → 5.1.9__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.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +1176 -909
- claude_mpm/agents/base_agent_loader.py +10 -35
- claude_mpm/agents/frontmatter_validator.py +68 -0
- claude_mpm/agents/templates/circuit-breakers.md +293 -44
- claude_mpm/cli/__init__.py +0 -1
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/agent_state_manager.py +64 -11
- claude_mpm/cli/commands/agents.py +446 -25
- claude_mpm/cli/commands/auto_configure.py +535 -233
- claude_mpm/cli/commands/configure.py +545 -89
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/run.py +1 -39
- claude_mpm/cli/commands/skills.py +322 -19
- claude_mpm/cli/interactive/agent_wizard.py +302 -195
- claude_mpm/cli/parsers/agents_parser.py +137 -0
- claude_mpm/cli/parsers/auto_configure_parser.py +13 -0
- claude_mpm/cli/parsers/base_parser.py +4 -0
- claude_mpm/cli/parsers/skills_parser.py +7 -0
- claude_mpm/cli/startup.py +73 -32
- claude_mpm/commands/mpm-agents-auto-configure.md +2 -2
- claude_mpm/commands/mpm-agents-list.md +2 -2
- claude_mpm/commands/mpm-config-view.md +2 -2
- claude_mpm/commands/mpm-help.md +3 -0
- claude_mpm/commands/mpm-postmortem.md +123 -0
- claude_mpm/commands/mpm-session-resume.md +2 -2
- claude_mpm/commands/mpm-ticket-organize.md +2 -2
- claude_mpm/commands/mpm-ticket-view.md +2 -2
- claude_mpm/config/agent_presets.py +312 -82
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/constants.py +1 -0
- claude_mpm/core/claude_runner.py +2 -25
- claude_mpm/core/framework/loaders/file_loader.py +54 -101
- claude_mpm/core/interactive_session.py +19 -5
- claude_mpm/core/oneshot_session.py +16 -4
- claude_mpm/core/output_style_manager.py +173 -43
- claude_mpm/core/protocols/__init__.py +23 -0
- claude_mpm/core/protocols/runner_protocol.py +103 -0
- claude_mpm/core/protocols/session_protocol.py +131 -0
- claude_mpm/core/shared/singleton_manager.py +11 -4
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/unified_agent_registry.py +129 -1
- claude_mpm/core/unified_config.py +22 -0
- claude_mpm/hooks/claude_hooks/memory_integration.py +12 -1
- claude_mpm/models/agent_definition.py +7 -0
- claude_mpm/services/agents/cache_git_manager.py +621 -0
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +110 -3
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +195 -1
- claude_mpm/services/agents/sources/git_source_sync_service.py +37 -5
- claude_mpm/services/analysis/__init__.py +25 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/command_deployment_service.py +108 -5
- claude_mpm/services/core/base.py +7 -2
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
- claude_mpm/services/git/git_operations_service.py +8 -8
- claude_mpm/services/mcp_config_manager.py +75 -145
- claude_mpm/services/mcp_gateway/core/process_pool.py +22 -16
- claude_mpm/services/mcp_service_verifier.py +6 -3
- claude_mpm/services/monitor/daemon.py +28 -8
- claude_mpm/services/monitor/daemon_manager.py +96 -19
- claude_mpm/services/project/project_organizer.py +4 -0
- claude_mpm/services/runner_configuration_service.py +16 -3
- claude_mpm/services/session_management_service.py +16 -4
- claude_mpm/utils/agent_filters.py +288 -0
- claude_mpm/utils/gitignore.py +3 -0
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/progress.py +5 -1
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.1.9.dist-info}/METADATA +69 -8
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.1.9.dist-info}/RECORD +76 -62
- /claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +0 -0
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.1.9.dist-info}/WHEEL +0 -0
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.1.9.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.1.9.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.1.9.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""System context utilities for Claude runner.
|
|
2
|
+
|
|
3
|
+
This module provides shared context creation functions that can be used
|
|
4
|
+
across different modules without circular dependencies.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def create_simple_context() -> str:
|
|
9
|
+
"""Create basic context for Claude.
|
|
10
|
+
|
|
11
|
+
This function is extracted to avoid circular imports between
|
|
12
|
+
claude_runner.py and interactive_session.py.
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
Basic system context string for Claude
|
|
16
|
+
"""
|
|
17
|
+
return """You are Claude Code running in Claude MPM (Multi-Agent Project Manager).
|
|
18
|
+
|
|
19
|
+
You have access to native subagents via the Task tool with subagent_type parameter:
|
|
20
|
+
- engineer: For coding, implementation, and technical tasks
|
|
21
|
+
- qa: For testing, validation, and quality assurance
|
|
22
|
+
- documentation: For docs, guides, and explanations
|
|
23
|
+
- research: For investigation and analysis
|
|
24
|
+
- security: For security-related tasks
|
|
25
|
+
- ops: For deployment and infrastructure
|
|
26
|
+
- version-control: For git and version management
|
|
27
|
+
- data-engineer: For data processing and APIs
|
|
28
|
+
|
|
29
|
+
Use these agents by calling: Task(description="task description", subagent_type="agent_name")
|
|
30
|
+
|
|
31
|
+
IMPORTANT: The Task tool accepts both naming formats:
|
|
32
|
+
- Capitalized format: "Research", "Engineer", "QA", "Version Control", "Data Engineer"
|
|
33
|
+
- Lowercase format: "research", "engineer", "qa", "version-control", "data-engineer"
|
|
34
|
+
|
|
35
|
+
Both formats work correctly. When you see capitalized names (matching TodoWrite prefixes),
|
|
36
|
+
automatically normalize them to lowercase-hyphenated format for the Task tool.
|
|
37
|
+
|
|
38
|
+
Work efficiently and delegate appropriately to subagents when needed."""
|
|
@@ -84,6 +84,12 @@ class AgentMetadata:
|
|
|
84
84
|
version: str = "1.0.0"
|
|
85
85
|
author: str = ""
|
|
86
86
|
tags: List[str] = None
|
|
87
|
+
# NEW: Collection-based identification fields
|
|
88
|
+
collection_id: Optional[str] = None # Format: owner/repo-name
|
|
89
|
+
source_path: Optional[str] = None # Relative path in repo
|
|
90
|
+
canonical_id: Optional[str] = (
|
|
91
|
+
None # Format: collection_id:agent_id or legacy:filename
|
|
92
|
+
)
|
|
87
93
|
|
|
88
94
|
def __post_init__(self):
|
|
89
95
|
"""Initialize default values for mutable fields."""
|
|
@@ -690,6 +696,111 @@ class UnifiedAgentRegistry:
|
|
|
690
696
|
"""Get all memory-aware agents."""
|
|
691
697
|
return self.list_agents(agent_type=AgentType.MEMORY_AWARE)
|
|
692
698
|
|
|
699
|
+
def get_agents_by_collection(self, collection_id: str) -> List[AgentMetadata]:
|
|
700
|
+
"""Get all agents from a specific collection.
|
|
701
|
+
|
|
702
|
+
NEW: Enables collection-based agent selection.
|
|
703
|
+
|
|
704
|
+
Args:
|
|
705
|
+
collection_id: Collection identifier (e.g., "bobmatnyc/claude-mpm-agents")
|
|
706
|
+
|
|
707
|
+
Returns:
|
|
708
|
+
List of agents from the specified collection
|
|
709
|
+
|
|
710
|
+
Example:
|
|
711
|
+
>>> registry = get_agent_registry()
|
|
712
|
+
>>> agents = registry.get_agents_by_collection("bobmatnyc/claude-mpm-agents")
|
|
713
|
+
>>> len(agents)
|
|
714
|
+
45
|
|
715
|
+
"""
|
|
716
|
+
if not self.registry:
|
|
717
|
+
self.discover_agents()
|
|
718
|
+
|
|
719
|
+
collection_agents = [
|
|
720
|
+
agent
|
|
721
|
+
for agent in self.registry.values()
|
|
722
|
+
if agent.collection_id == collection_id
|
|
723
|
+
]
|
|
724
|
+
|
|
725
|
+
return sorted(collection_agents, key=lambda a: a.name)
|
|
726
|
+
|
|
727
|
+
def list_collections(self) -> List[Dict[str, Any]]:
|
|
728
|
+
"""List all available collections with agent counts.
|
|
729
|
+
|
|
730
|
+
NEW: Provides overview of available collections.
|
|
731
|
+
|
|
732
|
+
Returns:
|
|
733
|
+
List of collection info dictionaries with:
|
|
734
|
+
- collection_id: Collection identifier
|
|
735
|
+
- agent_count: Number of agents in collection
|
|
736
|
+
- agents: List of agent names in collection
|
|
737
|
+
|
|
738
|
+
Example:
|
|
739
|
+
>>> registry = get_agent_registry()
|
|
740
|
+
>>> collections = registry.list_collections()
|
|
741
|
+
>>> collections
|
|
742
|
+
[
|
|
743
|
+
{
|
|
744
|
+
"collection_id": "bobmatnyc/claude-mpm-agents",
|
|
745
|
+
"agent_count": 45,
|
|
746
|
+
"agents": ["pm", "engineer", "qa", ...]
|
|
747
|
+
}
|
|
748
|
+
]
|
|
749
|
+
"""
|
|
750
|
+
if not self.registry:
|
|
751
|
+
self.discover_agents()
|
|
752
|
+
|
|
753
|
+
# Group agents by collection_id
|
|
754
|
+
collections_map: Dict[str, List[str]] = {}
|
|
755
|
+
|
|
756
|
+
for agent in self.registry.values():
|
|
757
|
+
if not agent.collection_id:
|
|
758
|
+
# Skip agents without collection (legacy or local)
|
|
759
|
+
continue
|
|
760
|
+
|
|
761
|
+
if agent.collection_id not in collections_map:
|
|
762
|
+
collections_map[agent.collection_id] = []
|
|
763
|
+
|
|
764
|
+
collections_map[agent.collection_id].append(agent.name)
|
|
765
|
+
|
|
766
|
+
# Convert to list format
|
|
767
|
+
collections = [
|
|
768
|
+
{
|
|
769
|
+
"collection_id": coll_id,
|
|
770
|
+
"agent_count": len(agent_names),
|
|
771
|
+
"agents": sorted(agent_names),
|
|
772
|
+
}
|
|
773
|
+
for coll_id, agent_names in collections_map.items()
|
|
774
|
+
]
|
|
775
|
+
|
|
776
|
+
return sorted(collections, key=lambda c: c["collection_id"])
|
|
777
|
+
|
|
778
|
+
def get_agent_by_canonical_id(self, canonical_id: str) -> Optional[AgentMetadata]:
|
|
779
|
+
"""Get agent by canonical ID (primary matching key).
|
|
780
|
+
|
|
781
|
+
NEW: Primary matching method using canonical_id.
|
|
782
|
+
|
|
783
|
+
Args:
|
|
784
|
+
canonical_id: Canonical identifier (e.g., "bobmatnyc/claude-mpm-agents:pm")
|
|
785
|
+
|
|
786
|
+
Returns:
|
|
787
|
+
AgentMetadata if found, None otherwise
|
|
788
|
+
|
|
789
|
+
Example:
|
|
790
|
+
>>> registry = get_agent_registry()
|
|
791
|
+
>>> agent = registry.get_agent_by_canonical_id("bobmatnyc/claude-mpm-agents:pm")
|
|
792
|
+
>>> agent.name
|
|
793
|
+
'Project Manager Agent'
|
|
794
|
+
"""
|
|
795
|
+
if not self.registry:
|
|
796
|
+
self.discover_agents()
|
|
797
|
+
|
|
798
|
+
for agent in self.registry.values():
|
|
799
|
+
if agent.canonical_id == canonical_id:
|
|
800
|
+
return agent
|
|
801
|
+
|
|
802
|
+
return None
|
|
803
|
+
|
|
693
804
|
def add_discovery_path(self, path: Union[str, Path]) -> None:
|
|
694
805
|
"""Add a new path for agent discovery."""
|
|
695
806
|
path = Path(path)
|
|
@@ -809,6 +920,21 @@ def get_registry_stats() -> Dict[str, Any]:
|
|
|
809
920
|
return get_agent_registry().get_registry_stats()
|
|
810
921
|
|
|
811
922
|
|
|
923
|
+
def get_agents_by_collection(collection_id: str) -> List[AgentMetadata]:
|
|
924
|
+
"""Get all agents from a specific collection."""
|
|
925
|
+
return get_agent_registry().get_agents_by_collection(collection_id)
|
|
926
|
+
|
|
927
|
+
|
|
928
|
+
def list_collections() -> List[Dict[str, Any]]:
|
|
929
|
+
"""List all available collections."""
|
|
930
|
+
return get_agent_registry().list_collections()
|
|
931
|
+
|
|
932
|
+
|
|
933
|
+
def get_agent_by_canonical_id(canonical_id: str) -> Optional[AgentMetadata]:
|
|
934
|
+
"""Get agent by canonical ID."""
|
|
935
|
+
return get_agent_registry().get_agent_by_canonical_id(canonical_id)
|
|
936
|
+
|
|
937
|
+
|
|
812
938
|
# Legacy function names for backward compatibility
|
|
813
939
|
def listAgents() -> List[str]:
|
|
814
940
|
"""Legacy function: Get list of agent names."""
|
|
@@ -838,14 +964,16 @@ __all__ = [
|
|
|
838
964
|
"discover_agents",
|
|
839
965
|
"discover_agents_sync",
|
|
840
966
|
"get_agent",
|
|
967
|
+
"get_agent_by_canonical_id",
|
|
841
968
|
"get_agent_names",
|
|
842
969
|
"get_agent_registry",
|
|
970
|
+
"get_agents_by_collection",
|
|
843
971
|
"get_core_agents",
|
|
844
972
|
"get_project_agents",
|
|
845
973
|
"get_registry_stats",
|
|
846
974
|
"get_specialized_agents",
|
|
847
|
-
# Legacy compatibility
|
|
848
975
|
"listAgents",
|
|
849
976
|
"list_agents",
|
|
850
977
|
"list_agents_all",
|
|
978
|
+
"list_collections",
|
|
851
979
|
]
|
|
@@ -218,6 +218,27 @@ class DevelopmentConfig(BaseModel):
|
|
|
218
218
|
)
|
|
219
219
|
|
|
220
220
|
|
|
221
|
+
class DocumentationConfig(BaseModel):
|
|
222
|
+
"""Documentation routing and management configuration."""
|
|
223
|
+
|
|
224
|
+
docs_path: str = Field(
|
|
225
|
+
default="docs/research/",
|
|
226
|
+
description="Default path for session documentation (relative to project root)",
|
|
227
|
+
)
|
|
228
|
+
attach_to_tickets: bool = Field(
|
|
229
|
+
default=True,
|
|
230
|
+
description="Attach work products to tickets when ticket context exists",
|
|
231
|
+
)
|
|
232
|
+
backup_locally: bool = Field(
|
|
233
|
+
default=True,
|
|
234
|
+
description="Always create local backup copies of documentation",
|
|
235
|
+
)
|
|
236
|
+
enable_ticket_detection: bool = Field(
|
|
237
|
+
default=True,
|
|
238
|
+
description="Enable automatic ticket context detection from user messages",
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
|
|
221
242
|
class UnifiedConfig(BaseSettings):
|
|
222
243
|
"""
|
|
223
244
|
Unified configuration model for Claude MPM.
|
|
@@ -242,6 +263,7 @@ class UnifiedConfig(BaseSettings):
|
|
|
242
263
|
performance: PerformanceConfig = Field(default_factory=PerformanceConfig)
|
|
243
264
|
sessions: SessionConfig = Field(default_factory=SessionConfig)
|
|
244
265
|
development: DevelopmentConfig = Field(default_factory=DevelopmentConfig)
|
|
266
|
+
documentation: DocumentationConfig = Field(default_factory=DocumentationConfig)
|
|
245
267
|
|
|
246
268
|
# Path configuration
|
|
247
269
|
base_path: Optional[Path] = Field(
|
|
@@ -5,8 +5,19 @@ This module provides utilities for integrating with the memory system,
|
|
|
5
5
|
including pre and post delegation hooks.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
import
|
|
8
|
+
import logging
|
|
9
9
|
import sys
|
|
10
|
+
|
|
11
|
+
# Reconfigure logging to INFO level BEFORE kuzu-memory imports
|
|
12
|
+
# This overrides kuzu-memory's WARNING-level basicConfig (fixes 1M-445)
|
|
13
|
+
logging.basicConfig(
|
|
14
|
+
level=logging.INFO,
|
|
15
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
16
|
+
force=True, # Python 3.8+ - reconfigures root logger
|
|
17
|
+
stream=sys.stderr,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
import os
|
|
10
21
|
from datetime import datetime, timezone
|
|
11
22
|
from typing import Optional
|
|
12
23
|
|
|
@@ -103,6 +103,10 @@ class AgentMetadata:
|
|
|
103
103
|
author: Optional[str] = None
|
|
104
104
|
tags: List[str] = field(default_factory=list)
|
|
105
105
|
specializations: List[str] = field(default_factory=list)
|
|
106
|
+
# NEW: Collection metadata for enhanced agent matching
|
|
107
|
+
collection_id: Optional[str] = None # Format: owner/repo-name
|
|
108
|
+
source_path: Optional[str] = None # Relative path in repository
|
|
109
|
+
canonical_id: Optional[str] = None # Format: collection_id:agent_id
|
|
106
110
|
|
|
107
111
|
def increment_serial_version(self) -> None:
|
|
108
112
|
"""Increment the patch version number.
|
|
@@ -181,6 +185,9 @@ class AgentDefinition:
|
|
|
181
185
|
"author": self.metadata.author,
|
|
182
186
|
"tags": self.metadata.tags,
|
|
183
187
|
"specializations": self.metadata.specializations,
|
|
188
|
+
"collection_id": self.metadata.collection_id,
|
|
189
|
+
"source_path": self.metadata.source_path,
|
|
190
|
+
"canonical_id": self.metadata.canonical_id,
|
|
184
191
|
},
|
|
185
192
|
"primary_role": self.primary_role,
|
|
186
193
|
"when_to_use": self.when_to_use,
|