claude-mpm 4.1.8__py3-none-any.whl → 4.1.11__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 (111) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/INSTRUCTIONS.md +26 -1
  3. claude_mpm/agents/agents_metadata.py +57 -0
  4. claude_mpm/agents/templates/.claude-mpm/memories/README.md +17 -0
  5. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +3 -0
  6. claude_mpm/agents/templates/agent-manager.json +263 -17
  7. claude_mpm/agents/templates/agentic_coder_optimizer.json +222 -0
  8. claude_mpm/agents/templates/code_analyzer.json +18 -8
  9. claude_mpm/agents/templates/engineer.json +1 -1
  10. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +39 -0
  11. claude_mpm/agents/templates/qa.json +1 -1
  12. claude_mpm/agents/templates/research.json +1 -1
  13. claude_mpm/cli/__init__.py +15 -0
  14. claude_mpm/cli/commands/__init__.py +6 -0
  15. claude_mpm/cli/commands/analyze.py +548 -0
  16. claude_mpm/cli/commands/analyze_code.py +524 -0
  17. claude_mpm/cli/commands/configure.py +78 -28
  18. claude_mpm/cli/commands/configure_tui.py +62 -60
  19. claude_mpm/cli/commands/dashboard.py +288 -0
  20. claude_mpm/cli/commands/debug.py +1386 -0
  21. claude_mpm/cli/commands/mpm_init.py +427 -0
  22. claude_mpm/cli/commands/mpm_init_handler.py +83 -0
  23. claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
  24. claude_mpm/cli/parsers/analyze_parser.py +135 -0
  25. claude_mpm/cli/parsers/base_parser.py +44 -0
  26. claude_mpm/cli/parsers/dashboard_parser.py +113 -0
  27. claude_mpm/cli/parsers/debug_parser.py +319 -0
  28. claude_mpm/cli/parsers/mpm_init_parser.py +122 -0
  29. claude_mpm/constants.py +13 -1
  30. claude_mpm/core/framework_loader.py +148 -6
  31. claude_mpm/core/log_manager.py +16 -13
  32. claude_mpm/core/logger.py +1 -1
  33. claude_mpm/core/unified_agent_registry.py +1 -1
  34. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +1 -0
  35. claude_mpm/dashboard/analysis_runner.py +455 -0
  36. claude_mpm/dashboard/static/built/components/activity-tree.js +2 -0
  37. claude_mpm/dashboard/static/built/components/agent-inference.js +1 -1
  38. claude_mpm/dashboard/static/built/components/code-tree.js +2 -0
  39. claude_mpm/dashboard/static/built/components/code-viewer.js +2 -0
  40. claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
  41. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +1 -1
  42. claude_mpm/dashboard/static/built/components/module-viewer.js +1 -1
  43. claude_mpm/dashboard/static/built/components/session-manager.js +1 -1
  44. claude_mpm/dashboard/static/built/components/working-directory.js +1 -1
  45. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  46. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  47. claude_mpm/dashboard/static/css/activity.css +549 -0
  48. claude_mpm/dashboard/static/css/code-tree.css +1175 -0
  49. claude_mpm/dashboard/static/css/dashboard.css +245 -0
  50. claude_mpm/dashboard/static/dist/components/activity-tree.js +2 -0
  51. claude_mpm/dashboard/static/dist/components/code-tree.js +2 -0
  52. claude_mpm/dashboard/static/dist/components/code-viewer.js +2 -0
  53. claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
  54. claude_mpm/dashboard/static/dist/components/session-manager.js +1 -1
  55. claude_mpm/dashboard/static/dist/components/working-directory.js +1 -1
  56. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  57. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  58. claude_mpm/dashboard/static/js/components/activity-tree.js +1338 -0
  59. claude_mpm/dashboard/static/js/components/code-tree.js +2535 -0
  60. claude_mpm/dashboard/static/js/components/code-viewer.js +480 -0
  61. claude_mpm/dashboard/static/js/components/event-viewer.js +59 -9
  62. claude_mpm/dashboard/static/js/components/session-manager.js +40 -4
  63. claude_mpm/dashboard/static/js/components/socket-manager.js +12 -0
  64. claude_mpm/dashboard/static/js/components/ui-state-manager.js +4 -0
  65. claude_mpm/dashboard/static/js/components/working-directory.js +17 -1
  66. claude_mpm/dashboard/static/js/dashboard.js +51 -0
  67. claude_mpm/dashboard/static/js/socket-client.js +465 -29
  68. claude_mpm/dashboard/templates/index.html +182 -4
  69. claude_mpm/hooks/claude_hooks/hook_handler.py +182 -5
  70. claude_mpm/hooks/claude_hooks/installer.py +386 -113
  71. claude_mpm/scripts/claude-hook-handler.sh +161 -0
  72. claude_mpm/scripts/socketio_daemon.py +121 -8
  73. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +2 -2
  74. claude_mpm/services/agents/deployment/agent_record_service.py +1 -2
  75. claude_mpm/services/agents/memory/memory_format_service.py +1 -3
  76. claude_mpm/services/cli/agent_cleanup_service.py +1 -5
  77. claude_mpm/services/cli/agent_dependency_service.py +1 -1
  78. claude_mpm/services/cli/agent_validation_service.py +3 -4
  79. claude_mpm/services/cli/dashboard_launcher.py +2 -3
  80. claude_mpm/services/cli/startup_checker.py +0 -11
  81. claude_mpm/services/core/cache_manager.py +1 -3
  82. claude_mpm/services/core/path_resolver.py +1 -4
  83. claude_mpm/services/core/service_container.py +2 -2
  84. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  85. claude_mpm/services/infrastructure/monitoring/__init__.py +11 -11
  86. claude_mpm/services/infrastructure/monitoring.py +11 -11
  87. claude_mpm/services/project/architecture_analyzer.py +1 -1
  88. claude_mpm/services/project/dependency_analyzer.py +4 -4
  89. claude_mpm/services/project/language_analyzer.py +3 -3
  90. claude_mpm/services/project/metrics_collector.py +3 -6
  91. claude_mpm/services/socketio/event_normalizer.py +64 -0
  92. claude_mpm/services/socketio/handlers/__init__.py +2 -0
  93. claude_mpm/services/socketio/handlers/code_analysis.py +672 -0
  94. claude_mpm/services/socketio/handlers/registry.py +2 -0
  95. claude_mpm/services/socketio/server/connection_manager.py +6 -4
  96. claude_mpm/services/socketio/server/core.py +100 -11
  97. claude_mpm/services/socketio/server/main.py +8 -2
  98. claude_mpm/services/visualization/__init__.py +19 -0
  99. claude_mpm/services/visualization/mermaid_generator.py +938 -0
  100. claude_mpm/tools/__main__.py +208 -0
  101. claude_mpm/tools/code_tree_analyzer.py +1596 -0
  102. claude_mpm/tools/code_tree_builder.py +631 -0
  103. claude_mpm/tools/code_tree_events.py +416 -0
  104. claude_mpm/tools/socketio_debug.py +671 -0
  105. {claude_mpm-4.1.8.dist-info → claude_mpm-4.1.11.dist-info}/METADATA +2 -1
  106. {claude_mpm-4.1.8.dist-info → claude_mpm-4.1.11.dist-info}/RECORD +110 -74
  107. claude_mpm/agents/schema/agent_schema.json +0 -314
  108. {claude_mpm-4.1.8.dist-info → claude_mpm-4.1.11.dist-info}/WHEEL +0 -0
  109. {claude_mpm-4.1.8.dist-info → claude_mpm-4.1.11.dist-info}/entry_points.txt +0 -0
  110. {claude_mpm-4.1.8.dist-info → claude_mpm-4.1.11.dist-info}/licenses/LICENSE +0 -0
  111. {claude_mpm-4.1.8.dist-info → claude_mpm-4.1.11.dist-info}/top_level.txt +0 -0
@@ -10,6 +10,7 @@ of client states, proper event delivery, and automatic recovery mechanisms.
10
10
  """
11
11
 
12
12
  import asyncio
13
+ import contextlib
13
14
  import time
14
15
  from collections import deque
15
16
  from dataclasses import dataclass, field
@@ -148,7 +149,9 @@ class ConnectionManager:
148
149
  - Automatic event replay on reconnection
149
150
  """
150
151
 
151
- def __init__(self, max_buffer_size: int = None, event_ttl: int = None):
152
+ def __init__(
153
+ self, max_buffer_size: Optional[int] = None, event_ttl: Optional[int] = None
154
+ ):
152
155
  """
153
156
  Initialize connection manager with centralized configuration.
154
157
 
@@ -263,6 +266,7 @@ class ConnectionManager:
263
266
  )
264
267
  self.connections[sid] = conn
265
268
  return conn
269
+ return None
266
270
 
267
271
  def _create_new_connection(
268
272
  self, sid: str, client_id: str, now: float
@@ -434,10 +438,8 @@ class ConnectionManager:
434
438
  """Stop the health monitoring task."""
435
439
  if self.health_task:
436
440
  self.health_task.cancel()
437
- try:
441
+ with contextlib.suppress(asyncio.CancelledError):
438
442
  await self.health_task
439
- except asyncio.CancelledError:
440
- pass
441
443
  self.health_task = None
442
444
  self.logger.info("Stopped connection health monitoring")
443
445
 
@@ -273,24 +273,113 @@ class SocketIOServerCore:
273
273
  # Parse JSON payload
274
274
  event_data = await request.json()
275
275
 
276
- # Log receipt if debugging
277
- event_type = event_data.get("subtype", "unknown")
278
- self.logger.debug(f"Received HTTP event: {event_type}")
276
+ # Log receipt with more detail
277
+ event_type = (
278
+ event_data.get("subtype")
279
+ or event_data.get("hook_event_name")
280
+ or "unknown"
281
+ )
282
+ self.logger.info(f"📨 Received HTTP event: {event_type}")
283
+ self.logger.debug(f"Event data keys: {list(event_data.keys())}")
284
+ self.logger.debug(f"Connected clients: {len(self.connected_clients)}")
285
+
286
+ # Transform hook event format to claude_event format if needed
287
+ if "hook_event_name" in event_data and "event" not in event_data:
288
+ # This is a raw hook event, transform it
289
+ from claude_mpm.services.socketio.event_normalizer import (
290
+ EventNormalizer,
291
+ )
292
+
293
+ normalizer = EventNormalizer()
294
+
295
+ # Create the format expected by normalizer
296
+ raw_event = {
297
+ "type": "hook",
298
+ "subtype": event_data.get("hook_event_name", "unknown")
299
+ .lower()
300
+ .replace("submit", "")
301
+ .replace("use", "_use"),
302
+ "timestamp": event_data.get("timestamp"),
303
+ "data": event_data.get("hook_input_data", {}),
304
+ "source": "claude_hooks",
305
+ "session_id": event_data.get("session_id"),
306
+ }
307
+
308
+ # Map hook event names to dashboard subtypes
309
+ subtype_map = {
310
+ "UserPromptSubmit": "user_prompt",
311
+ "PreToolUse": "pre_tool",
312
+ "PostToolUse": "post_tool",
313
+ "Stop": "stop",
314
+ "SubagentStop": "subagent_stop",
315
+ "AssistantResponse": "assistant_response",
316
+ }
317
+ raw_event["subtype"] = subtype_map.get(
318
+ event_data.get("hook_event_name"), "unknown"
319
+ )
320
+
321
+ normalized = normalizer.normalize(raw_event, source="hook")
322
+ event_data = normalized.to_dict()
323
+ self.logger.debug(
324
+ f"Normalized event: type={event_data.get('type')}, subtype={event_data.get('subtype')}"
325
+ )
279
326
 
280
327
  # Broadcast to all connected dashboard clients via SocketIO
281
328
  if self.sio:
282
- # The event is already in claude_event format from the hook handler
283
- await self.sio.emit("claude_event", event_data)
329
+ # CRITICAL: Use the main server's broadcaster for proper event handling
330
+ # The broadcaster handles retries, connection management, and buffering
331
+ if (
332
+ self.main_server
333
+ and hasattr(self.main_server, "broadcaster")
334
+ and self.main_server.broadcaster
335
+ ):
336
+ # The broadcaster expects raw event data and will normalize it
337
+ # Since we already normalized it, we need to pass it in a way that won't double-normalize
338
+ # We'll emit directly through the broadcaster's sio with proper handling
339
+
340
+ # Add to event buffer and history
341
+ with self.buffer_lock:
342
+ self.event_buffer.append(event_data)
343
+ self.stats["events_buffered"] = len(self.event_buffer)
344
+
345
+ # Add to main server's event history
346
+ if hasattr(self.main_server, "event_history"):
347
+ self.main_server.event_history.append(event_data)
348
+
349
+ # Use the broadcaster's sio to emit (it's the same as self.sio)
350
+ # This ensures the event goes through the proper channels
351
+ await self.sio.emit("claude_event", event_data)
352
+
353
+ # Update broadcaster stats
354
+ if hasattr(self.main_server.broadcaster, "stats"):
355
+ self.main_server.broadcaster.stats["events_sent"] = (
356
+ self.main_server.broadcaster.stats.get("events_sent", 0)
357
+ + 1
358
+ )
359
+
360
+ self.logger.info(
361
+ f"✅ Event broadcasted: {event_data.get('subtype', 'unknown')} to {len(self.connected_clients)} clients"
362
+ )
363
+ self.logger.debug(
364
+ f"Connected client IDs: {list(self.connected_clients) if self.connected_clients else 'None'}"
365
+ )
366
+ else:
367
+ # Fallback: Direct emit if broadcaster not available (shouldn't happen)
368
+ self.logger.warning(
369
+ "Broadcaster not available, using direct emit"
370
+ )
371
+ await self.sio.emit("claude_event", event_data)
284
372
 
285
- # Update stats
286
- self.stats["events_sent"] = self.stats.get("events_sent", 0) + 1
373
+ # Update stats manually if using fallback
374
+ self.stats["events_sent"] = self.stats.get("events_sent", 0) + 1
287
375
 
288
- # Add to event buffer for late-joining clients
289
- with self.buffer_lock:
290
- self.event_buffer.append(event_data)
291
- self.stats["events_buffered"] = len(self.event_buffer)
376
+ # Add to event buffer for late-joining clients
377
+ with self.buffer_lock:
378
+ self.event_buffer.append(event_data)
379
+ self.stats["events_buffered"] = len(self.event_buffer)
292
380
 
293
381
  # Return 204 No Content for success
382
+ self.logger.debug(f"✅ HTTP event processed successfully: {event_type}")
294
383
  return web.Response(status=204)
295
384
 
296
385
  except Exception as e:
@@ -265,10 +265,16 @@ class SocketIOServer(SocketIOServiceInterface):
265
265
  except Exception as e:
266
266
  self.logger.error(f"Error during EventBus teardown: {e}")
267
267
 
268
- # Stop health monitoring in connection handler
268
+ # Stop code analysis handler
269
269
  if self.event_registry:
270
- from ..handlers import ConnectionEventHandler
270
+ from ..handlers import CodeAnalysisEventHandler, ConnectionEventHandler
271
271
 
272
+ # Stop analysis runner
273
+ analysis_handler = self.event_registry.get_handler(CodeAnalysisEventHandler)
274
+ if analysis_handler and hasattr(analysis_handler, "cleanup"):
275
+ analysis_handler.cleanup()
276
+
277
+ # Stop health monitoring in connection handler
272
278
  conn_handler = self.event_registry.get_handler(ConnectionEventHandler)
273
279
  if conn_handler and hasattr(conn_handler, "stop_health_monitoring"):
274
280
  conn_handler.stop_health_monitoring()
@@ -0,0 +1,19 @@
1
+ """
2
+ Visualization Services for Claude MPM
3
+ =====================================
4
+
5
+ This module provides visualization services for code analysis,
6
+ including Mermaid diagram generation for various code structures.
7
+ """
8
+
9
+ from .mermaid_generator import (
10
+ DiagramConfig,
11
+ DiagramType,
12
+ MermaidGeneratorService,
13
+ )
14
+
15
+ __all__ = [
16
+ "DiagramConfig",
17
+ "DiagramType",
18
+ "MermaidGeneratorService",
19
+ ]