claude-mpm 4.1.7__py3-none-any.whl → 4.1.10__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 (109) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/INSTRUCTIONS.md +26 -1
  3. claude_mpm/agents/OUTPUT_STYLE.md +73 -0
  4. claude_mpm/agents/agents_metadata.py +57 -0
  5. claude_mpm/agents/templates/.claude-mpm/memories/README.md +17 -0
  6. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +3 -0
  7. claude_mpm/agents/templates/agent-manager.json +263 -17
  8. claude_mpm/agents/templates/agent-manager.md +248 -10
  9. claude_mpm/agents/templates/agentic_coder_optimizer.json +222 -0
  10. claude_mpm/agents/templates/code_analyzer.json +18 -8
  11. claude_mpm/agents/templates/engineer.json +1 -1
  12. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +39 -0
  13. claude_mpm/agents/templates/qa.json +1 -1
  14. claude_mpm/agents/templates/research.json +1 -1
  15. claude_mpm/cli/__init__.py +4 -0
  16. claude_mpm/cli/commands/__init__.py +6 -0
  17. claude_mpm/cli/commands/analyze.py +547 -0
  18. claude_mpm/cli/commands/analyze_code.py +524 -0
  19. claude_mpm/cli/commands/configure.py +223 -25
  20. claude_mpm/cli/commands/configure_tui.py +65 -61
  21. claude_mpm/cli/commands/debug.py +1387 -0
  22. claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
  23. claude_mpm/cli/parsers/analyze_parser.py +135 -0
  24. claude_mpm/cli/parsers/base_parser.py +29 -0
  25. claude_mpm/cli/parsers/configure_parser.py +23 -0
  26. claude_mpm/cli/parsers/debug_parser.py +319 -0
  27. claude_mpm/config/socketio_config.py +21 -21
  28. claude_mpm/constants.py +3 -1
  29. claude_mpm/core/framework_loader.py +148 -6
  30. claude_mpm/core/log_manager.py +16 -13
  31. claude_mpm/core/logger.py +1 -1
  32. claude_mpm/core/unified_agent_registry.py +1 -1
  33. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +1 -0
  34. claude_mpm/dashboard/analysis_runner.py +428 -0
  35. claude_mpm/dashboard/static/built/components/activity-tree.js +2 -0
  36. claude_mpm/dashboard/static/built/components/agent-inference.js +1 -1
  37. claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
  38. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +1 -1
  39. claude_mpm/dashboard/static/built/components/module-viewer.js +1 -1
  40. claude_mpm/dashboard/static/built/components/session-manager.js +1 -1
  41. claude_mpm/dashboard/static/built/components/working-directory.js +1 -1
  42. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  43. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  44. claude_mpm/dashboard/static/css/activity.css +549 -0
  45. claude_mpm/dashboard/static/css/code-tree.css +846 -0
  46. claude_mpm/dashboard/static/css/dashboard.css +245 -0
  47. claude_mpm/dashboard/static/dist/components/activity-tree.js +2 -0
  48. claude_mpm/dashboard/static/dist/components/code-tree.js +2 -0
  49. claude_mpm/dashboard/static/dist/components/code-viewer.js +2 -0
  50. claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
  51. claude_mpm/dashboard/static/dist/components/session-manager.js +1 -1
  52. claude_mpm/dashboard/static/dist/components/working-directory.js +1 -1
  53. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  54. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  55. claude_mpm/dashboard/static/js/components/activity-tree.js +1139 -0
  56. claude_mpm/dashboard/static/js/components/code-tree.js +1357 -0
  57. claude_mpm/dashboard/static/js/components/code-viewer.js +480 -0
  58. claude_mpm/dashboard/static/js/components/event-viewer.js +11 -0
  59. claude_mpm/dashboard/static/js/components/session-manager.js +40 -4
  60. claude_mpm/dashboard/static/js/components/socket-manager.js +12 -0
  61. claude_mpm/dashboard/static/js/components/ui-state-manager.js +4 -0
  62. claude_mpm/dashboard/static/js/components/working-directory.js +17 -1
  63. claude_mpm/dashboard/static/js/dashboard.js +39 -0
  64. claude_mpm/dashboard/static/js/socket-client.js +414 -20
  65. claude_mpm/dashboard/templates/index.html +184 -4
  66. claude_mpm/hooks/claude_hooks/hook_handler.py +182 -5
  67. claude_mpm/hooks/claude_hooks/installer.py +728 -0
  68. claude_mpm/scripts/claude-hook-handler.sh +161 -0
  69. claude_mpm/scripts/socketio_daemon.py +121 -8
  70. claude_mpm/services/agents/deployment/agent_config_provider.py +127 -27
  71. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +2 -2
  72. claude_mpm/services/agents/deployment/agent_record_service.py +1 -2
  73. claude_mpm/services/agents/memory/memory_format_service.py +1 -5
  74. claude_mpm/services/cli/agent_cleanup_service.py +1 -2
  75. claude_mpm/services/cli/agent_dependency_service.py +1 -1
  76. claude_mpm/services/cli/agent_validation_service.py +3 -4
  77. claude_mpm/services/cli/dashboard_launcher.py +2 -3
  78. claude_mpm/services/cli/startup_checker.py +0 -10
  79. claude_mpm/services/core/cache_manager.py +1 -2
  80. claude_mpm/services/core/path_resolver.py +1 -4
  81. claude_mpm/services/core/service_container.py +2 -2
  82. claude_mpm/services/diagnostics/checks/instructions_check.py +2 -5
  83. claude_mpm/services/event_bus/direct_relay.py +98 -20
  84. claude_mpm/services/infrastructure/monitoring/__init__.py +11 -11
  85. claude_mpm/services/infrastructure/monitoring.py +11 -11
  86. claude_mpm/services/project/architecture_analyzer.py +1 -1
  87. claude_mpm/services/project/dependency_analyzer.py +4 -4
  88. claude_mpm/services/project/language_analyzer.py +3 -3
  89. claude_mpm/services/project/metrics_collector.py +3 -6
  90. claude_mpm/services/socketio/handlers/__init__.py +2 -0
  91. claude_mpm/services/socketio/handlers/code_analysis.py +170 -0
  92. claude_mpm/services/socketio/handlers/registry.py +2 -0
  93. claude_mpm/services/socketio/server/connection_manager.py +95 -65
  94. claude_mpm/services/socketio/server/core.py +125 -17
  95. claude_mpm/services/socketio/server/main.py +44 -5
  96. claude_mpm/services/visualization/__init__.py +19 -0
  97. claude_mpm/services/visualization/mermaid_generator.py +938 -0
  98. claude_mpm/tools/__main__.py +208 -0
  99. claude_mpm/tools/code_tree_analyzer.py +778 -0
  100. claude_mpm/tools/code_tree_builder.py +632 -0
  101. claude_mpm/tools/code_tree_events.py +318 -0
  102. claude_mpm/tools/socketio_debug.py +671 -0
  103. {claude_mpm-4.1.7.dist-info → claude_mpm-4.1.10.dist-info}/METADATA +1 -1
  104. {claude_mpm-4.1.7.dist-info → claude_mpm-4.1.10.dist-info}/RECORD +108 -77
  105. claude_mpm/agents/schema/agent_schema.json +0 -314
  106. {claude_mpm-4.1.7.dist-info → claude_mpm-4.1.10.dist-info}/WHEEL +0 -0
  107. {claude_mpm-4.1.7.dist-info → claude_mpm-4.1.10.dist-info}/entry_points.txt +0 -0
  108. {claude_mpm-4.1.7.dist-info → claude_mpm-4.1.10.dist-info}/licenses/LICENSE +0 -0
  109. {claude_mpm-4.1.7.dist-info → claude_mpm-4.1.10.dist-info}/top_level.txt +0 -0
@@ -35,7 +35,7 @@ class AgentConfig:
35
35
  """Simple agent configuration model."""
36
36
 
37
37
  def __init__(
38
- self, name: str, description: str = "", dependencies: List[str] = None
38
+ self, name: str, description: str = "", dependencies: Optional[List[str]] = None
39
39
  ):
40
40
  self.name = name
41
41
  self.description = description
@@ -107,7 +107,7 @@ class SimpleAgentManager:
107
107
 
108
108
  # Get metadata for display info
109
109
  metadata = template_data.get("metadata", {})
110
- name = metadata.get("name", agent_id)
110
+ metadata.get("name", agent_id)
111
111
  description = metadata.get(
112
112
  "description", "No description available"
113
113
  )
@@ -222,6 +222,16 @@ class ConfigureCommand(BaseCommand):
222
222
  if getattr(args, "version_info", False):
223
223
  return self._show_version_info()
224
224
 
225
+ # Handle hook installation
226
+ if getattr(args, "install_hooks", False):
227
+ return self._install_hooks(force=getattr(args, "force", False))
228
+
229
+ if getattr(args, "verify_hooks", False):
230
+ return self._verify_hooks()
231
+
232
+ if getattr(args, "uninstall_hooks", False):
233
+ return self._uninstall_hooks()
234
+
225
235
  # Handle direct navigation options
226
236
  if getattr(args, "agents", False):
227
237
  return self._run_agent_management()
@@ -566,16 +576,15 @@ class ConfigureCommand(BaseCommand):
566
576
  display_template = template.copy()
567
577
  if "instructions" in display_template and isinstance(
568
578
  display_template["instructions"], dict
579
+ ) and (
580
+ "custom_instructions" in display_template["instructions"]
581
+ and len(str(display_template["instructions"]["custom_instructions"]))
582
+ > 200
569
583
  ):
570
- if (
571
- "custom_instructions" in display_template["instructions"]
572
- and len(str(display_template["instructions"]["custom_instructions"]))
573
- > 200
574
- ):
575
- display_template["instructions"]["custom_instructions"] = (
576
- display_template["instructions"]["custom_instructions"][:200]
577
- + "..."
578
- )
584
+ display_template["instructions"]["custom_instructions"] = (
585
+ display_template["instructions"]["custom_instructions"][:200]
586
+ + "..."
587
+ )
579
588
 
580
589
  json_str = json.dumps(display_template, indent=2)
581
590
  # Limit display to first 50 lines for readability
@@ -774,11 +783,10 @@ class ConfigureCommand(BaseCommand):
774
783
  config_dir.mkdir(parents=True, exist_ok=True)
775
784
  custom_path = config_dir / f"{agent.name}.json"
776
785
 
777
- if custom_path.exists():
778
- if not Confirm.ask(
779
- "[yellow]Custom template already exists. Overwrite?[/yellow]"
780
- ):
781
- return
786
+ if custom_path.exists() and not Confirm.ask(
787
+ "[yellow]Custom template already exists. Overwrite?[/yellow]"
788
+ ):
789
+ return
782
790
 
783
791
  # Save the template copy
784
792
  with open(custom_path, "w") as f:
@@ -1012,16 +1020,33 @@ class ConfigureCommand(BaseCommand):
1012
1020
  mpm_version = self.version_service.get_version()
1013
1021
  build_number = self.version_service.get_build_number()
1014
1022
 
1015
- # Try to get Claude Code version
1023
+ # Try to get Claude Code version using the installer's method
1016
1024
  claude_version = "Unknown"
1017
1025
  try:
1018
- import subprocess
1019
-
1020
- result = subprocess.run(
1021
- ["claude", "--version"], capture_output=True, text=True, timeout=5, check=False
1022
- )
1023
- if result.returncode == 0:
1024
- claude_version = result.stdout.strip()
1026
+ from ...hooks.claude_hooks.installer import HookInstaller
1027
+
1028
+ installer = HookInstaller()
1029
+ detected_version = installer.get_claude_version()
1030
+ if detected_version:
1031
+ is_compatible, _ = installer.is_version_compatible()
1032
+ claude_version = f"{detected_version} (Claude Code)"
1033
+ if not is_compatible:
1034
+ claude_version += (
1035
+ f" - Monitoring requires {installer.MIN_CLAUDE_VERSION}+"
1036
+ )
1037
+ else:
1038
+ # Fallback to direct subprocess call
1039
+ import subprocess
1040
+
1041
+ result = subprocess.run(
1042
+ ["claude", "--version"],
1043
+ capture_output=True,
1044
+ text=True,
1045
+ timeout=5,
1046
+ check=False,
1047
+ )
1048
+ if result.returncode == 0:
1049
+ claude_version = result.stdout.strip()
1025
1050
  except:
1026
1051
  pass
1027
1052
 
@@ -1157,7 +1182,11 @@ Directory: {self.project_dir}
1157
1182
  import subprocess
1158
1183
 
1159
1184
  result = subprocess.run(
1160
- ["claude", "--version"], capture_output=True, text=True, timeout=5, check=False
1185
+ ["claude", "--version"],
1186
+ capture_output=True,
1187
+ text=True,
1188
+ timeout=5,
1189
+ check=False,
1161
1190
  )
1162
1191
  if result.returncode == 0:
1163
1192
  data["claude_version"] = result.stdout.strip()
@@ -1175,6 +1204,175 @@ Directory: {self.project_dir}
1175
1204
 
1176
1205
  return CommandResult.success_result("Version information displayed", data=data)
1177
1206
 
1207
+ def _install_hooks(self, force: bool = False) -> CommandResult:
1208
+ """Install Claude MPM hooks for Claude Code integration."""
1209
+ try:
1210
+ from ...hooks.claude_hooks.installer import HookInstaller
1211
+
1212
+ installer = HookInstaller()
1213
+
1214
+ # Check Claude Code version compatibility first
1215
+ is_compatible, version_message = installer.is_version_compatible()
1216
+ self.console.print("[cyan]Checking Claude Code version...[/cyan]")
1217
+ self.console.print(version_message)
1218
+
1219
+ if not is_compatible:
1220
+ self.console.print(
1221
+ "\n[yellow]⚠ Hook monitoring is not available for your Claude Code version.[/yellow]"
1222
+ )
1223
+ self.console.print(
1224
+ "The dashboard and other features will work without real-time monitoring."
1225
+ )
1226
+ self.console.print(
1227
+ f"\n[dim]To enable monitoring, upgrade Claude Code to version {installer.MIN_CLAUDE_VERSION} or higher.[/dim]"
1228
+ )
1229
+ return CommandResult.success_result(
1230
+ "Version incompatible with hook monitoring",
1231
+ data={"compatible": False, "message": version_message},
1232
+ )
1233
+
1234
+ # Check current status
1235
+ status = installer.get_status()
1236
+ if status["installed"] and not force:
1237
+ self.console.print("[yellow]Hooks are already installed.[/yellow]")
1238
+ self.console.print("Use --force to reinstall.")
1239
+
1240
+ if not status["valid"]:
1241
+ self.console.print("\n[red]However, there are issues:[/red]")
1242
+ for issue in status["issues"]:
1243
+ self.console.print(f" - {issue}")
1244
+
1245
+ return CommandResult.success_result(
1246
+ "Hooks already installed", data=status
1247
+ )
1248
+
1249
+ # Install hooks
1250
+ self.console.print("[cyan]Installing Claude MPM hooks...[/cyan]")
1251
+ success = installer.install_hooks(force=force)
1252
+
1253
+ if success:
1254
+ self.console.print("[green]✓ Hooks installed successfully![/green]")
1255
+ self.console.print("\nYou can now use /mpm commands in Claude Code:")
1256
+ self.console.print(" /mpm - Show help")
1257
+ self.console.print(" /mpm status - Show claude-mpm status")
1258
+
1259
+ # Verify installation
1260
+ is_valid, issues = installer.verify_hooks()
1261
+ if not is_valid:
1262
+ self.console.print(
1263
+ "\n[yellow]Warning: Installation completed but verification found issues:[/yellow]"
1264
+ )
1265
+ for issue in issues:
1266
+ self.console.print(f" - {issue}")
1267
+
1268
+ return CommandResult.success_result("Hooks installed successfully")
1269
+ self.console.print("[red]✗ Hook installation failed[/red]")
1270
+ return CommandResult.error_result("Hook installation failed")
1271
+
1272
+ except ImportError:
1273
+ self.console.print("[red]Error: HookInstaller module not found[/red]")
1274
+ self.console.print("Please ensure claude-mpm is properly installed.")
1275
+ return CommandResult.error_result("HookInstaller module not found")
1276
+ except Exception as e:
1277
+ self.logger.error(f"Hook installation error: {e}", exc_info=True)
1278
+ return CommandResult.error_result(f"Hook installation failed: {e}")
1279
+
1280
+ def _verify_hooks(self) -> CommandResult:
1281
+ """Verify that Claude MPM hooks are properly installed."""
1282
+ try:
1283
+ from ...hooks.claude_hooks.installer import HookInstaller
1284
+
1285
+ installer = HookInstaller()
1286
+ status = installer.get_status()
1287
+
1288
+ self.console.print("[bold]Hook Installation Status[/bold]\n")
1289
+
1290
+ # Show Claude Code version and compatibility
1291
+ if status.get("claude_version"):
1292
+ self.console.print(f"Claude Code Version: {status['claude_version']}")
1293
+ if status.get("version_compatible"):
1294
+ self.console.print(
1295
+ "[green]✓[/green] Version compatible with hook monitoring"
1296
+ )
1297
+ else:
1298
+ self.console.print(
1299
+ f"[yellow]⚠[/yellow] {status.get('version_message', 'Version incompatible')}"
1300
+ )
1301
+ self.console.print()
1302
+ else:
1303
+ self.console.print(
1304
+ "[yellow]Claude Code version could not be detected[/yellow]"
1305
+ )
1306
+ self.console.print()
1307
+
1308
+ if status["installed"]:
1309
+ self.console.print(
1310
+ f"[green]✓[/green] Hooks installed at: {status['hook_script']}"
1311
+ )
1312
+ else:
1313
+ self.console.print("[red]✗[/red] Hooks not installed")
1314
+
1315
+ if status["settings_file"]:
1316
+ self.console.print(
1317
+ f"[green]✓[/green] Settings file: {status['settings_file']}"
1318
+ )
1319
+ else:
1320
+ self.console.print("[red]✗[/red] Settings file not found")
1321
+
1322
+ if status.get("configured_events"):
1323
+ self.console.print(
1324
+ f"[green]✓[/green] Configured events: {', '.join(status['configured_events'])}"
1325
+ )
1326
+ else:
1327
+ self.console.print("[red]✗[/red] No events configured")
1328
+
1329
+ if status["valid"]:
1330
+ self.console.print("\n[green]All checks passed![/green]")
1331
+ else:
1332
+ self.console.print("\n[red]Issues found:[/red]")
1333
+ for issue in status["issues"]:
1334
+ self.console.print(f" - {issue}")
1335
+
1336
+ return CommandResult.success_result(
1337
+ "Hook verification complete", data=status
1338
+ )
1339
+
1340
+ except ImportError:
1341
+ self.console.print("[red]Error: HookInstaller module not found[/red]")
1342
+ return CommandResult.error_result("HookInstaller module not found")
1343
+ except Exception as e:
1344
+ self.logger.error(f"Hook verification error: {e}", exc_info=True)
1345
+ return CommandResult.error_result(f"Hook verification failed: {e}")
1346
+
1347
+ def _uninstall_hooks(self) -> CommandResult:
1348
+ """Uninstall Claude MPM hooks."""
1349
+ try:
1350
+ from ...hooks.claude_hooks.installer import HookInstaller
1351
+
1352
+ installer = HookInstaller()
1353
+
1354
+ # Confirm uninstallation
1355
+ if not Confirm.ask(
1356
+ "[yellow]Are you sure you want to uninstall Claude MPM hooks?[/yellow]"
1357
+ ):
1358
+ return CommandResult.success_result("Uninstallation cancelled")
1359
+
1360
+ self.console.print("[cyan]Uninstalling Claude MPM hooks...[/cyan]")
1361
+ success = installer.uninstall_hooks()
1362
+
1363
+ if success:
1364
+ self.console.print("[green]✓ Hooks uninstalled successfully![/green]")
1365
+ return CommandResult.success_result("Hooks uninstalled successfully")
1366
+ self.console.print("[red]✗ Hook uninstallation failed[/red]")
1367
+ return CommandResult.error_result("Hook uninstallation failed")
1368
+
1369
+ except ImportError:
1370
+ self.console.print("[red]Error: HookInstaller module not found[/red]")
1371
+ return CommandResult.error_result("HookInstaller module not found")
1372
+ except Exception as e:
1373
+ self.logger.error(f"Hook uninstallation error: {e}", exc_info=True)
1374
+ return CommandResult.error_result(f"Hook uninstallation failed: {e}")
1375
+
1178
1376
  def _run_agent_management(self) -> CommandResult:
1179
1377
  """Jump directly to agent management."""
1180
1378
  try: