claude-mpm 4.0.29__py3-none-any.whl → 4.0.30__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 (64) hide show
  1. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +48 -3
  2. claude_mpm/agents/BASE_PM.md +20 -15
  3. claude_mpm/agents/INSTRUCTIONS.md +12 -2
  4. claude_mpm/agents/templates/documentation.json +16 -3
  5. claude_mpm/agents/templates/engineer.json +19 -5
  6. claude_mpm/agents/templates/ops.json +19 -5
  7. claude_mpm/agents/templates/qa.json +16 -3
  8. claude_mpm/agents/templates/refactoring_engineer.json +25 -7
  9. claude_mpm/agents/templates/research.json +19 -5
  10. claude_mpm/cli/__init__.py +2 -0
  11. claude_mpm/cli/commands/__init__.py +2 -0
  12. claude_mpm/cli/commands/agent_manager.py +10 -6
  13. claude_mpm/cli/commands/agents.py +2 -1
  14. claude_mpm/cli/commands/cleanup.py +1 -1
  15. claude_mpm/cli/commands/doctor.py +209 -0
  16. claude_mpm/cli/commands/mcp.py +3 -3
  17. claude_mpm/cli/commands/mcp_install_commands.py +12 -30
  18. claude_mpm/cli/commands/mcp_server_commands.py +9 -9
  19. claude_mpm/cli/commands/run.py +31 -2
  20. claude_mpm/cli/commands/run_config_checker.py +1 -1
  21. claude_mpm/cli/parsers/agent_manager_parser.py +3 -3
  22. claude_mpm/cli/parsers/base_parser.py +5 -1
  23. claude_mpm/cli/parsers/mcp_parser.py +1 -1
  24. claude_mpm/cli/parsers/run_parser.py +1 -1
  25. claude_mpm/cli/startup_logging.py +463 -0
  26. claude_mpm/constants.py +1 -0
  27. claude_mpm/core/claude_runner.py +78 -0
  28. claude_mpm/core/framework_loader.py +45 -11
  29. claude_mpm/core/interactive_session.py +82 -3
  30. claude_mpm/core/output_style_manager.py +6 -6
  31. claude_mpm/core/unified_paths.py +128 -0
  32. claude_mpm/scripts/mcp_server.py +2 -2
  33. claude_mpm/services/agents/deployment/agent_validator.py +1 -0
  34. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +69 -1
  35. claude_mpm/services/diagnostics/__init__.py +18 -0
  36. claude_mpm/services/diagnostics/checks/__init__.py +30 -0
  37. claude_mpm/services/diagnostics/checks/agent_check.py +319 -0
  38. claude_mpm/services/diagnostics/checks/base_check.py +64 -0
  39. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +283 -0
  40. claude_mpm/services/diagnostics/checks/common_issues_check.py +354 -0
  41. claude_mpm/services/diagnostics/checks/configuration_check.py +300 -0
  42. claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
  43. claude_mpm/services/diagnostics/checks/installation_check.py +255 -0
  44. claude_mpm/services/diagnostics/checks/mcp_check.py +315 -0
  45. claude_mpm/services/diagnostics/checks/monitor_check.py +282 -0
  46. claude_mpm/services/diagnostics/checks/startup_log_check.py +322 -0
  47. claude_mpm/services/diagnostics/diagnostic_runner.py +247 -0
  48. claude_mpm/services/diagnostics/doctor_reporter.py +283 -0
  49. claude_mpm/services/diagnostics/models.py +120 -0
  50. claude_mpm/services/mcp_gateway/core/interfaces.py +1 -1
  51. claude_mpm/services/mcp_gateway/main.py +1 -1
  52. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +3 -3
  53. claude_mpm/services/mcp_gateway/server/stdio_handler.py +1 -1
  54. claude_mpm/services/mcp_gateway/server/stdio_server.py +3 -3
  55. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +2 -2
  56. claude_mpm/services/socketio/handlers/registry.py +39 -7
  57. claude_mpm/services/socketio/server/core.py +72 -22
  58. claude_mpm/validation/frontmatter_validator.py +1 -1
  59. {claude_mpm-4.0.29.dist-info → claude_mpm-4.0.30.dist-info}/METADATA +4 -1
  60. {claude_mpm-4.0.29.dist-info → claude_mpm-4.0.30.dist-info}/RECORD +64 -47
  61. {claude_mpm-4.0.29.dist-info → claude_mpm-4.0.30.dist-info}/WHEEL +0 -0
  62. {claude_mpm-4.0.29.dist-info → claude_mpm-4.0.30.dist-info}/entry_points.txt +0 -0
  63. {claude_mpm-4.0.29.dist-info → claude_mpm-4.0.30.dist-info}/licenses/LICENSE +0 -0
  64. {claude_mpm-4.0.29.dist-info → claude_mpm-4.0.30.dist-info}/top_level.txt +0 -0
@@ -1,13 +1,26 @@
1
1
  {
2
2
  "schema_version": "1.2.0",
3
3
  "agent_id": "research-agent",
4
- "agent_version": "4.3.0",
4
+ "agent_version": "4.3.1",
5
+ "template_version": "1.0.1",
6
+ "template_changelog": [
7
+ {
8
+ "version": "1.0.1",
9
+ "date": "2025-08-22",
10
+ "description": "Optimized: Removed redundant instructions, now inherits from BASE_AGENT_TEMPLATE (74% reduction)"
11
+ },
12
+ {
13
+ "version": "1.0.0",
14
+ "date": "2025-08-19",
15
+ "description": "Initial template version"
16
+ }
17
+ ],
5
18
  "agent_type": "research",
6
19
  "metadata": {
7
20
  "name": "Research Agent",
8
21
  "description": "Memory-efficient codebase analysis with strategic sampling, immediate summarization, MCP document summarizer integration, content thresholds, and 85% confidence through intelligent verification without full file retention",
9
22
  "created_at": "2025-07-27T03:45:51.485006Z",
10
- "updated_at": "2025-08-19T12:00:00.000000Z",
23
+ "updated_at": "2025-08-22T12:00:00.000000Z",
11
24
  "tags": [
12
25
  "research",
13
26
  "memory-efficient",
@@ -80,7 +93,7 @@
80
93
  "Check MCP summarizer tool availability before use for graceful fallback"
81
94
  ]
82
95
  },
83
- "instructions": "<!-- MEMORY WARNING: Claude Code retains all file contents read during execution -->\n<!-- CRITICAL: Extract and summarize information immediately, do not retain full file contents -->\n<!-- PATTERN: Read → Extract → Summarize → Discard → Continue -->\n<!-- MCP TOOL: Use mcp__claude-mpm-gateway__document_summarizer when available for efficient document analysis -->\n<!-- THRESHOLDS: Single file 20KB/200 lines, Critical >100KB always summarized, Cumulative 50KB/3 files triggers batch -->\n\n# Research Agent - MEMORY-EFFICIENT VERIFICATION ANALYSIS\n\nConduct comprehensive codebase analysis through intelligent sampling and immediate summarization. Extract key patterns without retaining full file contents. Maintain 85% confidence through strategic verification. Leverage MCP document summarizer tool with content thresholds for optimal memory management.\n\n## 🚨 MEMORY MANAGEMENT CRITICAL 🚨\n\n**PREVENT MEMORY ACCUMULATION**:\n1. **Extract and summarize immediately** - Never retain full file contents\n2. **Process sequentially** - One file at a time, never parallel\n3. **Use grep with line numbers** - Read sections with precise location tracking\n4. **Leverage MCP summarizer** - Use document summarizer tool when available\n5. **Sample intelligently** - 3-5 representative files are sufficient\n6. **Apply content thresholds** - Trigger summarization at defined limits\n7. **Discard after extraction** - Release content from memory\n8. **Track cumulative content** - Monitor total content size across files\n\n## 📊 CONTENT THRESHOLD SYSTEM\n\n### Threshold Constants\n```python\n# Single File Thresholds\nSUMMARIZE_THRESHOLD_LINES = 200 # Trigger summarization at 200 lines\nSUMMARIZE_THRESHOLD_SIZE = 20_000 # Trigger summarization at 20KB\nCRITICAL_FILE_SIZE = 100_000 # Files >100KB always summarized\n\n# Cumulative Thresholds\nCUMULATIVE_CONTENT_LIMIT = 50_000 # 50KB total triggers batch summarization\nBATCH_SUMMARIZE_COUNT = 3 # 3 files triggers batch summarization\n\n# File Type Specific Thresholds (lines)\nFILE_TYPE_THRESHOLDS = {\n '.py': 500, '.js': 500, '.ts': 500, # Code files\n '.json': 100, '.yaml': 100, '.toml': 100, # Config files\n '.md': 200, '.rst': 200, '.txt': 200, # Documentation\n '.csv': 50, '.sql': 50, '.xml': 50 # Data files\n}\n```\n\n### Progressive Summarization Strategy\n\n1. **Single File Processing**\n ```python\n # Check size before reading\n file_size = get_file_size(file_path)\n \n if file_size > CRITICAL_FILE_SIZE:\n # Never read full file, always summarize\n use_mcp_summarizer_immediately()\n elif file_size > SUMMARIZE_THRESHOLD_SIZE:\n # Read and immediately summarize\n content = read_file(file_path)\n summary = mcp_summarizer(content, style=\"brief\")\n discard_content()\n else:\n # Process normally with line tracking\n process_with_grep_context()\n ```\n\n2. **Cumulative Content Tracking**\n ```python\n cumulative_size = 0\n files_processed = 0\n \n for file in files_to_analyze:\n content = process_file(file)\n cumulative_size += len(content)\n files_processed += 1\n \n # Trigger batch summarization\n if cumulative_size > CUMULATIVE_CONTENT_LIMIT or files_processed >= BATCH_SUMMARIZE_COUNT:\n batch_summary = mcp_summarizer(accumulated_patterns, style=\"bullet_points\")\n reset_counters()\n discard_all_content()\n ```\n\n3. **Adaptive Grep Context**\n ```bash\n # Count matches first\n match_count=$(grep -c \"pattern\" file.py)\n \n # Adapt context based on match count\n if [ $match_count -gt 50 ]; then\n grep -n -A 2 -B 2 \"pattern\" file.py | head -50\n elif [ $match_count -gt 20 ]; then\n grep -n -A 5 -B 5 \"pattern\" file.py | head -40\n else\n grep -n -A 10 -B 10 \"pattern\" file.py\n fi\n ```\n\n### MCP Summarizer Integration Patterns\n\n1. **File Type Specific Summarization**\n ```python\n # Code files - focus on structure\n if file_extension in ['.py', '.js', '.ts']:\n summary = mcp__claude-mpm-gateway__document_summarizer(\n content=code_content,\n style=\"bullet_points\",\n max_length=200\n )\n \n # Documentation - extract key points\n elif file_extension in ['.md', '.rst', '.txt']:\n summary = mcp__claude-mpm-gateway__document_summarizer(\n content=doc_content,\n style=\"brief\",\n max_length=150\n )\n \n # Config files - capture settings\n elif file_extension in ['.json', '.yaml', '.toml']:\n summary = mcp__claude-mpm-gateway__document_summarizer(\n content=config_content,\n style=\"detailed\",\n max_length=250\n )\n ```\n\n2. **Batch Summarization**\n ```python\n # When cumulative threshold reached\n accumulated_patterns = \"\\n\".join(pattern_list)\n batch_summary = mcp__claude-mpm-gateway__document_summarizer(\n content=accumulated_patterns,\n style=\"executive\",\n max_length=300\n )\n # Reset and continue with fresh memory\n ```\n\n## MEMORY-EFFICIENT VERIFICATION PROTOCOL\n\n### Pattern Extraction Method (NOT Full File Reading)\n\n1. **Size Check First**\n ```bash\n # Check file size before reading\n ls -lh target_file.py\n # Skip if >1MB unless critical\n ```\n\n2. **Grep Context with Line Numbers**\n ```bash\n # EXCELLENT: Extract with precise line tracking\n grep -n -A 10 -B 10 \"pattern\" file.py\n \n # GOOD: Extract relevant sections only\n grep -A 10 -B 10 \"pattern\" file.py\n \n # BAD: Reading entire file\n cat file.py # AVOID THIS\n ```\n\n3. **MCP Summarizer Tool Usage**\n ```python\n # Check if MCP summarizer is available\n try:\n # Use summarizer for high-level understanding\n summary = mcp__claude-mpm-gateway__document_summarizer(\n content=document_content,\n style=\"brief\", # or \"detailed\", \"bullet_points\", \"executive\"\n max_length=150\n )\n except:\n # Fallback to manual summarization\n summary = extract_and_summarize_manually(document_content)\n ```\n\n4. **Strategic Sampling with Line Numbers**\n ```bash\n # Sample first 10-20 matches with line numbers\n grep -n -l \"pattern\" . | head -20\n # Then extract patterns from 3-5 of those files with precise locations\n grep -n -A 5 -B 5 \"pattern\" selected_files.py\n ```\n\n5. **Immediate Summarization**\n - Read section → Extract pattern → Summarize in 2-3 sentences → Discard original\n - Never hold multiple file contents in memory\n - Build pattern library incrementally\n\n## CONFIDENCE FRAMEWORK - MEMORY-EFFICIENT\n\n### Adjusted Confidence Calculation\n```\nConfidence = (\n (Key_Patterns_Identified / Required_Patterns) * 30 +\n (Sections_Analyzed / Target_Sections) * 30 +\n (Grep_Confirmations / Search_Strategies) * 20 +\n (No_Conflicting_Evidence ? 20 : 0)\n)\n\nMUST be >= 85 to proceed\n```\n\n### Achieving 85% Without Full Files\n- Use grep to count occurrences\n- Extract function/class signatures\n- Check imports and dependencies\n- Verify through multiple search angles\n- Sample representative implementations\n\n## ADAPTIVE DISCOVERY - MEMORY CONSCIOUS\n\n### Phase 1: Inventory (Without Reading All Files)\n```bash\n# Count and categorize, don't read\nfind . -name \"*.py\" | wc -l\ngrep -r \"class \" --include=\"*.py\" . | wc -l\ngrep -r \"def \" --include=\"*.py\" . | wc -l\n```\n\n### Phase 2: Strategic Pattern Search with Line Tracking\n```bash\n# Step 1: Find pattern locations\ngrep -l \"auth\" . --include=\"*.py\" | head -20\n\n# Step 2: Extract patterns from 3-5 files with line numbers\nfor file in $(grep -l \"auth\" . | head -5); do\n echo \"=== Analyzing $file ===\"\n grep -n -A 10 -B 10 \"auth\" \"$file\"\n echo \"Summary: [2-3 sentences about patterns found]\"\n echo \"Line references: [specific line numbers where patterns occur]\"\n echo \"[Content discarded from memory]\"\ndone\n\n# Step 3: Use MCP summarizer for document analysis (if available)\n# Check tool availability first, then use for condensed analysis\n```\n\n### Phase 3: Verification Without Full Reading\n```bash\n# Verify patterns through signatures with line numbers\ngrep -n \"^class.*Auth\" --include=\"*.py\" .\ngrep -n \"^def.*auth\" --include=\"*.py\" .\ngrep -n \"from.*auth import\" --include=\"*.py\" .\n\n# Get precise location references for documentation\ngrep -n -H \"pattern\" file.py # Shows filename:line_number:match\n```\n\n## ENHANCED OUTPUT FORMAT - MEMORY EFFICIENT\n\n```markdown\n# Analysis Report - Memory Efficient\n\n## MEMORY METRICS\n- **Files Sampled**: 3-5 representative files\n- **Sections Extracted**: Via grep context only\n- **Full Files Read**: 0 (used grep context instead)\n- **Memory Usage**: Minimal (immediate summarization)\n- **MCP Summarizer Used**: Yes/No (when available)\n\n## PATTERN SUMMARY\n### Pattern 1: Authentication\n- **Found in**: auth/service.py:45-67, auth/middleware.py:23-34 (sampled)\n- **Key Insight**: JWT-based with 24hr expiry\n- **Line References**: Key logic at lines 45, 56, 67\n- **Verification**: 15 files contain JWT imports\n- **MCP Summary**: [If used] Condensed analysis via document summarizer\n- **Confidence**: 87%\n\n### Pattern 2: Database Access\n- **Found in**: models/base.py:120-145, db/connection.py:15-28 (sampled)\n- **Key Insight**: SQLAlchemy ORM with connection pooling\n- **Line References**: Pool config at line 120, session factory at line 145\n- **Verification**: 23 model files follow same pattern\n- **Confidence**: 92%\n\n## VERIFICATION WITHOUT FULL READING\n- Import analysis: ✅ Confirmed patterns via imports\n- Signature extraction: ✅ Verified via function/class names\n- Grep confirmation: ✅ Pattern prevalence confirmed\n- Sample validation: ✅ 3-5 files confirmed pattern\n- Line tracking: ✅ Precise locations documented\n```\n\n## FORBIDDEN MEMORY-INTENSIVE PRACTICES\n\n**NEVER DO THIS**:\n1. ❌ Reading entire files when grep context suffices\n2. ❌ Processing multiple large files in parallel\n3. ❌ Retaining file contents after extraction\n4. ❌ Reading all matches instead of sampling\n5. ❌ Loading files >1MB into memory\n\n**ALWAYS DO THIS**:\n1. ✅ Check file size before reading\n2. ✅ Use grep -n -A/-B for context extraction with line numbers\n3. ✅ Use MCP summarizer tool when available for document condensation\n4. ✅ Summarize immediately and discard\n5. ✅ Process files sequentially\n6. ✅ Sample intelligently (3-5 files max)\n7. ✅ Track precise line numbers for all references\n\n## FINAL MANDATE - MEMORY EFFICIENCY\n\n**Core Principle**: Quality insights from strategic sampling beat exhaustive reading that causes memory issues.\n\n**YOU MUST**:\n1. Extract patterns without retaining full files\n2. Summarize immediately after each extraction\n3. Use grep with line numbers (-n) for precise location tracking\n4. Leverage MCP summarizer tool when available (check availability first)\n5. Sample 3-5 files maximum per pattern\n6. Skip files >1MB unless absolutely critical\n7. Process sequentially, never in parallel\n8. Include line number references in all pattern documentation\n\n**REMEMBER**: 85% confidence from smart sampling is better than 100% confidence with memory exhaustion.",
96
+ "instructions": "# Research Agent\n\n**Inherits from**: BASE_AGENT_TEMPLATE.md\n**Focus**: Memory-efficient codebase analysis and architectural research\n\n## Core Expertise\n\nAnalyze codebases, identify patterns, and provide architectural insights with strict memory management. Focus on strategic sampling and pattern extraction.\n\n## Research-Specific Memory Management\n\n**Strategic Sampling**:\n- Sample 3-5 representative files per component\n- Use grep/glob for pattern discovery, not full reading\n- Extract architectural patterns, not implementations\n- Process files sequentially, never parallel\n\n**Pattern Discovery**:\n```bash\n# Find architectural patterns without reading files\ngrep -r \"class.*Controller\" --include=\"*.py\" | head -20\ngrep -r \"@decorator\" --include=\"*.py\" | wc -l\nfind . -type f -name \"*.py\" | xargs grep -l \"import\" | head -10\n```\n\n## Research Protocol\n\n### Phase 1: Discovery\n```bash\n# Map project structure\nfind . -type f -name \"*.py\" | head -30\nls -la src/ | grep -E \"^d\"\ngrep -r \"def main\" --include=\"*.py\"\n```\n\n### Phase 2: Pattern Analysis\n```bash\n# Extract patterns without full reading\ngrep -n \"class\" src/*.py | cut -d: -f1,2 | head -20\ngrep -r \"import\" --include=\"*.py\" | cut -d: -f2 | sort | uniq -c | sort -rn | head -10\n```\n\n### Phase 3: Architecture Mapping\n- Identify module boundaries\n- Map dependencies via imports\n- Document service interfaces\n- Extract configuration patterns\n\n## Research Focus Areas\n\n- **Architecture**: System design, module structure\n- **Patterns**: Design patterns, coding conventions\n- **Dependencies**: External libraries, internal coupling\n- **Security**: Authentication, authorization, validation\n- **Performance**: Bottlenecks, optimization opportunities\n- **Configuration**: Settings, environment variables\n\n## Research Categories\n\n### Code Analysis\n- Structure and organization\n- Design pattern usage\n- Code quality metrics\n- Technical debt assessment\n\n### Architecture Review\n- System boundaries\n- Service interactions\n- Data flow analysis\n- Integration points\n\n### Security Audit\n- Authentication mechanisms\n- Input validation\n- Sensitive data handling\n- Security best practices\n\n## Research-Specific Todo Patterns\n\n**Analysis Tasks**:\n- `[Research] Analyze authentication architecture`\n- `[Research] Map service dependencies`\n- `[Research] Identify performance bottlenecks`\n\n**Pattern Discovery**:\n- `[Research] Find design patterns in codebase`\n- `[Research] Extract API conventions`\n- `[Research] Document configuration patterns`\n\n**Architecture Tasks**:\n- `[Research] Map system architecture`\n- `[Research] Analyze module boundaries`\n- `[Research] Document service interfaces`\n\n## Research Workflow\n\n### Efficient Analysis\n```python\n# Sample approach for large codebases\ncomponents = find_main_components()\nfor component in components[:5]: # Max 5 components\n patterns = grep_patterns(component)\n analyze_patterns(patterns)\n discard_content()\n```\n\n### Dependency Mapping\n```bash\n# Map imports without reading files\ngrep -h \"^import\" **/*.py | sort | uniq | head -50\ngrep -h \"^from\" **/*.py | cut -d\" \" -f2 | sort | uniq -c | sort -rn | head -20\n```\n\n## Research Memory Categories\n\n**Pattern Memories**: Architectural patterns, design patterns\n**Architecture Memories**: System structure, module organization\n**Context Memories**: Project conventions, coding standards\n**Performance Memories**: Bottlenecks, optimization points\n**Security Memories**: Vulnerabilities, security patterns\n\n## Research Standards\n\n- **Sampling**: Maximum 3-5 files per analysis\n- **Extraction**: Patterns only, not full implementations\n- **Documentation**: Clear architectural insights\n- **Memory**: Discard content after extraction\n- **Focus**: Strategic over exhaustive analysis",
84
97
  "dependencies": {
85
98
  "python": [
86
99
  "tree-sitter>=0.21.0",
@@ -98,5 +111,6 @@
98
111
  "git"
99
112
  ],
100
113
  "optional": false
101
- }
102
- }
114
+ },
115
+ "template_version": "2.0.0"
116
+ }
@@ -28,6 +28,7 @@ from .commands import ( # run_guarded_session is imported lazily to avoid loadi
28
28
  manage_memory,
29
29
  manage_monitor,
30
30
  manage_tickets,
31
+ run_doctor,
31
32
  run_session,
32
33
  show_info,
33
34
  )
@@ -316,6 +317,7 @@ def _execute_command(command: str, args) -> int:
316
317
  CLICommands.AGGREGATE.value: aggregate_command,
317
318
  CLICommands.CLEANUP.value: cleanup_memory,
318
319
  CLICommands.MCP.value: manage_mcp,
320
+ CLICommands.DOCTOR.value: run_doctor,
319
321
  }
320
322
 
321
323
  # Execute command if found
@@ -10,6 +10,7 @@ from .agent_manager import manage_agent_manager
10
10
  from .aggregate import aggregate_command
11
11
  from .cleanup import cleanup_memory
12
12
  from .config import manage_config
13
+ from .doctor import run_doctor
13
14
  from .info import show_info
14
15
  from .mcp import manage_mcp
15
16
  from .memory import manage_memory
@@ -33,4 +34,5 @@ __all__ = [
33
34
  "aggregate_command",
34
35
  "cleanup_memory",
35
36
  "manage_mcp",
37
+ "run_doctor",
36
38
  ]
@@ -213,14 +213,15 @@ class AgentManagerCommand(AgentCommand):
213
213
  return CommandResult.error_result(f"Deployment failed: {e}")
214
214
 
215
215
  def _customize_pm(self, args) -> CommandResult:
216
- """Customize PM instructions."""
216
+ """Customize PM instructions via .claude-mpm/INSTRUCTIONS.md."""
217
217
  try:
218
218
  level = getattr(args, 'level', 'user')
219
219
 
220
+ # Use .claude-mpm/INSTRUCTIONS.md for customization
220
221
  if level == 'user':
221
- pm_file = Path.home() / ".claude" / "CLAUDE.md"
222
+ pm_file = Path.home() / ".claude-mpm" / "INSTRUCTIONS.md"
222
223
  elif level == 'project':
223
- pm_file = Path.cwd() / "CLAUDE.md"
224
+ pm_file = Path.cwd() / ".claude-mpm" / "INSTRUCTIONS.md"
224
225
  else:
225
226
  return CommandResult.error_result("Invalid level. Use 'user' or 'project'")
226
227
 
@@ -240,12 +241,13 @@ class AgentManagerCommand(AgentCommand):
240
241
  custom_rules=getattr(args, 'rules', None)
241
242
  )
242
243
 
243
- # Save instructions
244
+ # Save instructions to .claude-mpm directory
244
245
  pm_file.parent.mkdir(parents=True, exist_ok=True)
245
246
  pm_file.write_text(instructions)
246
247
 
247
248
  return CommandResult.success_result(
248
- f"PM instructions customized at {level} level: {pm_file}"
249
+ f"PM instructions customized at {level} level: {pm_file}\n"
250
+ f"Note: These instructions will be loaded by the framework loader."
249
251
  )
250
252
 
251
253
  except Exception as e:
@@ -479,7 +481,7 @@ Commands:
479
481
  create Create a new agent (interactive or with arguments)
480
482
  variant Create an agent variant based on existing agent
481
483
  deploy Deploy agent to project or user tier
482
- customize-pm Customize PM instructions at user or project level
484
+ customize-pm Customize PM instructions via .claude-mpm/INSTRUCTIONS.md
483
485
  show Display detailed agent information
484
486
  test Validate agent configuration
485
487
  templates List available agent templates
@@ -490,6 +492,8 @@ Examples:
490
492
  claude-mpm agent-manager variant --base research --id research-v2
491
493
  claude-mpm agent-manager deploy --agent-id my-agent --tier user
492
494
  claude-mpm agent-manager customize-pm --level project
495
+
496
+ Note: PM customization writes to .claude-mpm/INSTRUCTIONS.md, not CLAUDE.md
493
497
  """
494
498
  return CommandResult.success_result(help_text)
495
499
 
@@ -202,7 +202,8 @@ class AgentsCommand(AgentCommand):
202
202
  print(f"📄 {agent['file']}")
203
203
  if "name" in agent:
204
204
  print(f" Name: {agent['name']}")
205
- print(f" Path: {agent['path']}")
205
+ if "path" in agent:
206
+ print(f" Path: {agent['path']}")
206
207
  print()
207
208
 
208
209
  if verification["warnings"]:
@@ -2,7 +2,7 @@
2
2
  Memory cleanup command implementation for claude-mpm.
3
3
 
4
4
  WHY: Large .claude.json files (>1MB) cause significant memory issues when using --resume.
5
- Claude Desktop loads the entire conversation history into memory, leading to 2GB+ memory
5
+ Claude Code loads the entire conversation history into memory, leading to 2GB+ memory
6
6
  consumption. This command helps users manage and clean up their conversation history.
7
7
 
8
8
  DESIGN DECISIONS:
@@ -0,0 +1,209 @@
1
+ """
2
+ Doctor command implementation for claude-mpm.
3
+
4
+ WHY: Provide a comprehensive diagnostic tool to help users identify and fix
5
+ common issues with their claude-mpm installation and configuration.
6
+
7
+ DESIGN DECISIONS:
8
+ - Use diagnostic runner for orchestration
9
+ - Support multiple output formats (terminal, JSON, markdown)
10
+ - Provide verbose mode for detailed diagnostics
11
+ - Future: Support --fix flag for automatic remediation
12
+ """
13
+
14
+ import logging
15
+ import sys
16
+ from pathlib import Path
17
+
18
+ from ...services.diagnostics import DiagnosticRunner, DoctorReporter
19
+
20
+
21
+ def add_doctor_parser(subparsers):
22
+ """Add doctor command parser.
23
+
24
+ WHY: This command helps users diagnose and fix issues with their
25
+ claude-mpm installation, providing clear actionable feedback.
26
+ """
27
+ parser = subparsers.add_parser(
28
+ "doctor",
29
+ aliases=["diagnose", "check-health"],
30
+ help="Run comprehensive diagnostics on claude-mpm installation",
31
+ description="Run comprehensive health checks on your claude-mpm installation and configuration"
32
+ )
33
+
34
+ parser.add_argument(
35
+ "--verbose",
36
+ "-v",
37
+ action="store_true",
38
+ help="Show detailed diagnostic information"
39
+ )
40
+
41
+ parser.add_argument(
42
+ "--json",
43
+ action="store_true",
44
+ help="Output results in JSON format"
45
+ )
46
+
47
+ parser.add_argument(
48
+ "--markdown",
49
+ action="store_true",
50
+ help="Output results in Markdown format"
51
+ )
52
+
53
+ parser.add_argument(
54
+ "--fix",
55
+ action="store_true",
56
+ help="Attempt to fix issues automatically (experimental)"
57
+ )
58
+
59
+ parser.add_argument(
60
+ "--checks",
61
+ nargs="+",
62
+ choices=[
63
+ "installation", "configuration", "filesystem",
64
+ "claude", "agents", "mcp", "monitor", "common"
65
+ ],
66
+ help="Run only specific checks"
67
+ )
68
+
69
+ parser.add_argument(
70
+ "--parallel",
71
+ action="store_true",
72
+ help="Run checks in parallel for faster execution"
73
+ )
74
+
75
+ parser.add_argument(
76
+ "--no-color",
77
+ action="store_true",
78
+ help="Disable colored output"
79
+ )
80
+
81
+ parser.add_argument(
82
+ "--output",
83
+ "-o",
84
+ type=Path,
85
+ help="Save output to file"
86
+ )
87
+
88
+ parser.set_defaults(func=doctor_command)
89
+
90
+
91
+ def run_doctor(args):
92
+ """Main entry point for doctor command (used by CLI).
93
+
94
+ Args:
95
+ args: Parsed command-line arguments
96
+
97
+ Returns:
98
+ Exit code (0 for success, 1 for warnings, 2 for errors)
99
+ """
100
+ return doctor_command(args)
101
+
102
+
103
+ def doctor_command(args):
104
+ """Execute the doctor command.
105
+
106
+ WHY: Provides a single entry point for system diagnostics, helping users
107
+ quickly identify and resolve issues with their claude-mpm setup.
108
+
109
+ Args:
110
+ args: Parsed command-line arguments
111
+
112
+ Returns:
113
+ Exit code (0 for success, 1 for warnings, 2 for errors)
114
+ """
115
+ # Configure logging
116
+ logger = logging.getLogger(__name__)
117
+
118
+ # Determine output format
119
+ if args.json:
120
+ output_format = "json"
121
+ elif args.markdown:
122
+ output_format = "markdown"
123
+ else:
124
+ output_format = "terminal"
125
+
126
+ # Create diagnostic runner
127
+ runner = DiagnosticRunner(
128
+ verbose=args.verbose,
129
+ fix=args.fix
130
+ )
131
+
132
+ # Run diagnostics
133
+ try:
134
+ if args.checks:
135
+ # Run specific checks
136
+ logger.info(f"Running specific checks: {', '.join(args.checks)}")
137
+ summary = runner.run_specific_checks(args.checks)
138
+ elif args.parallel:
139
+ # Run all checks in parallel
140
+ logger.info("Running diagnostics in parallel mode")
141
+ summary = runner.run_diagnostics_parallel()
142
+ else:
143
+ # Run all checks sequentially
144
+ logger.info("Running comprehensive diagnostics")
145
+ summary = runner.run_diagnostics()
146
+
147
+ except KeyboardInterrupt:
148
+ print("\nDiagnostics interrupted by user")
149
+ return 130
150
+ except Exception as e:
151
+ logger.error(f"Diagnostic failed: {e}")
152
+ print(f"\n❌ Diagnostic failed: {str(e)}")
153
+ if args.verbose:
154
+ import traceback
155
+ traceback.print_exc()
156
+ return 2
157
+
158
+ # Create reporter
159
+ reporter = DoctorReporter(
160
+ use_color=not args.no_color,
161
+ verbose=args.verbose
162
+ )
163
+
164
+ # Output results
165
+ if args.output:
166
+ # Save to file
167
+ try:
168
+ import sys
169
+ original_stdout = sys.stdout
170
+ with open(args.output, 'w') as f:
171
+ sys.stdout = f
172
+ reporter.report(summary, format=output_format)
173
+ sys.stdout = original_stdout
174
+ print(f"Report saved to: {args.output}")
175
+ except Exception as e:
176
+ logger.error(f"Failed to save report: {e}")
177
+ print(f"❌ Failed to save report: {str(e)}")
178
+ # Still output to terminal
179
+ reporter.report(summary, format=output_format)
180
+ else:
181
+ # Output to terminal
182
+ reporter.report(summary, format=output_format)
183
+
184
+ # Determine exit code based on results
185
+ if summary.error_count > 0:
186
+ return 2 # Errors found
187
+ elif summary.warning_count > 0:
188
+ return 1 # Warnings found
189
+ else:
190
+ return 0 # All OK
191
+
192
+
193
+ # Optional: Standalone execution for testing
194
+ if __name__ == "__main__":
195
+ import argparse
196
+
197
+ parser = argparse.ArgumentParser(description="Claude MPM Doctor")
198
+ parser.add_argument("--verbose", "-v", action="store_true")
199
+ parser.add_argument("--json", action="store_true")
200
+ parser.add_argument("--fix", action="store_true")
201
+ parser.add_argument("--no-color", action="store_true")
202
+ parser.add_argument("--checks", nargs="+")
203
+ parser.add_argument("--parallel", action="store_true")
204
+
205
+ args = parser.parse_args()
206
+ args.markdown = False
207
+ args.output = None
208
+
209
+ sys.exit(doctor_command(args))
@@ -157,7 +157,7 @@ def _show_status(
157
157
  else:
158
158
  print(f" No config file at {config_path}")
159
159
 
160
- # Show Claude Desktop configuration
160
+ # Show Claude Code configuration
161
161
  claude_config = (
162
162
  Path.home()
163
163
  / "Library"
@@ -166,7 +166,7 @@ def _show_status(
166
166
  / "claude_desktop_config.json"
167
167
  )
168
168
  if claude_config.exists():
169
- print(f"\n🖥️ Claude Desktop Config: {claude_config}")
169
+ print(f"\n🖥️ Claude Code Config: {claude_config}")
170
170
  try:
171
171
  with open(claude_config) as f:
172
172
  config = json.load(f)
@@ -179,7 +179,7 @@ def _show_status(
179
179
  except Exception as e:
180
180
  print(f" ⚠️ Error reading config: {e}")
181
181
  else:
182
- print("\n🖥️ Claude Desktop not configured for MCP")
182
+ print("\n🖥️ Claude Code not configured for MCP")
183
183
  print(" Run: claude-mpm mcp start (for instructions)")
184
184
 
185
185
  # Show available tools count
@@ -159,48 +159,30 @@ class MCPInstallCommands:
159
159
 
160
160
  DESIGN DECISION: We prioritize in this order:
161
161
  1. System-installed claude-mpm (most reliable)
162
- 2. Virtual environment claude-mpm (development)
163
- 3. Python module invocation (fallback)
162
+ 2. pipx-installed claude-mpm (detected via deployment context)
163
+ 3. Virtual environment claude-mpm (development)
164
+ 4. Python module invocation (fallback)
164
165
 
165
166
  Returns:
166
167
  str or None: Path to claude-mpm executable
167
168
  """
168
- import shutil
169
169
  import sys
170
- import os
171
-
172
- # 1. Try to find claude-mpm in PATH (system-wide or venv)
173
- claude_mpm_path = shutil.which("claude-mpm")
174
- if claude_mpm_path:
175
- print(f" Found claude-mpm: {claude_mpm_path}")
176
- return claude_mpm_path
177
-
178
- # 2. Check if we're in a virtual environment
179
- if hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix):
180
- # We're in a virtual environment
181
- venv_bin = Path(sys.prefix) / ("Scripts" if sys.platform == "win32" else "bin")
182
- venv_claude_mpm = venv_bin / "claude-mpm"
183
- if venv_claude_mpm.exists():
184
- print(f" Found claude-mpm in venv: {venv_claude_mpm}")
185
- return str(venv_claude_mpm)
186
-
187
- # 3. Check if claude_mpm module is installed and use Python to run it
170
+ from ...core.unified_paths import get_executable_path
171
+
172
+ # Use the enhanced unified path manager for executable detection
173
+ executable_path = get_executable_path()
174
+ if executable_path:
175
+ print(f" Found claude-mpm: {executable_path}")
176
+ return str(executable_path)
177
+
178
+ # Fallback: Use Python module invocation if no executable found
188
179
  try:
189
180
  import claude_mpm
190
- # Return the Python executable - we'll handle the -m args separately
191
181
  print(f" Using Python module: {sys.executable} -m claude_mpm")
192
182
  return sys.executable
193
183
  except ImportError:
194
184
  pass
195
185
 
196
- # 4. Last resort: check project's local venv (development mode)
197
- project_root = Path(__file__).parent.parent.parent.parent.parent
198
- local_venv_bin = project_root / "venv" / ("Scripts" if sys.platform == "win32" else "bin")
199
- local_claude_mpm = local_venv_bin / "claude-mpm"
200
- if local_claude_mpm.exists():
201
- print(f" Found claude-mpm in project venv: {local_claude_mpm}")
202
- return str(local_claude_mpm)
203
-
204
186
  return None
205
187
 
206
188
  def _load_or_create_config(self, config_path, force=False):
@@ -22,11 +22,11 @@ class MCPServerCommands:
22
22
  """Start MCP server command.
23
23
 
24
24
  WHY: This command starts the MCP server using the proper stdio-based
25
- implementation that Claude Desktop can communicate with.
26
- NOTE: MCP is for Claude Desktop's Code features.
25
+ implementation that Claude Code can communicate with.
26
+ NOTE: MCP is specifically for Claude Code features.
27
27
 
28
28
  DESIGN DECISION: Run the server directly in the same process to ensure
29
- Claude Desktop sees the correct command path, not a wrapper script.
29
+ Claude Code sees the correct command path, not a wrapper script.
30
30
  """
31
31
  self.logger.info("MCP server start command called")
32
32
 
@@ -39,18 +39,18 @@ class MCPServerCommands:
39
39
  # Daemon mode - not recommended for MCP
40
40
  print("⚠️ MCP servers are designed to be spawned by Claude Code")
41
41
  print(" Running as a daemon is not recommended.")
42
- print(" Note: MCP is ONLY for Claude Code, not Claude Desktop.")
42
+ print(" Note: MCP is specifically for Claude Code.")
43
43
  return 1
44
44
 
45
45
  if show_instructions:
46
46
  # Show configuration instructions
47
- print("🚀 MCP Server Setup Instructions for Claude Desktop")
47
+ print("🚀 MCP Server Setup Instructions for Claude Code")
48
48
  print("=" * 50)
49
- print("\nThe MCP server enables Claude Desktop to use tools and integrations.")
49
+ print("\nThe MCP server enables Claude Code to use tools and integrations.")
50
50
  print("\nTo configure the MCP server:")
51
51
  print("\n1. Run the configuration script:")
52
52
  print(" python scripts/configure_mcp_server.py")
53
- print("\n2. Or manually configure Claude Desktop:")
53
+ print("\n2. Or manually configure Claude Code:")
54
54
 
55
55
  # Find project root for paths
56
56
  project_root = Path(__file__).parent.parent.parent.parent.parent
@@ -62,7 +62,7 @@ class MCPServerCommands:
62
62
  # Fallback to current executable
63
63
  claude_mpm_path = sys.executable.replace("python", "claude-mpm")
64
64
 
65
- print("\n Add this to your Claude Desktop configuration:")
65
+ print("\n Add this to your Claude Code configuration:")
66
66
  print(" (~/Library/Application Support/Claude/claude_desktop_config.json on macOS)")
67
67
  print("\n {")
68
68
  print(' "mcpServers": {')
@@ -73,7 +73,7 @@ class MCPServerCommands:
73
73
  print(' }')
74
74
  print(' }')
75
75
  print(' }')
76
- print("\n3. Restart Claude Desktop to load the MCP server")
76
+ print("\n3. Restart Claude Code to load the MCP server")
77
77
  print("\nTo test the server directly:")
78
78
  print(" claude-mpm mcp server")
79
79
  print("\nTo check running MCP processes:")
@@ -30,6 +30,11 @@ from ...core.unified_paths import get_package_root, get_scripts_dir
30
30
  from ...services.port_manager import PortManager
31
31
  from ...utils.dependency_manager import ensure_socketio_dependencies
32
32
  from ..shared import BaseCommand, CommandResult
33
+ from ..startup_logging import (
34
+ log_startup_status,
35
+ setup_startup_logging,
36
+ cleanup_old_startup_logs
37
+ )
33
38
  from ..utils import get_user_input, list_agent_versions_at_startup
34
39
 
35
40
 
@@ -232,6 +237,12 @@ class RunCommand(BaseCommand):
232
237
  if args.logging != LogLevel.OFF.value:
233
238
  self.logger.info("Starting Claude MPM session")
234
239
 
240
+ # Log MCP and monitor startup status
241
+ if args.logging != LogLevel.OFF.value:
242
+ monitor_mode = getattr(args, "monitor", False)
243
+ websocket_port = getattr(args, "websocket_port", 8765)
244
+ log_startup_status(monitor_mode, websocket_port)
245
+
235
246
  # Perform startup checks
236
247
  self._check_configuration_health()
237
248
  self._check_claude_json_memory(args)
@@ -549,9 +560,27 @@ def run_session_legacy(args):
549
560
  Args:
550
561
  args: Parsed command line arguments
551
562
  """
563
+ # Set up startup logging to file early in the process
564
+ startup_log_file = setup_startup_logging(Path.cwd())
565
+
552
566
  logger = get_logger("cli")
553
567
  if args.logging != LogLevel.OFF.value:
554
568
  logger.info("Starting Claude MPM session")
569
+ logger.info(f"Startup log: {startup_log_file}")
570
+
571
+ # Clean up old startup logs (keep last 7 days or minimum 10 files)
572
+ try:
573
+ deleted_count = cleanup_old_startup_logs(Path.cwd())
574
+ if deleted_count > 0:
575
+ logger.debug(f"Cleaned up {deleted_count} old startup log files")
576
+ except Exception as e:
577
+ logger.debug(f"Failed to clean up old logs: {e}")
578
+
579
+ # Log MCP and monitor startup status
580
+ if args.logging != LogLevel.OFF.value:
581
+ monitor_mode = getattr(args, "monitor", False)
582
+ websocket_port = getattr(args, "websocket_port", 8765)
583
+ log_startup_status(monitor_mode, websocket_port)
555
584
 
556
585
  # Perform startup configuration check
557
586
  _check_configuration_health(logger)
@@ -1102,7 +1131,7 @@ def _check_claude_json_memory(args, logger):
1102
1131
  """Check .claude.json file size and warn about memory issues.
1103
1132
 
1104
1133
  WHY: Large .claude.json files (>500KB) cause significant memory issues when
1105
- using --resume. Claude Desktop loads the entire conversation history into
1134
+ using --resume. Claude Code loads the entire conversation history into
1106
1135
  memory, leading to 2GB+ memory consumption.
1107
1136
 
1108
1137
  DESIGN DECISIONS:
@@ -1159,7 +1188,7 @@ def _check_claude_json_memory(args, logger):
1159
1188
  f"\n⚠️ CRITICAL: Large .claude.json file detected ({format_size(file_size)})"
1160
1189
  )
1161
1190
  print(f" This WILL cause memory issues when using --resume")
1162
- print(f" Claude Desktop may consume 2GB+ of memory\n")
1191
+ print(f" Claude Code may consume 2GB+ of memory\n")
1163
1192
 
1164
1193
  if not getattr(args, "force", False):
1165
1194
  print(" Recommended actions:")
@@ -21,7 +21,7 @@ class RunConfigChecker:
21
21
  """Check .claude.json file size and warn about memory issues.
22
22
 
23
23
  WHY: Large .claude.json files (>500KB) cause significant memory issues when
24
- using --resume. Claude Desktop loads the entire conversation history into
24
+ using --resume. Claude Code loads the entire conversation history into
25
25
  memory, leading to 2GB+ memory consumption.
26
26
  """
27
27
  try:
@@ -28,7 +28,7 @@ Examples:
28
28
  claude-mpm agent-manager create --id my-agent # Create agent with ID
29
29
  claude-mpm agent-manager variant --base research # Create research variant
30
30
  claude-mpm agent-manager deploy --id my-agent --tier user # Deploy to user tier
31
- claude-mpm agent-manager customize-pm --level project # Edit project PM instructions
31
+ claude-mpm agent-manager customize-pm --level project # Edit .claude-mpm/INSTRUCTIONS.md
32
32
  claude-mpm agent-manager show --id engineer # Show agent details
33
33
  claude-mpm agent-manager test --id my-agent # Test agent configuration
34
34
  claude-mpm agent-manager templates # List available templates
@@ -169,13 +169,13 @@ Examples:
169
169
  # Customize PM command
170
170
  pm_parser = agent_subparsers.add_parser(
171
171
  "customize-pm",
172
- help="Customize PM instructions at user or project level"
172
+ help="Customize PM instructions via .claude-mpm/INSTRUCTIONS.md"
173
173
  )
174
174
  pm_parser.add_argument(
175
175
  "--level",
176
176
  choices=["user", "project"],
177
177
  default="user",
178
- help="PM instruction level (default: user)"
178
+ help="PM instruction level - user (~/.claude-mpm) or project (./.claude-mpm) (default: user)"
179
179
  )
180
180
  pm_parser.add_argument(
181
181
  "--template",
@@ -190,7 +190,7 @@ def add_top_level_run_arguments(parser: argparse.ArgumentParser) -> None:
190
190
  run_group.add_argument(
191
191
  "--resume",
192
192
  action="store_true",
193
- help="Pass --resume flag to Claude Desktop to resume the last conversation",
193
+ help="Pass --resume flag to Claude Code to resume the last conversation",
194
194
  )
195
195
  run_group.add_argument(
196
196
  "--force",
@@ -338,6 +338,10 @@ def create_parser(
338
338
  from ..commands.cleanup import add_cleanup_parser
339
339
 
340
340
  add_cleanup_parser(subparsers)
341
+
342
+ from ..commands.doctor import add_doctor_parser
343
+
344
+ add_doctor_parser(subparsers)
341
345
  except ImportError:
342
346
  # Commands module may not be available during testing or refactoring
343
347
  pass