claude-mpm 4.0.28__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 (89) 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/agent-manager.json +24 -0
  5. claude_mpm/agents/templates/agent-manager.md +304 -0
  6. claude_mpm/agents/templates/documentation.json +16 -3
  7. claude_mpm/agents/templates/engineer.json +19 -5
  8. claude_mpm/agents/templates/ops.json +19 -5
  9. claude_mpm/agents/templates/qa.json +16 -3
  10. claude_mpm/agents/templates/refactoring_engineer.json +25 -7
  11. claude_mpm/agents/templates/research.json +19 -5
  12. claude_mpm/cli/__init__.py +4 -0
  13. claude_mpm/cli/commands/__init__.py +4 -0
  14. claude_mpm/cli/commands/agent_manager.py +521 -0
  15. claude_mpm/cli/commands/agents.py +2 -1
  16. claude_mpm/cli/commands/cleanup.py +1 -1
  17. claude_mpm/cli/commands/doctor.py +209 -0
  18. claude_mpm/cli/commands/mcp.py +3 -3
  19. claude_mpm/cli/commands/mcp_install_commands.py +12 -30
  20. claude_mpm/cli/commands/mcp_server_commands.py +9 -9
  21. claude_mpm/cli/commands/memory.py +1 -1
  22. claude_mpm/cli/commands/run.py +31 -2
  23. claude_mpm/cli/commands/run_config_checker.py +1 -1
  24. claude_mpm/cli/parsers/agent_manager_parser.py +247 -0
  25. claude_mpm/cli/parsers/base_parser.py +12 -1
  26. claude_mpm/cli/parsers/mcp_parser.py +1 -1
  27. claude_mpm/cli/parsers/run_parser.py +1 -1
  28. claude_mpm/cli/shared/__init__.py +1 -1
  29. claude_mpm/cli/startup_logging.py +463 -0
  30. claude_mpm/constants.py +2 -0
  31. claude_mpm/core/claude_runner.py +81 -2
  32. claude_mpm/core/constants.py +2 -2
  33. claude_mpm/core/framework_loader.py +45 -11
  34. claude_mpm/core/interactive_session.py +82 -3
  35. claude_mpm/core/output_style_manager.py +6 -6
  36. claude_mpm/core/socketio_pool.py +2 -2
  37. claude_mpm/core/unified_paths.py +128 -0
  38. claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
  39. claude_mpm/dashboard/static/built/components/module-viewer.js +1 -1
  40. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  41. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  42. claude_mpm/dashboard/static/css/dashboard.css +170 -0
  43. claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
  44. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  45. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  46. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +21 -3
  47. claude_mpm/dashboard/static/js/components/module-viewer.js +129 -1
  48. claude_mpm/dashboard/static/js/dashboard.js +116 -0
  49. claude_mpm/dashboard/static/js/socket-client.js +0 -1
  50. claude_mpm/hooks/claude_hooks/connection_pool.py +1 -1
  51. claude_mpm/hooks/claude_hooks/hook_handler.py +1 -1
  52. claude_mpm/scripts/mcp_server.py +2 -2
  53. claude_mpm/services/agents/agent_builder.py +455 -0
  54. claude_mpm/services/agents/deployment/agent_template_builder.py +10 -3
  55. claude_mpm/services/agents/deployment/agent_validator.py +1 -0
  56. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +69 -1
  57. claude_mpm/services/diagnostics/__init__.py +18 -0
  58. claude_mpm/services/diagnostics/checks/__init__.py +30 -0
  59. claude_mpm/services/diagnostics/checks/agent_check.py +319 -0
  60. claude_mpm/services/diagnostics/checks/base_check.py +64 -0
  61. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +283 -0
  62. claude_mpm/services/diagnostics/checks/common_issues_check.py +354 -0
  63. claude_mpm/services/diagnostics/checks/configuration_check.py +300 -0
  64. claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
  65. claude_mpm/services/diagnostics/checks/installation_check.py +255 -0
  66. claude_mpm/services/diagnostics/checks/mcp_check.py +315 -0
  67. claude_mpm/services/diagnostics/checks/monitor_check.py +282 -0
  68. claude_mpm/services/diagnostics/checks/startup_log_check.py +322 -0
  69. claude_mpm/services/diagnostics/diagnostic_runner.py +247 -0
  70. claude_mpm/services/diagnostics/doctor_reporter.py +283 -0
  71. claude_mpm/services/diagnostics/models.py +120 -0
  72. claude_mpm/services/mcp_gateway/core/interfaces.py +1 -1
  73. claude_mpm/services/mcp_gateway/main.py +1 -1
  74. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +3 -3
  75. claude_mpm/services/mcp_gateway/server/stdio_handler.py +1 -1
  76. claude_mpm/services/mcp_gateway/server/stdio_server.py +3 -3
  77. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +2 -2
  78. claude_mpm/services/memory/__init__.py +2 -0
  79. claude_mpm/services/socketio/handlers/connection.py +27 -33
  80. claude_mpm/services/socketio/handlers/registry.py +39 -7
  81. claude_mpm/services/socketio/server/core.py +72 -22
  82. claude_mpm/validation/frontmatter_validator.py +1 -1
  83. {claude_mpm-4.0.28.dist-info → claude_mpm-4.0.30.dist-info}/METADATA +4 -1
  84. {claude_mpm-4.0.28.dist-info → claude_mpm-4.0.30.dist-info}/RECORD +89 -67
  85. /claude_mpm/cli/shared/{command_base.py → base_command.py} +0 -0
  86. {claude_mpm-4.0.28.dist-info → claude_mpm-4.0.30.dist-info}/WHEEL +0 -0
  87. {claude_mpm-4.0.28.dist-info → claude_mpm-4.0.30.dist-info}/entry_points.txt +0 -0
  88. {claude_mpm-4.0.28.dist-info → claude_mpm-4.0.30.dist-info}/licenses/LICENSE +0 -0
  89. {claude_mpm-4.0.28.dist-info → claude_mpm-4.0.30.dist-info}/top_level.txt +0 -0
@@ -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:")
@@ -23,7 +23,7 @@ from ...core.config import Config
23
23
  from ...core.logger import get_logger
24
24
  from ...core.shared.config_loader import ConfigLoader
25
25
  from ...services.agents.memory import AgentMemoryManager
26
- from ..shared.command_base import MemoryCommand, CommandResult
26
+ from ..shared.base_command import MemoryCommand, CommandResult
27
27
  from ..shared.argument_patterns import add_memory_arguments, add_output_arguments
28
28
 
29
29
 
@@ -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:
@@ -0,0 +1,247 @@
1
+ """
2
+ Agent Manager parser module for claude-mpm CLI.
3
+
4
+ This module defines the argument parser for the agent-manager command,
5
+ which provides comprehensive agent lifecycle management capabilities.
6
+ """
7
+
8
+ import argparse
9
+
10
+
11
+ def add_agent_manager_subparser(subparsers: argparse._SubParsersAction) -> None:
12
+ """
13
+ Add the agent-manager subcommand to the parser.
14
+
15
+ Args:
16
+ subparsers: The subparsers object to add to
17
+ """
18
+ # Create the agent-manager parser
19
+ agent_manager_parser = subparsers.add_parser(
20
+ "agent-manager",
21
+ help="Manage agent creation, customization, and deployment",
22
+ description="Comprehensive agent lifecycle management for Claude MPM",
23
+ formatter_class=argparse.RawDescriptionHelpFormatter,
24
+ epilog="""
25
+ Examples:
26
+ claude-mpm agent-manager list # List all agents across tiers
27
+ claude-mpm agent-manager create # Interactive agent creation
28
+ claude-mpm agent-manager create --id my-agent # Create agent with ID
29
+ claude-mpm agent-manager variant --base research # Create research variant
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 .claude-mpm/INSTRUCTIONS.md
32
+ claude-mpm agent-manager show --id engineer # Show agent details
33
+ claude-mpm agent-manager test --id my-agent # Test agent configuration
34
+ claude-mpm agent-manager templates # List available templates
35
+ """
36
+ )
37
+
38
+ # Create subcommands for agent-manager
39
+ agent_subparsers = agent_manager_parser.add_subparsers(
40
+ dest="agent_manager_command",
41
+ help="Agent management operations",
42
+ metavar="OPERATION"
43
+ )
44
+
45
+ # List command
46
+ list_parser = agent_subparsers.add_parser(
47
+ "list",
48
+ help="List all agents across tiers with hierarchy"
49
+ )
50
+ list_parser.add_argument(
51
+ "--format",
52
+ choices=["text", "json", "yaml"],
53
+ default="text",
54
+ help="Output format (default: text)"
55
+ )
56
+
57
+ # Create command
58
+ create_parser = agent_subparsers.add_parser(
59
+ "create",
60
+ help="Create a new agent (interactive or with arguments)"
61
+ )
62
+ create_parser.add_argument(
63
+ "--id",
64
+ dest="agent_id",
65
+ help="Agent ID (lowercase, hyphens only)"
66
+ )
67
+ create_parser.add_argument(
68
+ "--name",
69
+ help="Display name for the agent"
70
+ )
71
+ create_parser.add_argument(
72
+ "--description",
73
+ help="Agent purpose and capabilities"
74
+ )
75
+ create_parser.add_argument(
76
+ "--model",
77
+ choices=["sonnet", "opus", "haiku"],
78
+ default="sonnet",
79
+ help="LLM model to use (default: sonnet)"
80
+ )
81
+ create_parser.add_argument(
82
+ "--tool-choice",
83
+ choices=["auto", "required", "any", "none"],
84
+ default="auto",
85
+ help="Tool selection strategy (default: auto)"
86
+ )
87
+ create_parser.add_argument(
88
+ "--template",
89
+ help="Base template to extend from"
90
+ )
91
+ create_parser.add_argument(
92
+ "--format",
93
+ choices=["text", "json"],
94
+ default="text",
95
+ help="Output format (default: text)"
96
+ )
97
+
98
+ # Variant command
99
+ variant_parser = agent_subparsers.add_parser(
100
+ "variant",
101
+ help="Create an agent variant based on existing agent"
102
+ )
103
+ variant_parser.add_argument(
104
+ "--base",
105
+ dest="base_agent",
106
+ required=True,
107
+ help="Base agent ID to create variant from"
108
+ )
109
+ variant_parser.add_argument(
110
+ "--id",
111
+ dest="variant_id",
112
+ required=True,
113
+ help="Variant agent ID"
114
+ )
115
+ variant_parser.add_argument(
116
+ "--name",
117
+ help="Display name for the variant"
118
+ )
119
+ variant_parser.add_argument(
120
+ "--model",
121
+ choices=["sonnet", "opus", "haiku"],
122
+ help="Override model for variant"
123
+ )
124
+ variant_parser.add_argument(
125
+ "--tool-choice",
126
+ choices=["auto", "required", "any", "none"],
127
+ help="Override tool choice for variant"
128
+ )
129
+ variant_parser.add_argument(
130
+ "--instructions",
131
+ help="Additional instructions to append for variant"
132
+ )
133
+ variant_parser.add_argument(
134
+ "--format",
135
+ choices=["text", "json"],
136
+ default="text",
137
+ help="Output format (default: text)"
138
+ )
139
+
140
+ # Deploy command
141
+ deploy_parser = agent_subparsers.add_parser(
142
+ "deploy",
143
+ help="Deploy agent to specified tier"
144
+ )
145
+ deploy_parser.add_argument(
146
+ "--id",
147
+ dest="agent_id",
148
+ required=True,
149
+ help="Agent ID to deploy"
150
+ )
151
+ deploy_parser.add_argument(
152
+ "--tier",
153
+ choices=["project", "user"],
154
+ default="user",
155
+ help="Deployment tier (default: user)"
156
+ )
157
+ deploy_parser.add_argument(
158
+ "--force",
159
+ action="store_true",
160
+ help="Force deployment even if agent exists"
161
+ )
162
+ deploy_parser.add_argument(
163
+ "--format",
164
+ choices=["text", "json"],
165
+ default="text",
166
+ help="Output format (default: text)"
167
+ )
168
+
169
+ # Customize PM command
170
+ pm_parser = agent_subparsers.add_parser(
171
+ "customize-pm",
172
+ help="Customize PM instructions via .claude-mpm/INSTRUCTIONS.md"
173
+ )
174
+ pm_parser.add_argument(
175
+ "--level",
176
+ choices=["user", "project"],
177
+ default="user",
178
+ help="PM instruction level - user (~/.claude-mpm) or project (./.claude-mpm) (default: user)"
179
+ )
180
+ pm_parser.add_argument(
181
+ "--template",
182
+ help="Use predefined PM template"
183
+ )
184
+ pm_parser.add_argument(
185
+ "--patterns",
186
+ nargs="+",
187
+ help="Custom delegation patterns"
188
+ )
189
+ pm_parser.add_argument(
190
+ "--rules",
191
+ nargs="+",
192
+ help="Additional PM rules"
193
+ )
194
+ pm_parser.add_argument(
195
+ "--format",
196
+ choices=["text", "json"],
197
+ default="text",
198
+ help="Output format (default: text)"
199
+ )
200
+
201
+ # Show command
202
+ show_parser = agent_subparsers.add_parser(
203
+ "show",
204
+ help="Display detailed agent information"
205
+ )
206
+ show_parser.add_argument(
207
+ "--id",
208
+ dest="agent_id",
209
+ required=True,
210
+ help="Agent ID to show"
211
+ )
212
+ show_parser.add_argument(
213
+ "--format",
214
+ choices=["text", "json", "yaml"],
215
+ default="text",
216
+ help="Output format (default: text)"
217
+ )
218
+
219
+ # Test command
220
+ test_parser = agent_subparsers.add_parser(
221
+ "test",
222
+ help="Test and validate agent configuration"
223
+ )
224
+ test_parser.add_argument(
225
+ "--id",
226
+ dest="agent_id",
227
+ required=True,
228
+ help="Agent ID to test"
229
+ )
230
+ test_parser.add_argument(
231
+ "--format",
232
+ choices=["text", "json"],
233
+ default="text",
234
+ help="Output format (default: text)"
235
+ )
236
+
237
+ # Templates command
238
+ templates_parser = agent_subparsers.add_parser(
239
+ "templates",
240
+ help="List available agent templates"
241
+ )
242
+ templates_parser.add_argument(
243
+ "--format",
244
+ choices=["text", "json", "yaml"],
245
+ default="text",
246
+ help="Output format (default: text)"
247
+ )