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
@@ -70,21 +70,31 @@ class EventHandlerRegistry:
70
70
  )
71
71
  return
72
72
 
73
+ # Add debug logging for deployment context
74
+ try:
75
+ from ....core.unified_paths import PathContext
76
+ deployment_context = PathContext.detect_deployment_context()
77
+ self.logger.info(f"Initializing event handlers in {deployment_context.value} mode")
78
+ except Exception as e:
79
+ self.logger.debug(f"Could not detect deployment context: {e}")
80
+
73
81
  handler_classes = handler_classes or self.DEFAULT_HANDLERS
82
+ self.logger.debug(f"Initializing {len(handler_classes)} handler classes")
74
83
 
75
84
  for handler_class in handler_classes:
76
85
  try:
86
+ self.logger.debug(f"Creating instance of {handler_class.__name__}")
77
87
  handler = handler_class(self.server)
78
88
  self.handlers.append(handler)
79
- self.logger.info(f"Initialized handler: {handler_class.__name__}")
89
+ self.logger.info(f"Initialized handler: {handler_class.__name__}")
80
90
  except Exception as e:
81
- self.logger.error(f"Failed to initialize {handler_class.__name__}: {e}")
91
+ self.logger.error(f"Failed to initialize {handler_class.__name__}: {e}")
82
92
  import traceback
83
93
 
84
94
  self.logger.error(f"Stack trace: {traceback.format_exc()}")
85
95
 
86
96
  self._initialized = True
87
- self.logger.info(f"Registry initialized with {len(self.handlers)} handlers")
97
+ self.logger.info(f"🎯 Registry initialized with {len(self.handlers)} handlers")
88
98
 
89
99
  def register_all_events(self) -> None:
90
100
  """Register all events from all handlers.
@@ -97,27 +107,49 @@ class EventHandlerRegistry:
97
107
  self.logger.error("Registry not initialized. Call initialize() first.")
98
108
  raise RuntimeError("EventHandlerRegistry not initialized")
99
109
 
110
+ self.logger.info(f"🔄 Starting event registration for {len(self.handlers)} handlers")
111
+
112
+ # Verify Socket.IO server is available
113
+ if not hasattr(self.server, 'core') or not self.server.core or not self.server.core.sio:
114
+ self.logger.error("❌ Socket.IO server instance not available for event registration")
115
+ raise RuntimeError("Socket.IO server not available")
116
+
117
+ self.logger.debug(f"Socket.IO server available: {type(self.server.core.sio)}")
118
+
100
119
  registered_count = 0
101
120
  for handler in self.handlers:
102
121
  try:
122
+ self.logger.debug(f"Registering events for {handler.__class__.__name__}")
123
+
124
+ # Get the number of registered events before and after
125
+ sio_events_before = len(getattr(self.server.core.sio, 'handlers', {}))
126
+
103
127
  handler.register_events()
128
+
129
+ sio_events_after = len(getattr(self.server.core.sio, 'handlers', {}))
130
+ events_added = sio_events_after - sio_events_before
131
+
104
132
  registered_count += 1
105
- self.logger.info(f"Registered events for {handler.__class__.__name__}")
133
+ self.logger.info(f"Registered {events_added} events for {handler.__class__.__name__}")
134
+
106
135
  except NotImplementedError:
107
136
  # Handler has no events to register (like ProjectEventHandler)
108
137
  self.logger.debug(
109
- f"No events to register for {handler.__class__.__name__}"
138
+ f"⏭️ No events to register for {handler.__class__.__name__}"
110
139
  )
111
140
  except Exception as e:
112
141
  self.logger.error(
113
- f"Failed to register events for {handler.__class__.__name__}: {e}"
142
+ f"Failed to register events for {handler.__class__.__name__}: {e}"
114
143
  )
115
144
  import traceback
116
145
 
117
146
  self.logger.error(f"Stack trace: {traceback.format_exc()}")
118
147
 
148
+ # Final verification
149
+ total_sio_events = len(getattr(self.server.core.sio, 'handlers', {}))
119
150
  self.logger.info(
120
- f"Successfully registered events from {registered_count} handlers"
151
+ f"🎉 Event registration complete: {registered_count} handlers processed, "
152
+ f"{total_sio_events} total Socket.IO events registered"
121
153
  )
122
154
 
123
155
  def add_handler(self, handler_class: Type[BaseEventHandler]):
@@ -231,15 +231,27 @@ class SocketIOServerCore:
231
231
  def _setup_static_files(self):
232
232
  """Setup static file serving for the dashboard."""
233
233
  try:
234
+ # Add debug logging for deployment context
235
+ try:
236
+ from ....core.unified_paths import PathContext
237
+ deployment_context = PathContext.detect_deployment_context()
238
+ self.logger.debug(f"Setting up static files in {deployment_context.value} mode")
239
+ except Exception as e:
240
+ self.logger.debug(f"Could not detect deployment context: {e}")
241
+
234
242
  self.dashboard_path = self._find_static_path()
235
243
 
236
244
  if self.dashboard_path and self.dashboard_path.exists():
245
+ self.logger.info(f"✅ Dashboard found at: {self.dashboard_path}")
246
+
237
247
  # Serve index.html at root
238
248
  async def index_handler(request):
239
249
  index_file = self.dashboard_path / "index.html"
240
250
  if index_file.exists():
251
+ self.logger.debug(f"Serving dashboard index from: {index_file}")
241
252
  return web.FileResponse(index_file)
242
253
  else:
254
+ self.logger.warning(f"Dashboard index.html not found at: {index_file}")
243
255
  return web.Response(text="Dashboard not available", status=404)
244
256
 
245
257
  self.app.router.add_get("/", index_handler)
@@ -252,10 +264,12 @@ class SocketIOServerCore:
252
264
  self.app.router.add_static(
253
265
  "/static/", dashboard_static_path, name="dashboard_static"
254
266
  )
267
+ self.logger.info(f"✅ Static assets available at: {dashboard_static_path}")
255
268
  else:
256
- self.logger.debug(f"Static assets directory not found at: {dashboard_static_path}")
269
+ self.logger.warning(f"⚠️ Static assets directory not found at: {dashboard_static_path}")
257
270
 
258
271
  else:
272
+ self.logger.warning("⚠️ No dashboard found, serving fallback response")
259
273
  # Fallback handler
260
274
  async def fallback_handler(request):
261
275
  return web.Response(
@@ -266,7 +280,10 @@ class SocketIOServerCore:
266
280
  self.app.router.add_get("/", fallback_handler)
267
281
 
268
282
  except Exception as e:
269
- self.logger.warning(f"Error setting up static files: {e}")
283
+ self.logger.error(f"Error setting up static files: {e}")
284
+ import traceback
285
+ self.logger.debug(f"Static file setup traceback: {traceback.format_exc()}")
286
+
270
287
  # Ensure we always have a basic handler
271
288
  async def error_handler(request):
272
289
  return web.Response(
@@ -281,40 +298,73 @@ class SocketIOServerCore:
281
298
  WHY: The static files location varies depending on how the application
282
299
  is installed and run. We try multiple common locations to find them.
283
300
  """
301
+ # Get deployment-context-aware paths
302
+ try:
303
+ from ....core.unified_paths import get_path_manager
304
+ path_manager = get_path_manager()
305
+
306
+ # Use package root for installed packages (including pipx)
307
+ package_root = path_manager.package_root
308
+ self.logger.debug(f"Package root: {package_root}")
309
+
310
+ # Use project root for development
311
+ project_root = get_project_root()
312
+ self.logger.debug(f"Project root: {project_root}")
313
+
314
+ except Exception as e:
315
+ self.logger.debug(f"Could not get path manager: {e}")
316
+ package_root = None
317
+ project_root = get_project_root()
318
+
284
319
  # Try multiple possible locations for static files and dashboard
285
320
  possible_paths = [
286
- # Dashboard template directory (primary location)
287
- get_project_root() / "src" / "claude_mpm" / "dashboard" / "templates",
288
- get_project_root() / "dashboard" / "templates",
289
- # Static file directories
290
- get_project_root() / "src" / "claude_mpm" / "services" / "static",
291
- get_project_root()
292
- / "src"
293
- / "claude_mpm"
294
- / "services"
295
- / "socketio"
296
- / "static",
297
- get_project_root() / "static",
298
- get_project_root() / "src" / "static",
299
- # Package installation locations
321
+ # Package-based paths (for pipx and pip installations)
322
+ package_root / "dashboard" / "templates" if package_root else None,
323
+ package_root / "services" / "socketio" / "static" if package_root else None,
324
+ package_root / "static" if package_root else None,
325
+
326
+ # Project-based paths (for development)
327
+ project_root / "src" / "claude_mpm" / "dashboard" / "templates",
328
+ project_root / "dashboard" / "templates",
329
+ project_root / "src" / "claude_mpm" / "services" / "static",
330
+ project_root / "src" / "claude_mpm" / "services" / "socketio" / "static",
331
+ project_root / "static",
332
+ project_root / "src" / "static",
333
+
334
+ # Package installation locations (fallback)
300
335
  Path(__file__).parent.parent / "static",
301
336
  Path(__file__).parent / "static",
337
+
302
338
  # Scripts directory (for standalone installations)
303
339
  get_scripts_dir() / "static",
304
340
  get_scripts_dir() / "socketio" / "static",
341
+
305
342
  # Current working directory
306
343
  Path.cwd() / "static",
307
344
  Path.cwd() / "socketio" / "static",
308
345
  ]
309
346
 
347
+ # Filter out None values
348
+ possible_paths = [p for p in possible_paths if p is not None]
349
+ self.logger.debug(f"Searching {len(possible_paths)} possible static file locations")
350
+
310
351
  for path in possible_paths:
311
- if path.exists() and path.is_dir():
312
- # Check if it contains expected files
313
- if (path / "index.html").exists():
314
- self.logger.debug(f"Found static files at: {path}")
315
- return path
352
+ self.logger.debug(f"Checking for static files at: {path}")
353
+ try:
354
+ if path.exists() and path.is_dir():
355
+ # Check if it contains expected files
356
+ if (path / "index.html").exists():
357
+ self.logger.info(f"✅ Found static files at: {path}")
358
+ return path
359
+ else:
360
+ self.logger.debug(f"Directory exists but no index.html: {path}")
361
+ else:
362
+ self.logger.debug(f"Path does not exist: {path}")
363
+ except Exception as e:
364
+ self.logger.debug(f"Error checking path {path}: {e}")
316
365
 
317
- self.logger.warning("Static files not found - dashboard will not be available")
366
+ self.logger.warning("⚠️ Static files not found - dashboard will not be available")
367
+ self.logger.debug(f"Searched paths: {[str(p) for p in possible_paths]}")
318
368
  return None
319
369
 
320
370
  def get_connection_count(self) -> int:
@@ -4,7 +4,7 @@ from pathlib import Path
4
4
  Claude Code Frontmatter Validator
5
5
 
6
6
  Validates agent frontmatter against Claude Code Desktop specification.
7
- Critical for ensuring agents work correctly with Claude Desktop.
7
+ Critical for ensuring agents work correctly with Claude Code.
8
8
  """
9
9
 
10
10
  import re
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-mpm
3
- Version: 4.0.28
3
+ Version: 4.0.30
4
4
  Summary: Claude Multi-Agent Project Manager - Orchestrate Claude with agent delegation and ticket tracking
5
5
  Author-email: Bob Matsuoka <bob@matsuoka.com>
6
6
  Maintainer: Claude MPM Team
@@ -146,6 +146,9 @@ claude-mpm run --monitor
146
146
  # Use MCP Gateway for external tool integration
147
147
  claude-mpm mcp
148
148
 
149
+ # Run health diagnostics
150
+ claude-mpm doctor
151
+
149
152
  # Manage memory for large conversation histories
150
153
  claude-mpm cleanup-memory
151
154
  ```