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.
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +48 -3
- claude_mpm/agents/BASE_PM.md +20 -15
- claude_mpm/agents/INSTRUCTIONS.md +12 -2
- claude_mpm/agents/templates/documentation.json +16 -3
- claude_mpm/agents/templates/engineer.json +19 -5
- claude_mpm/agents/templates/ops.json +19 -5
- claude_mpm/agents/templates/qa.json +16 -3
- claude_mpm/agents/templates/refactoring_engineer.json +25 -7
- claude_mpm/agents/templates/research.json +19 -5
- claude_mpm/cli/__init__.py +2 -0
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/agent_manager.py +10 -6
- claude_mpm/cli/commands/agents.py +2 -1
- claude_mpm/cli/commands/cleanup.py +1 -1
- claude_mpm/cli/commands/doctor.py +209 -0
- claude_mpm/cli/commands/mcp.py +3 -3
- claude_mpm/cli/commands/mcp_install_commands.py +12 -30
- claude_mpm/cli/commands/mcp_server_commands.py +9 -9
- claude_mpm/cli/commands/run.py +31 -2
- claude_mpm/cli/commands/run_config_checker.py +1 -1
- claude_mpm/cli/parsers/agent_manager_parser.py +3 -3
- claude_mpm/cli/parsers/base_parser.py +5 -1
- claude_mpm/cli/parsers/mcp_parser.py +1 -1
- claude_mpm/cli/parsers/run_parser.py +1 -1
- claude_mpm/cli/startup_logging.py +463 -0
- claude_mpm/constants.py +1 -0
- claude_mpm/core/claude_runner.py +78 -0
- claude_mpm/core/framework_loader.py +45 -11
- claude_mpm/core/interactive_session.py +82 -3
- claude_mpm/core/output_style_manager.py +6 -6
- claude_mpm/core/unified_paths.py +128 -0
- claude_mpm/scripts/mcp_server.py +2 -2
- claude_mpm/services/agents/deployment/agent_validator.py +1 -0
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +69 -1
- claude_mpm/services/diagnostics/__init__.py +18 -0
- claude_mpm/services/diagnostics/checks/__init__.py +30 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +319 -0
- claude_mpm/services/diagnostics/checks/base_check.py +64 -0
- claude_mpm/services/diagnostics/checks/claude_desktop_check.py +283 -0
- claude_mpm/services/diagnostics/checks/common_issues_check.py +354 -0
- claude_mpm/services/diagnostics/checks/configuration_check.py +300 -0
- claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
- claude_mpm/services/diagnostics/checks/installation_check.py +255 -0
- claude_mpm/services/diagnostics/checks/mcp_check.py +315 -0
- claude_mpm/services/diagnostics/checks/monitor_check.py +282 -0
- claude_mpm/services/diagnostics/checks/startup_log_check.py +322 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +247 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +283 -0
- claude_mpm/services/diagnostics/models.py +120 -0
- claude_mpm/services/mcp_gateway/core/interfaces.py +1 -1
- claude_mpm/services/mcp_gateway/main.py +1 -1
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +3 -3
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +1 -1
- claude_mpm/services/mcp_gateway/server/stdio_server.py +3 -3
- claude_mpm/services/mcp_gateway/tools/ticket_tools.py +2 -2
- claude_mpm/services/socketio/handlers/registry.py +39 -7
- claude_mpm/services/socketio/server/core.py +72 -22
- claude_mpm/validation/frontmatter_validator.py +1 -1
- {claude_mpm-4.0.29.dist-info → claude_mpm-4.0.30.dist-info}/METADATA +4 -1
- {claude_mpm-4.0.29.dist-info → claude_mpm-4.0.30.dist-info}/RECORD +64 -47
- {claude_mpm-4.0.29.dist-info → claude_mpm-4.0.30.dist-info}/WHEEL +0 -0
- {claude_mpm-4.0.29.dist-info → claude_mpm-4.0.30.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.0.29.dist-info → claude_mpm-4.0.30.dist-info}/licenses/LICENSE +0 -0
- {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.
|
|
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-
|
|
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
|
+
}
|
claude_mpm/cli/__init__.py
CHANGED
|
@@ -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" / "
|
|
222
|
+
pm_file = Path.home() / ".claude-mpm" / "INSTRUCTIONS.md"
|
|
222
223
|
elif level == 'project':
|
|
223
|
-
pm_file = Path.cwd() / "
|
|
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
|
|
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
|
-
|
|
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
|
|
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))
|
claude_mpm/cli/commands/mcp.py
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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.
|
|
163
|
-
3.
|
|
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
|
|
171
|
-
|
|
172
|
-
#
|
|
173
|
-
|
|
174
|
-
if
|
|
175
|
-
print(f" Found claude-mpm: {
|
|
176
|
-
return
|
|
177
|
-
|
|
178
|
-
#
|
|
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
|
|
26
|
-
NOTE: MCP is for Claude
|
|
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
|
|
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
|
|
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
|
|
47
|
+
print("🚀 MCP Server Setup Instructions for Claude Code")
|
|
48
48
|
print("=" * 50)
|
|
49
|
-
print("\nThe MCP server enables Claude
|
|
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
|
|
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
|
|
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
|
|
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:")
|
claude_mpm/cli/commands/run.py
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|