claude-mpm 5.6.3__py3-none-any.whl → 5.6.16__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 (118) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/PM_INSTRUCTIONS.md +8 -3
  3. claude_mpm/cli/commands/commander.py +173 -3
  4. claude_mpm/cli/commands/skill_source.py +51 -2
  5. claude_mpm/cli/commands/skills.py +5 -3
  6. claude_mpm/cli/parsers/commander_parser.py +41 -8
  7. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  8. claude_mpm/cli/parsers/skills_parser.py +5 -0
  9. claude_mpm/cli/startup.py +10 -1
  10. claude_mpm/cli/startup_display.py +2 -1
  11. claude_mpm/commander/__init__.py +6 -0
  12. claude_mpm/commander/adapters/__init__.py +32 -3
  13. claude_mpm/commander/adapters/auggie.py +260 -0
  14. claude_mpm/commander/adapters/base.py +98 -1
  15. claude_mpm/commander/adapters/claude_code.py +32 -1
  16. claude_mpm/commander/adapters/codex.py +237 -0
  17. claude_mpm/commander/adapters/example_usage.py +310 -0
  18. claude_mpm/commander/adapters/mpm.py +389 -0
  19. claude_mpm/commander/adapters/registry.py +204 -0
  20. claude_mpm/commander/api/app.py +32 -16
  21. claude_mpm/commander/api/errors.py +21 -0
  22. claude_mpm/commander/api/routes/messages.py +11 -11
  23. claude_mpm/commander/api/routes/projects.py +20 -20
  24. claude_mpm/commander/api/routes/sessions.py +37 -26
  25. claude_mpm/commander/api/routes/work.py +86 -50
  26. claude_mpm/commander/api/schemas.py +4 -0
  27. claude_mpm/commander/chat/cli.py +4 -0
  28. claude_mpm/commander/core/__init__.py +10 -0
  29. claude_mpm/commander/core/block_manager.py +325 -0
  30. claude_mpm/commander/core/response_manager.py +323 -0
  31. claude_mpm/commander/daemon.py +206 -10
  32. claude_mpm/commander/env_loader.py +59 -0
  33. claude_mpm/commander/memory/__init__.py +45 -0
  34. claude_mpm/commander/memory/compression.py +347 -0
  35. claude_mpm/commander/memory/embeddings.py +230 -0
  36. claude_mpm/commander/memory/entities.py +310 -0
  37. claude_mpm/commander/memory/example_usage.py +290 -0
  38. claude_mpm/commander/memory/integration.py +325 -0
  39. claude_mpm/commander/memory/search.py +381 -0
  40. claude_mpm/commander/memory/store.py +657 -0
  41. claude_mpm/commander/registry.py +10 -4
  42. claude_mpm/commander/runtime/monitor.py +32 -2
  43. claude_mpm/commander/work/executor.py +38 -20
  44. claude_mpm/commander/workflow/event_handler.py +25 -3
  45. claude_mpm/config/skill_sources.py +16 -0
  46. claude_mpm/core/claude_runner.py +143 -0
  47. claude_mpm/core/config.py +27 -19
  48. claude_mpm/core/output_style_manager.py +34 -7
  49. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  50. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-312.pyc +0 -0
  51. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-314.pyc +0 -0
  52. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  53. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-312.pyc +0 -0
  54. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-314.pyc +0 -0
  55. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  56. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  57. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-312.pyc +0 -0
  58. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-314.pyc +0 -0
  59. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  60. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-312.pyc +0 -0
  61. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-314.pyc +0 -0
  62. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  63. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-314.pyc +0 -0
  64. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  65. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-312.pyc +0 -0
  66. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-314.pyc +0 -0
  67. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  68. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-312.pyc +0 -0
  69. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-314.pyc +0 -0
  70. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  71. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-312.pyc +0 -0
  72. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-314.pyc +0 -0
  73. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +29 -30
  74. claude_mpm/hooks/claude_hooks/event_handlers.py +80 -105
  75. claude_mpm/hooks/claude_hooks/hook_handler.py +0 -0
  76. claude_mpm/hooks/claude_hooks/installer.py +41 -0
  77. claude_mpm/hooks/claude_hooks/memory_integration.py +30 -21
  78. claude_mpm/hooks/claude_hooks/response_tracking.py +39 -58
  79. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  80. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-312.pyc +0 -0
  81. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-314.pyc +0 -0
  82. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  83. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  84. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-312.pyc +0 -0
  85. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-314.pyc +0 -0
  86. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  87. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-312.pyc +0 -0
  88. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-314.pyc +0 -0
  89. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  90. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-312.pyc +0 -0
  91. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-314.pyc +0 -0
  92. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  93. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-312.pyc +0 -0
  94. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-314.pyc +0 -0
  95. claude_mpm/hooks/claude_hooks/services/connection_manager.py +23 -28
  96. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +22 -26
  97. claude_mpm/hooks/claude_hooks/services/state_manager.py +23 -36
  98. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +47 -73
  99. claude_mpm/hooks/session_resume_hook.py +22 -18
  100. claude_mpm/hooks/templates/pre_tool_use_template.py +10 -2
  101. claude_mpm/scripts/claude-hook-handler.sh +5 -5
  102. claude_mpm/scripts/start_activity_logging.py +0 -0
  103. claude_mpm/services/agents/agent_selection_service.py +2 -2
  104. claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
  105. claude_mpm/services/skills/git_skill_source_manager.py +79 -8
  106. claude_mpm/services/skills/selective_skill_deployer.py +28 -0
  107. claude_mpm/services/skills/skill_discovery_service.py +17 -1
  108. claude_mpm/services/skills_deployer.py +31 -5
  109. claude_mpm/skills/__init__.py +2 -1
  110. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  111. claude_mpm/skills/registry.py +295 -90
  112. {claude_mpm-5.6.3.dist-info → claude_mpm-5.6.16.dist-info}/METADATA +5 -3
  113. {claude_mpm-5.6.3.dist-info → claude_mpm-5.6.16.dist-info}/RECORD +116 -58
  114. {claude_mpm-5.6.3.dist-info → claude_mpm-5.6.16.dist-info}/WHEEL +0 -0
  115. {claude_mpm-5.6.3.dist-info → claude_mpm-5.6.16.dist-info}/entry_points.txt +0 -0
  116. {claude_mpm-5.6.3.dist-info → claude_mpm-5.6.16.dist-info}/licenses/LICENSE +0 -0
  117. {claude_mpm-5.6.3.dist-info → claude_mpm-5.6.16.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  118. {claude_mpm-5.6.3.dist-info → claude_mpm-5.6.16.dist-info}/top_level.txt +0 -0
@@ -50,6 +50,22 @@ logger = get_logger(__name__)
50
50
  # Deployment tracking index file
51
51
  DEPLOYED_INDEX_FILE = ".mpm-deployed-skills.json"
52
52
 
53
+ # Core PM skills that should always be deployed
54
+ # These are referenced in PM_INSTRUCTIONS.md with [SKILL: name] markers
55
+ # Without these skills, PM only sees placeholders, not actual content
56
+ PM_CORE_SKILLS = {
57
+ "mpm-delegation-patterns",
58
+ "mpm-verification-protocols",
59
+ "mpm-tool-usage-guide",
60
+ "mpm-git-file-tracking",
61
+ "mpm-pr-workflow",
62
+ "mpm-ticketing-integration",
63
+ "mpm-teaching-mode",
64
+ "mpm-bug-reporting",
65
+ "mpm-circuit-breaker-enforcement",
66
+ "mpm-session-management",
67
+ }
68
+
53
69
  # Core skills that are universally useful across all projects
54
70
  # These are deployed when skill mapping returns too many skills (>60)
55
71
  # Target: ~25-30 core skills for balanced functionality
@@ -376,6 +392,18 @@ def get_required_skills_from_agents(agents_dir: Path) -> Set[str]:
376
392
  "(converted slashes to dashes)"
377
393
  )
378
394
 
395
+ # Always include PM core skills to ensure PM_INSTRUCTIONS.md markers are resolved
396
+ # These skills are referenced in PM_INSTRUCTIONS.md and must be deployed
397
+ # for PM to see actual content instead of [SKILL: name] placeholders
398
+ before_pm_skills = len(normalized_skills)
399
+ normalized_skills = normalized_skills | PM_CORE_SKILLS
400
+ pm_skills_added = len(normalized_skills) - before_pm_skills
401
+
402
+ if pm_skills_added > 0:
403
+ logger.info(
404
+ f"Added {pm_skills_added} PM core skills to ensure PM_INSTRUCTIONS.md markers resolve"
405
+ )
406
+
379
407
  return normalized_skills
380
408
 
381
409
 
@@ -188,6 +188,15 @@ class SkillDiscoveryService:
188
188
  f"and {len(legacy_md_files)} legacy .md files in {self.skills_dir}"
189
189
  )
190
190
 
191
+ # Log first few file paths for debugging
192
+ if all_skill_files:
193
+ sample_files = [
194
+ str(f.relative_to(self.skills_dir)) for f in all_skill_files[:5]
195
+ ]
196
+ self.logger.debug(f"Sample skill files: {sample_files}")
197
+ else:
198
+ self.logger.debug(f"No SKILL.md or .md files found in {self.skills_dir}")
199
+
191
200
  # Track deployment names to detect collisions
192
201
  deployment_names = {}
193
202
 
@@ -226,7 +235,14 @@ class SkillDiscoveryService:
226
235
  except Exception as e:
227
236
  self.logger.warning(f"Failed to parse skill {skill_file}: {e}")
228
237
 
229
- self.logger.info(f"Discovered {len(skills)} skills from {self.skills_dir.name}")
238
+ # Summary logging
239
+ parsed_count = len(skills)
240
+ failed_count = len(all_skill_files) - parsed_count
241
+ self.logger.info(
242
+ f"Discovered {parsed_count} skills from {self.skills_dir.name} "
243
+ f"({len(all_skill_files)} files found, {failed_count} failed to parse)"
244
+ )
245
+
230
246
  return skills
231
247
 
232
248
  def _parse_skill_file(self, skill_file: Path) -> Optional[Dict[str, Any]]:
@@ -28,7 +28,7 @@ References:
28
28
  import json
29
29
  import platform
30
30
  import shutil
31
- import subprocess
31
+ import subprocess # nosec B404 - subprocess needed for safe git operations
32
32
  from pathlib import Path
33
33
  from typing import Any, Dict, List, Optional
34
34
 
@@ -653,7 +653,7 @@ class SkillsDeployerService(LoggerMixin):
653
653
  f"Updating existing collection '{collection_name}' at {target_dir}"
654
654
  )
655
655
  try:
656
- result = subprocess.run(
656
+ result = subprocess.run( # nosec B603 B607 - Safe: hardcoded git command
657
657
  ["git", "pull"],
658
658
  cwd=target_dir,
659
659
  capture_output=True,
@@ -684,7 +684,7 @@ class SkillsDeployerService(LoggerMixin):
684
684
  f"Installing new collection '{collection_name}' to {target_dir}"
685
685
  )
686
686
  try:
687
- result = subprocess.run(
687
+ result = subprocess.run( # nosec B603 B607 - Safe: hardcoded git command
688
688
  ["git", "clone", repo_url, str(target_dir)],
689
689
  capture_output=True,
690
690
  text=True,
@@ -773,6 +773,32 @@ class SkillsDeployerService(LoggerMixin):
773
773
  if isinstance(skills_data, dict):
774
774
  flat_skills = []
775
775
 
776
+ # Define valid top-level categories
777
+ VALID_CATEGORIES = {"universal", "toolchains"}
778
+
779
+ # Check for unknown categories and warn user
780
+ unknown_categories = set(skills_data.keys()) - VALID_CATEGORIES
781
+ if unknown_categories:
782
+ # Count skills in unknown categories
783
+ skipped_count = 0
784
+ for cat in unknown_categories:
785
+ cat_data = skills_data.get(cat, [])
786
+ if isinstance(cat_data, list):
787
+ skipped_count += len(cat_data)
788
+ elif isinstance(cat_data, dict):
789
+ # If it's a dict like toolchains, count nested skills
790
+ for skills_list in cat_data.values():
791
+ if isinstance(skills_list, list):
792
+ skipped_count += len(skills_list)
793
+
794
+ self.logger.warning(
795
+ f"Unknown categories in manifest will be skipped: "
796
+ f"{', '.join(sorted(unknown_categories))} ({skipped_count} skills)"
797
+ )
798
+ self.logger.info(
799
+ f"Valid top-level categories: {', '.join(sorted(VALID_CATEGORIES))}"
800
+ )
801
+
776
802
  # Add universal skills
777
803
  universal_skills = skills_data.get("universal", [])
778
804
  if isinstance(universal_skills, list):
@@ -1022,12 +1048,12 @@ class SkillsDeployerService(LoggerMixin):
1022
1048
  """
1023
1049
  try:
1024
1050
  if platform.system() == "Windows":
1025
- result = subprocess.run(
1051
+ result = subprocess.run( # nosec B603 B607 - Safe: hardcoded tasklist command
1026
1052
  ["tasklist"], check=False, capture_output=True, text=True, timeout=5
1027
1053
  )
1028
1054
  return "claude" in result.stdout.lower()
1029
1055
  # macOS and Linux
1030
- result = subprocess.run(
1056
+ result = subprocess.run( # nosec B603 B607 - Safe: hardcoded ps command
1031
1057
  ["ps", "aux"], check=False, capture_output=True, text=True, timeout=5
1032
1058
  )
1033
1059
  # Look for "Claude Code" or "claude-code" process
@@ -24,7 +24,7 @@ Legacy System (maintained for compatibility):
24
24
  from .agent_skills_injector import AgentSkillsInjector
25
25
 
26
26
  # Legacy System (maintained for compatibility)
27
- from .registry import Skill, SkillsRegistry, get_registry
27
+ from .registry import Skill, SkillsRegistry, get_registry, validate_agentskills_spec
28
28
  from .skill_manager import SkillManager
29
29
  from .skills_registry import SkillsRegistry as SkillsRegistryHelper
30
30
  from .skills_service import SkillsService
@@ -39,4 +39,5 @@ __all__ = [
39
39
  # New Skills Integration System
40
40
  "SkillsService",
41
41
  "get_registry",
42
+ "validate_agentskills_spec",
42
43
  ]
@@ -0,0 +1,170 @@
1
+ ---
2
+ name: mpm-session-pause
3
+ description: Pause session and save current work state for later resume
4
+ user-invocable: true
5
+ version: "1.0.0"
6
+ category: mpm-command
7
+ tags: [mpm-command, session, pm-recommended]
8
+ ---
9
+
10
+ # /mpm-pause
11
+
12
+ Pause the current session and save all work state for later resume.
13
+
14
+ ## What This Does
15
+
16
+ When invoked, this skill:
17
+ 1. Captures current work state (todos, git status, context summary)
18
+ 2. Creates session file at `.claude-mpm/sessions/session-{timestamp}.md`
19
+ 3. Updates `.claude-mpm/sessions/LATEST-SESSION.txt` pointer
20
+ 4. Optionally commits session state to git
21
+ 5. Shows user the session file path for later resume
22
+
23
+ ## Usage
24
+
25
+ ```
26
+ /mpm-pause [optional message describing current work]
27
+ ```
28
+
29
+ **Examples:**
30
+ ```
31
+ /mpm-pause
32
+ /mpm-pause Working on authentication refactor, about to test login flow
33
+ /mpm-pause Need to context switch to urgent bug fix
34
+ ```
35
+
36
+ ## Implementation
37
+
38
+ **Execute the following Python code to pause the session:**
39
+
40
+ ```python
41
+ from pathlib import Path
42
+ from claude_mpm.services.cli.session_pause_manager import SessionPauseManager
43
+
44
+ # Optional: Get message from user's command
45
+ # If user provided message after /mpm-pause, extract it
46
+ # Otherwise, message = None
47
+
48
+ # Create session pause manager
49
+ manager = SessionPauseManager(project_path=Path.cwd())
50
+
51
+ # Create pause session
52
+ session_id = manager.create_pause_session(
53
+ message=message, # Optional context message
54
+ skip_commit=False, # Will commit to git if in a repo
55
+ export_path=None, # No additional export needed
56
+ )
57
+
58
+ # Report success to user
59
+ print(f"✅ Session paused successfully!")
60
+ print(f"")
61
+ print(f"Session ID: {session_id}")
62
+ print(f"Session files:")
63
+ print(f" - .claude-mpm/sessions/{session_id}.md (human-readable)")
64
+ print(f" - .claude-mpm/sessions/{session_id}.json (machine-readable)")
65
+ print(f" - .claude-mpm/sessions/{session_id}.yaml (config format)")
66
+ print(f"")
67
+ print(f"Quick resume:")
68
+ print(f" /mpm-resume")
69
+ print(f"")
70
+ print(f"View session context:")
71
+ print(f" cat .claude-mpm/sessions/LATEST-SESSION.txt")
72
+ print(f" cat .claude-mpm/sessions/{session_id}.md")
73
+ ```
74
+
75
+ ## What Gets Saved
76
+
77
+ **Session State:**
78
+ - Session ID and timestamp
79
+ - Current working directory
80
+ - Git branch, recent commits, and file status
81
+ - Primary task and current phase
82
+ - Context message (if provided)
83
+
84
+ **Resume Instructions:**
85
+ - Quick-start commands
86
+ - Validation commands
87
+ - Files to review
88
+
89
+ **File Formats:**
90
+ - `.md` - Human-readable markdown (for reading)
91
+ - `.json` - Machine-readable (for tooling)
92
+ - `.yaml` - Human-readable config (for editing)
93
+
94
+ ## Session File Location
95
+
96
+ All session files are stored in:
97
+ ```
98
+ .claude-mpm/sessions/
99
+ ├── LATEST-SESSION.txt # Pointer to most recent session
100
+ ├── session-YYYYMMDD-HHMMSS.md
101
+ ├── session-YYYYMMDD-HHMMSS.json
102
+ └── session-YYYYMMDD-HHMMSS.yaml
103
+ ```
104
+
105
+ ## Token Budget
106
+
107
+ **Token usage:** ~5-10k tokens to execute (2-5% of context budget)
108
+
109
+ **Benefit:** Saves all remaining context for future resume, allowing you to:
110
+ - Context switch to urgent tasks
111
+ - Take a break and resume later
112
+ - Archive current work state before major changes
113
+
114
+ ## Resume Later
115
+
116
+ To resume this session:
117
+ ```
118
+ /mpm-resume
119
+ ```
120
+
121
+ Or manually:
122
+ ```bash
123
+ cat .claude-mpm/sessions/LATEST-SESSION.txt
124
+ cat .claude-mpm/sessions/session-YYYYMMDD-HHMMSS.md
125
+ ```
126
+
127
+ ## Git Integration
128
+
129
+ If in a git repository, the session will be automatically committed with message:
130
+ ```
131
+ session: pause at YYYY-MM-DD HH:MM:SS
132
+
133
+ Session ID: session-YYYYMMDD-HHMMSS
134
+ Context: [your optional message]
135
+ ```
136
+
137
+ ## Use Cases
138
+
139
+ **Context switching:**
140
+ ```
141
+ /mpm-pause Switching to urgent production bug
142
+ ```
143
+
144
+ **End of work session:**
145
+ ```
146
+ /mpm-pause Completed API refactor, ready for testing tomorrow
147
+ ```
148
+
149
+ **Before major changes:**
150
+ ```
151
+ /mpm-pause Saving state before attempting risky refactor
152
+ ```
153
+
154
+ **When approaching context limit:**
155
+ ```
156
+ /mpm-pause Hit 150k tokens, starting fresh session
157
+ ```
158
+
159
+ ## Related Commands
160
+
161
+ - `/mpm-resume` - Resume from most recent paused session
162
+ - `/mpm-init resume` - Alternative resume command
163
+ - See `docs/features/session-auto-resume.md` for auto-pause behavior
164
+
165
+ ## Notes
166
+
167
+ - Session files are project-local (not synced across machines)
168
+ - Git commit is optional (automatically skipped if not a repo)
169
+ - LATEST-SESSION.txt always points to most recent session
170
+ - Session format compatible with auto-pause feature (70% context trigger)