claude-mpm 4.14.7__py3-none-any.whl → 4.14.9__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.

Potentially problematic release.


This version of claude-mpm might be problematic. Click here for more details.

Files changed (79) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/agent_loader.py +13 -1
  3. claude_mpm/agents/frontmatter_validator.py +284 -253
  4. claude_mpm/cli/__init__.py +34 -740
  5. claude_mpm/cli/commands/agent_manager.py +25 -12
  6. claude_mpm/cli/commands/agent_state_manager.py +186 -0
  7. claude_mpm/cli/commands/agents.py +204 -148
  8. claude_mpm/cli/commands/aggregate.py +7 -3
  9. claude_mpm/cli/commands/analyze.py +9 -4
  10. claude_mpm/cli/commands/analyze_code.py +7 -2
  11. claude_mpm/cli/commands/config.py +47 -13
  12. claude_mpm/cli/commands/configure.py +159 -1801
  13. claude_mpm/cli/commands/configure_agent_display.py +261 -0
  14. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  15. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  16. claude_mpm/cli/commands/configure_models.py +18 -0
  17. claude_mpm/cli/commands/configure_navigation.py +165 -0
  18. claude_mpm/cli/commands/configure_paths.py +104 -0
  19. claude_mpm/cli/commands/configure_persistence.py +254 -0
  20. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  21. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  22. claude_mpm/cli/commands/configure_validators.py +73 -0
  23. claude_mpm/cli/commands/memory.py +54 -20
  24. claude_mpm/cli/commands/mpm_init.py +35 -21
  25. claude_mpm/cli/executor.py +202 -0
  26. claude_mpm/cli/helpers.py +105 -0
  27. claude_mpm/cli/shared/output_formatters.py +28 -19
  28. claude_mpm/cli/startup.py +455 -0
  29. claude_mpm/core/enums.py +399 -0
  30. claude_mpm/core/instruction_reinforcement_hook.py +2 -1
  31. claude_mpm/core/interactive_session.py +6 -3
  32. claude_mpm/core/logging_config.py +6 -2
  33. claude_mpm/core/oneshot_session.py +8 -4
  34. claude_mpm/core/service_registry.py +5 -1
  35. claude_mpm/core/typing_utils.py +7 -6
  36. claude_mpm/hooks/instruction_reinforcement.py +7 -2
  37. claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
  38. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +3 -2
  39. claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
  40. claude_mpm/services/diagnostics/checks/installation_check.py +3 -2
  41. claude_mpm/services/diagnostics/checks/mcp_check.py +20 -6
  42. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +8 -7
  43. claude_mpm/services/memory_hook_service.py +4 -1
  44. claude_mpm/services/monitor/daemon_manager.py +3 -2
  45. claude_mpm/services/monitor/handlers/dashboard.py +2 -1
  46. claude_mpm/services/monitor/handlers/hooks.py +2 -1
  47. claude_mpm/services/monitor/management/lifecycle.py +3 -2
  48. claude_mpm/services/monitor/server.py +2 -1
  49. claude_mpm/services/session_management_service.py +3 -2
  50. claude_mpm/services/socketio/handlers/hook.py +3 -2
  51. claude_mpm/services/socketio/server/main.py +3 -1
  52. claude_mpm/services/subprocess_launcher_service.py +14 -5
  53. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +6 -5
  54. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +6 -5
  55. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +8 -7
  56. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +5 -4
  57. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +5 -4
  58. claude_mpm/services/unified/config_strategies/validation_strategy.py +13 -9
  59. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +10 -3
  60. claude_mpm/services/unified/deployment_strategies/local.py +3 -2
  61. claude_mpm/services/unified/deployment_strategies/utils.py +2 -1
  62. claude_mpm/services/unified/deployment_strategies/vercel.py +2 -1
  63. claude_mpm/services/unified/interfaces.py +3 -1
  64. claude_mpm/services/unified/unified_analyzer.py +7 -6
  65. claude_mpm/services/unified/unified_config.py +2 -1
  66. claude_mpm/services/unified/unified_deployment.py +7 -2
  67. claude_mpm/tools/code_tree_analyzer.py +177 -141
  68. claude_mpm/tools/code_tree_events.py +4 -2
  69. {claude_mpm-4.14.7.dist-info → claude_mpm-4.14.9.dist-info}/METADATA +1 -1
  70. {claude_mpm-4.14.7.dist-info → claude_mpm-4.14.9.dist-info}/RECORD +74 -64
  71. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
  72. claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1041
  73. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
  74. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
  75. claude_mpm/services/project/analyzer_refactored.py +0 -450
  76. {claude_mpm-4.14.7.dist-info → claude_mpm-4.14.9.dist-info}/WHEEL +0 -0
  77. {claude_mpm-4.14.7.dist-info → claude_mpm-4.14.9.dist-info}/entry_points.txt +0 -0
  78. {claude_mpm-4.14.7.dist-info → claude_mpm-4.14.9.dist-info}/licenses/LICENSE +0 -0
  79. {claude_mpm-4.14.7.dist-info → claude_mpm-4.14.9.dist-info}/top_level.txt +0 -0
@@ -25,6 +25,7 @@ import logging
25
25
  from typing import Any, ClassVar, Dict, List, Optional, Tuple
26
26
 
27
27
  from claude_mpm.core.config import Config
28
+ from claude_mpm.core.enums import OperationResult
28
29
  from claude_mpm.core.interfaces import MemoryServiceInterface
29
30
  from claude_mpm.core.unified_paths import get_path_manager
30
31
 
@@ -596,9 +597,10 @@ class AgentMemoryManager(MemoryServiceInterface):
596
597
  """
597
598
  # Deprecated - return informative message
598
599
  return {
599
- "status": "deprecated",
600
+ "status": OperationResult.ERROR, # Deprecated function - calling it is an error
600
601
  "message": "Cross-reference analysis has been deprecated in favor of simplified memory management",
601
602
  "suggestion": "Use get_memory_status() for memory overview",
603
+ "deprecated": True,
602
604
  }
603
605
 
604
606
  def get_all_memories_raw(self) -> Dict[str, Any]:
@@ -613,9 +615,10 @@ class AgentMemoryManager(MemoryServiceInterface):
613
615
  """
614
616
  # Deprecated - return informative message
615
617
  return {
616
- "status": "deprecated",
618
+ "status": OperationResult.ERROR, # Deprecated function - calling it is an error
617
619
  "message": "Raw memory access has been deprecated in favor of simplified memory management",
618
620
  "suggestion": "Use load_agent_memory() for specific agent memories",
621
+ "deprecated": True,
619
622
  }
620
623
 
621
624
  def _save_memory_file_wrapper(self, agent_id: str, content: str) -> bool:
@@ -11,6 +11,7 @@ import sys
11
11
  from pathlib import Path
12
12
  from typing import Optional
13
13
 
14
+ from ....core.enums import OperationResult
14
15
  from ..models import DiagnosticResult, DiagnosticStatus
15
16
  from .base_check import BaseDiagnosticCheck
16
17
 
@@ -418,7 +419,7 @@ class InstallationCheck(BaseDiagnosticCheck):
418
419
  message=f"Missing optional dependencies: {', '.join(warnings)}",
419
420
  details={
420
421
  "optional_missing": warnings,
421
- "status": "partial",
422
+ "status": OperationResult.PARTIAL,
422
423
  "installed": installed,
423
424
  "python_executable": sys.executable,
424
425
  "in_venv": in_venv,
@@ -429,7 +430,7 @@ class InstallationCheck(BaseDiagnosticCheck):
429
430
  status=DiagnosticStatus.OK,
430
431
  message="All dependencies installed",
431
432
  details={
432
- "status": "complete",
433
+ "status": OperationResult.COMPLETED,
433
434
  "installed": installed,
434
435
  "python_executable": sys.executable,
435
436
  "in_venv": in_venv,
@@ -9,6 +9,8 @@ import json
9
9
  import subprocess
10
10
  from pathlib import Path
11
11
 
12
+ from claude_mpm.core.enums import ServiceState
13
+
12
14
  from ..models import DiagnosticResult, DiagnosticStatus
13
15
  from .base_check import BaseDiagnosticCheck
14
16
 
@@ -226,18 +228,18 @@ class MCPCheck(BaseDiagnosticCheck):
226
228
  )
227
229
 
228
230
  if result.returncode == 0:
229
- if "running" in result.stdout.lower():
231
+ if ServiceState.RUNNING.value in result.stdout.lower():
230
232
  return DiagnosticResult(
231
233
  category="MCP Server Status",
232
234
  status=DiagnosticStatus.OK,
233
235
  message="MCP server is running",
234
- details={"running": True},
236
+ details={"running": True, "state": ServiceState.RUNNING},
235
237
  )
236
238
  return DiagnosticResult(
237
239
  category="MCP Server Status",
238
240
  status=DiagnosticStatus.WARNING,
239
241
  message="MCP server not running",
240
- details={"running": False},
242
+ details={"running": False, "state": ServiceState.STOPPED},
241
243
  fix_command="claude-mpm mcp start",
242
244
  fix_description="Start the MCP server",
243
245
  )
@@ -245,7 +247,11 @@ class MCPCheck(BaseDiagnosticCheck):
245
247
  category="MCP Server Status",
246
248
  status=DiagnosticStatus.WARNING,
247
249
  message="Could not determine server status",
248
- details={"running": "unknown", "error": result.stderr},
250
+ details={
251
+ "running": "unknown",
252
+ "state": ServiceState.UNKNOWN,
253
+ "error": result.stderr,
254
+ },
249
255
  )
250
256
 
251
257
  except subprocess.TimeoutExpired:
@@ -253,14 +259,22 @@ class MCPCheck(BaseDiagnosticCheck):
253
259
  category="MCP Server Status",
254
260
  status=DiagnosticStatus.WARNING,
255
261
  message="Server status check timed out",
256
- details={"running": "unknown", "error": "timeout"},
262
+ details={
263
+ "running": "unknown",
264
+ "state": ServiceState.UNKNOWN,
265
+ "error": "timeout",
266
+ },
257
267
  )
258
268
  except Exception as e:
259
269
  return DiagnosticResult(
260
270
  category="MCP Server Status",
261
271
  status=DiagnosticStatus.WARNING,
262
272
  message=f"Could not check server status: {e!s}",
263
- details={"running": "unknown", "error": str(e)},
273
+ details={
274
+ "running": "unknown",
275
+ "state": ServiceState.UNKNOWN,
276
+ "error": str(e),
277
+ },
264
278
  )
265
279
 
266
280
  def _check_startup_verification(self) -> DiagnosticResult:
@@ -26,6 +26,7 @@ from typing import Any, Dict
26
26
  import psutil
27
27
 
28
28
  from claude_mpm.config.paths import paths
29
+ from claude_mpm.core.enums import OperationResult, ServiceState
29
30
  from claude_mpm.core.logger import get_logger
30
31
  from claude_mpm.services.mcp_gateway.core.interfaces import (
31
32
  MCPToolDefinition,
@@ -168,20 +169,20 @@ class HealthCheckTool(BaseToolAdapter):
168
169
  if i < len(check_results):
169
170
  if isinstance(check_results[i], Exception):
170
171
  results["checks"][check_name] = {
171
- "status": "error",
172
+ "status": OperationResult.ERROR,
172
173
  "error": str(check_results[i]),
173
174
  }
174
175
  else:
175
176
  results["checks"][check_name] = check_results[i]
176
177
  else:
177
178
  results["checks"][check_name] = {
178
- "status": "timeout",
179
+ "status": OperationResult.TIMEOUT,
179
180
  "error": "Check timed out",
180
181
  }
181
182
 
182
183
  except asyncio.TimeoutError:
183
184
  results["checks"]["timeout"] = {
184
- "status": "error",
185
+ "status": OperationResult.ERROR,
185
186
  "error": f"Health checks timed out after {timeout} seconds",
186
187
  }
187
188
 
@@ -194,7 +195,7 @@ class HealthCheckTool(BaseToolAdapter):
194
195
  async def _check_system_health(self, detailed: bool) -> Dict[str, Any]:
195
196
  """Check system health (CPU, memory, disk, etc.)."""
196
197
  check_result = {
197
- "status": "healthy",
198
+ "status": ServiceState.RUNNING,
198
199
  "checks": {},
199
200
  "warnings": [],
200
201
  "errors": [],
@@ -270,7 +271,7 @@ class HealthCheckTool(BaseToolAdapter):
270
271
  async def _check_gateway_health(self, detailed: bool) -> Dict[str, Any]:
271
272
  """Check MCP Gateway health."""
272
273
  check_result = {
273
- "status": "healthy",
274
+ "status": ServiceState.RUNNING,
274
275
  "checks": {},
275
276
  "warnings": [],
276
277
  "errors": [],
@@ -313,7 +314,7 @@ class HealthCheckTool(BaseToolAdapter):
313
314
  async def _check_tools_health(self, detailed: bool) -> Dict[str, Any]:
314
315
  """Check MCP tools health."""
315
316
  check_result = {
316
- "status": "healthy",
317
+ "status": ServiceState.RUNNING,
317
318
  "checks": {},
318
319
  "warnings": [],
319
320
  "errors": [],
@@ -365,7 +366,7 @@ class HealthCheckTool(BaseToolAdapter):
365
366
  async def _check_config_health(self, detailed: bool) -> Dict[str, Any]:
366
367
  """Check configuration health."""
367
368
  check_result = {
368
- "status": "healthy",
369
+ "status": ServiceState.RUNNING,
369
370
  "checks": {},
370
371
  "warnings": [],
371
372
  "errors": [],
@@ -11,6 +11,7 @@ Extracted from ClaudeRunner to follow Single Responsibility Principle.
11
11
  from typing import Any, Dict
12
12
 
13
13
  from claude_mpm.core.base_service import BaseService
14
+ from claude_mpm.core.enums import ServiceState
14
15
  from claude_mpm.services.core.interfaces import MemoryHookInterface
15
16
 
16
17
 
@@ -463,5 +464,7 @@ class MemoryHookService(BaseService, MemoryHookInterface):
463
464
  "hook_service_available": self.hook_service is not None,
464
465
  "memory_enabled": self.is_memory_enabled(),
465
466
  "total_hooks": len(self.registered_hooks),
466
- "status": "active" if self.registered_hooks else "inactive",
467
+ "status": (
468
+ ServiceState.RUNNING if self.registered_hooks else ServiceState.IDLE
469
+ ),
467
470
  }
@@ -31,6 +31,7 @@ import time
31
31
  from pathlib import Path
32
32
  from typing import Optional, Tuple
33
33
 
34
+ from ...core.enums import OperationResult
34
35
  from ...core.logging_config import get_logger
35
36
 
36
37
 
@@ -906,7 +907,7 @@ class DaemonManager:
906
907
  with self.startup_status_file.open() as f:
907
908
  status = f.read().strip()
908
909
 
909
- if status == "success":
910
+ if status == OperationResult.SUCCESS:
910
911
  # Cleanup status file
911
912
  Path(self.startup_status_file).unlink(missing_ok=True)
912
913
  return True
@@ -936,7 +937,7 @@ class DaemonManager:
936
937
  # Don't check if file exists - we need to write to it regardless
937
938
  # The parent created it and is waiting for us to update it
938
939
  with self.startup_status_file.open("w") as f:
939
- f.write("success")
940
+ f.write(OperationResult.SUCCESS)
940
941
  f.flush() # Ensure it's written immediately
941
942
  os.fsync(f.fileno()) # Force write to disk
942
943
  except Exception:
@@ -18,6 +18,7 @@ from typing import Dict, Set
18
18
 
19
19
  import socketio
20
20
 
21
+ from ....core.enums import ServiceState
21
22
  from ....core.logging_config import get_logger
22
23
 
23
24
 
@@ -128,7 +129,7 @@ class DashboardHandler:
128
129
  try:
129
130
  status = {
130
131
  "service": "unified-monitor",
131
- "status": "running",
132
+ "status": ServiceState.RUNNING,
132
133
  "clients_connected": len(self.connected_clients),
133
134
  "uptime": asyncio.get_event_loop().time(),
134
135
  "features": {
@@ -19,6 +19,7 @@ from typing import Dict, List
19
19
 
20
20
  import socketio
21
21
 
22
+ from ....core.enums import ServiceState
22
23
  from ....core.logging_config import get_logger
23
24
 
24
25
 
@@ -170,7 +171,7 @@ class HookHandler:
170
171
  session_info = {
171
172
  "session_id": session_id,
172
173
  "start_time": asyncio.get_event_loop().time(),
173
- "status": "active",
174
+ "status": ServiceState.RUNNING,
174
175
  "event_count": 0,
175
176
  "last_activity": asyncio.get_event_loop().time(),
176
177
  "metadata": data.get("metadata", {}),
@@ -23,6 +23,7 @@ import time
23
23
  from pathlib import Path
24
24
  from typing import Optional, Tuple
25
25
 
26
+ from ....core.enums import OperationResult
26
27
  from ....core.logging_config import get_logger
27
28
 
28
29
 
@@ -388,7 +389,7 @@ class DaemonLifecycle:
388
389
  with self.startup_status_file.open() as f:
389
390
  status = f.read().strip()
390
391
 
391
- if status == "success":
392
+ if status == OperationResult.SUCCESS:
392
393
  # Child started successfully
393
394
  self._cleanup_status_file()
394
395
  return True
@@ -438,7 +439,7 @@ class DaemonLifecycle:
438
439
  if self.startup_status_file:
439
440
  try:
440
441
  with self.startup_status_file.open("w") as f:
441
- f.write("success")
442
+ f.write(OperationResult.SUCCESS)
442
443
  except Exception as e:
443
444
  self.logger.error(f"Failed to report startup success: {e}")
444
445
 
@@ -26,6 +26,7 @@ from typing import Dict, Optional
26
26
  import socketio
27
27
  from aiohttp import web
28
28
 
29
+ from ...core.enums import ServiceState
29
30
  from ...core.logging_config import get_logger
30
31
  from ...dashboard.api.simple_directory import list_directory
31
32
  from .event_emitter import get_event_emitter
@@ -333,7 +334,7 @@ class UnifiedMonitorServer:
333
334
 
334
335
  return web.json_response(
335
336
  {
336
- "status": "healthy",
337
+ "status": ServiceState.RUNNING,
337
338
  "service": "claude-mpm-monitor", # Important: must match what is_our_service() checks
338
339
  "version": version,
339
340
  "port": self.port,
@@ -17,6 +17,7 @@ from datetime import timezone
17
17
  from typing import Any, Dict, List, Optional
18
18
 
19
19
  from claude_mpm.core.base_service import BaseService
20
+ from claude_mpm.core.enums import OperationResult, ServiceState
20
21
  from claude_mpm.services.core.interfaces import SessionManagementInterface
21
22
 
22
23
 
@@ -223,7 +224,7 @@ class SessionManagementService(BaseService, SessionManagementInterface):
223
224
  "id": session_id,
224
225
  "config": session_config,
225
226
  "start_time": time.time(),
226
- "status": "active",
227
+ "status": ServiceState.RUNNING,
227
228
  "type": session_config.get("type", "interactive"),
228
229
  }
229
230
 
@@ -267,7 +268,7 @@ class SessionManagementService(BaseService, SessionManagementInterface):
267
268
  return self.active_sessions[session_id].copy()
268
269
  return {
269
270
  "id": session_id,
270
- "status": "not_found",
271
+ "status": OperationResult.ERROR,
271
272
  "error": "Session not found",
272
273
  }
273
274
 
@@ -7,6 +7,7 @@ agent delegations, and other hook-based activity for the system heartbeat.
7
7
  from datetime import datetime, timezone
8
8
  from typing import Any, Dict
9
9
 
10
+ from ....core.enums import ServiceState
10
11
  from .base import BaseEventHandler
11
12
 
12
13
 
@@ -108,7 +109,7 @@ class HookEventHandler(BaseEventHandler):
108
109
  "session_id": session_id,
109
110
  "start_time": datetime.now(timezone.utc).isoformat(),
110
111
  "agent": agent_type,
111
- "status": "active",
112
+ "status": ServiceState.RUNNING,
112
113
  "prompt": data.get("prompt", "")[:100], # First 100 chars
113
114
  "last_activity": datetime.now(timezone.utc).isoformat(),
114
115
  }
@@ -159,7 +160,7 @@ class HookEventHandler(BaseEventHandler):
159
160
  "session_id": session_id,
160
161
  "start_time": datetime.now(timezone.utc).isoformat(),
161
162
  "agent": "pm", # Default to PM
162
- "status": "active",
163
+ "status": ServiceState.RUNNING,
163
164
  "prompt": data.get("prompt_text", "")[:100],
164
165
  "working_directory": data.get("working_directory", ""),
165
166
  "last_activity": datetime.now(timezone.utc).isoformat(),
@@ -16,6 +16,8 @@ from collections import deque
16
16
  from datetime import datetime, timezone
17
17
  from typing import Any, Dict, List, Optional, Set
18
18
 
19
+ from ....core.enums import ServiceState
20
+
19
21
  try:
20
22
  import aiohttp
21
23
  import socketio
@@ -384,7 +386,7 @@ class SocketIOServer(SocketIOServiceInterface):
384
386
  "session_id": session_id,
385
387
  "start_time": datetime.now(timezone.utc).isoformat(),
386
388
  "agent": "pm", # Default to PM, will be updated if delegated
387
- "status": "active",
389
+ "status": ServiceState.RUNNING,
388
390
  "launch_method": launch_method,
389
391
  "working_dir": working_dir,
390
392
  }
@@ -22,6 +22,7 @@ import tty
22
22
  from typing import Any, Dict, List, Optional
23
23
 
24
24
  from claude_mpm.core.base_service import BaseService
25
+ from claude_mpm.core.enums import OperationResult, ServiceState
25
26
  from claude_mpm.services.core.interfaces import SubprocessLauncherInterface
26
27
 
27
28
 
@@ -62,9 +63,17 @@ class SubprocessLauncherService(BaseService, SubprocessLauncherInterface):
62
63
  try:
63
64
  env = kwargs.get("env", self.prepare_subprocess_environment())
64
65
  self.launch_subprocess_interactive(command, env)
65
- return {"status": "launched", "command": command, "method": "interactive"}
66
+ return {
67
+ "status": OperationResult.SUCCESS,
68
+ "command": command,
69
+ "method": "interactive",
70
+ }
66
71
  except Exception as e:
67
- return {"status": "failed", "error": str(e), "command": command}
72
+ return {
73
+ "status": OperationResult.FAILED,
74
+ "error": str(e),
75
+ "command": command,
76
+ }
68
77
 
69
78
  async def launch_subprocess_async(
70
79
  self, command: List[str], **kwargs
@@ -109,7 +118,7 @@ class SubprocessLauncherService(BaseService, SubprocessLauncherInterface):
109
118
  # For now, return unknown status
110
119
  return {
111
120
  "process_id": process_id,
112
- "status": "unknown",
121
+ "status": OperationResult.UNKNOWN,
113
122
  "message": "Process tracking not implemented",
114
123
  }
115
124
 
@@ -160,7 +169,7 @@ class SubprocessLauncherService(BaseService, SubprocessLauncherInterface):
160
169
  # Notify WebSocket clients
161
170
  if self.websocket_server:
162
171
  self.websocket_server.claude_status_changed(
163
- status="running",
172
+ status=ServiceState.RUNNING,
164
173
  pid=process.pid,
165
174
  message="Claude subprocess started",
166
175
  )
@@ -195,7 +204,7 @@ class SubprocessLauncherService(BaseService, SubprocessLauncherInterface):
195
204
  # Notify WebSocket clients
196
205
  if self.websocket_server:
197
206
  self.websocket_server.claude_status_changed(
198
- status="stopped",
207
+ status=ServiceState.STOPPED,
199
208
  message=f"Claude subprocess exited with code {process.returncode}",
200
209
  )
201
210
 
@@ -14,6 +14,7 @@ import re
14
14
  from pathlib import Path
15
15
  from typing import Any, Dict, List, Optional
16
16
 
17
+ from claude_mpm.core.enums import OperationResult
17
18
  from claude_mpm.core.logging_utils import get_logger
18
19
 
19
20
  from ..strategies import (
@@ -120,7 +121,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
120
121
  return self._analyze_ast(target, options)
121
122
 
122
123
  return {
123
- "status": "error",
124
+ "status": OperationResult.ERROR,
124
125
  "message": f"Unsupported target type: {type(target).__name__}",
125
126
  }
126
127
 
@@ -159,7 +160,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
159
160
  metrics["maintainability_index"] = self._calculate_maintainability(metrics)
160
161
 
161
162
  return {
162
- "status": "success",
163
+ "status": OperationResult.SUCCESS,
163
164
  "type": "file",
164
165
  "path": str(file_path),
165
166
  "metrics": metrics,
@@ -168,7 +169,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
168
169
  except Exception as e:
169
170
  logger.error(f"Error analyzing file {file_path}: {e}")
170
171
  return {
171
- "status": "error",
172
+ "status": OperationResult.ERROR,
172
173
  "path": str(file_path),
173
174
  "error": str(e),
174
175
  }
@@ -178,7 +179,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
178
179
  ) -> Dict[str, Any]:
179
180
  """Analyze all code files in a directory."""
180
181
  results = {
181
- "status": "success",
182
+ "status": OperationResult.SUCCESS,
182
183
  "type": "directory",
183
184
  "path": str(dir_path),
184
185
  "files": [],
@@ -285,7 +286,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
285
286
  )
286
287
 
287
288
  return {
288
- "status": "success",
289
+ "status": OperationResult.SUCCESS,
289
290
  "type": "ast",
290
291
  "metrics": metrics,
291
292
  }
@@ -14,6 +14,7 @@ import re
14
14
  from pathlib import Path
15
15
  from typing import Any, ClassVar, Dict, List, Optional
16
16
 
17
+ from claude_mpm.core.enums import OperationResult
17
18
  from claude_mpm.core.logging_utils import get_logger
18
19
 
19
20
  from ..strategies import (
@@ -166,7 +167,7 @@ class DependencyAnalyzerStrategy(AnalyzerStrategy):
166
167
  return self._analyze_manifest(target_path, options)
167
168
 
168
169
  return {
169
- "status": "error",
170
+ "status": OperationResult.ERROR,
170
171
  "message": f"Unsupported target type: {type(target).__name__}",
171
172
  }
172
173
 
@@ -175,7 +176,7 @@ class DependencyAnalyzerStrategy(AnalyzerStrategy):
175
176
  ) -> Dict[str, Any]:
176
177
  """Analyze dependencies in a project directory."""
177
178
  results = {
178
- "status": "success",
179
+ "status": OperationResult.SUCCESS,
179
180
  "type": "project",
180
181
  "path": str(project_path),
181
182
  "package_managers": [],
@@ -221,7 +222,7 @@ class DependencyAnalyzerStrategy(AnalyzerStrategy):
221
222
  ) -> Dict[str, Any]:
222
223
  """Analyze a specific package manifest file."""
223
224
  results = {
224
- "status": "success",
225
+ "status": OperationResult.SUCCESS,
225
226
  "type": "manifest",
226
227
  "path": str(manifest_path),
227
228
  "dependencies": {},
@@ -238,7 +239,7 @@ class DependencyAnalyzerStrategy(AnalyzerStrategy):
238
239
 
239
240
  if not manager:
240
241
  return {
241
- "status": "error",
242
+ "status": OperationResult.ERROR,
242
243
  "message": f"Unknown manifest file: {manifest_path.name}",
243
244
  }
244
245
 
@@ -598,7 +599,7 @@ class DependencyAnalyzerStrategy(AnalyzerStrategy):
598
599
  """Extract key metrics from analysis results."""
599
600
  metrics = {}
600
601
 
601
- if analysis_result.get("status") != "success":
602
+ if analysis_result.get("status") != OperationResult.SUCCESS:
602
603
  return metrics
603
604
 
604
605
  # Extract dependency counts
@@ -14,6 +14,7 @@ import re
14
14
  from pathlib import Path
15
15
  from typing import Any, ClassVar, Dict, List, Optional
16
16
 
17
+ from claude_mpm.core.enums import OperationResult
17
18
  from claude_mpm.core.logging_utils import get_logger
18
19
 
19
20
  from ..strategies import (
@@ -188,14 +189,14 @@ class PerformanceAnalyzerStrategy(AnalyzerStrategy):
188
189
  return self._analyze_ast_performance(target, options)
189
190
 
190
191
  return {
191
- "status": "error",
192
+ "status": OperationResult.ERROR,
192
193
  "message": f"Unsupported target type: {type(target).__name__}",
193
194
  }
194
195
 
195
196
  def _analyze_file(self, file_path: Path, options: Dict[str, Any]) -> Dict[str, Any]:
196
197
  """Analyze a single file for performance issues."""
197
198
  results = {
198
- "status": "success",
199
+ "status": OperationResult.SUCCESS,
199
200
  "type": "file",
200
201
  "path": str(file_path),
201
202
  "issues": [],
@@ -240,7 +241,7 @@ class PerformanceAnalyzerStrategy(AnalyzerStrategy):
240
241
 
241
242
  except Exception as e:
242
243
  logger.error(f"Error analyzing file {file_path}: {e}")
243
- results["status"] = "error"
244
+ results["status"] = OperationResult.ERROR
244
245
  results["error"] = str(e)
245
246
 
246
247
  return results
@@ -250,7 +251,7 @@ class PerformanceAnalyzerStrategy(AnalyzerStrategy):
250
251
  ) -> Dict[str, Any]:
251
252
  """Analyze all files in a directory for performance issues."""
252
253
  results = {
253
- "status": "success",
254
+ "status": OperationResult.SUCCESS,
254
255
  "type": "directory",
255
256
  "path": str(dir_path),
256
257
  "files_analyzed": 0,
@@ -291,7 +292,7 @@ class PerformanceAnalyzerStrategy(AnalyzerStrategy):
291
292
  continue
292
293
 
293
294
  file_result = self._analyze_file(file_path, options)
294
- if file_result["status"] == "success":
295
+ if file_result["status"] == OperationResult.SUCCESS:
295
296
  results["files_analyzed"] += 1
296
297
  total_score += file_result["performance_score"]
297
298
 
@@ -654,7 +655,7 @@ class PerformanceAnalyzerStrategy(AnalyzerStrategy):
654
655
  ) -> Dict[str, Any]:
655
656
  """Analyze performance of an AST node."""
656
657
  results = {
657
- "status": "success",
658
+ "status": OperationResult.SUCCESS,
658
659
  "type": "ast",
659
660
  "complexity": {},
660
661
  "issues": [],
@@ -802,7 +803,7 @@ class PerformanceAnalyzerStrategy(AnalyzerStrategy):
802
803
  """Extract key metrics from analysis results."""
803
804
  metrics = {}
804
805
 
805
- if analysis_result.get("status") != "success":
806
+ if analysis_result.get("status") != OperationResult.SUCCESS:
806
807
  return metrics
807
808
 
808
809
  if analysis_result.get("type") == "file":
@@ -14,6 +14,7 @@ import re
14
14
  from pathlib import Path
15
15
  from typing import Any, ClassVar, Dict, List, Optional
16
16
 
17
+ from claude_mpm.core.enums import OperationResult
17
18
  from claude_mpm.core.logging_utils import get_logger
18
19
 
19
20
  from ..strategies import (
@@ -198,14 +199,14 @@ class SecurityAnalyzerStrategy(AnalyzerStrategy):
198
199
  return self._analyze_directory(target_path, options)
199
200
 
200
201
  return {
201
- "status": "error",
202
+ "status": OperationResult.ERROR,
202
203
  "message": f"Unsupported target type: {type(target).__name__}",
203
204
  }
204
205
 
205
206
  def _analyze_file(self, file_path: Path, options: Dict[str, Any]) -> Dict[str, Any]:
206
207
  """Analyze a single file for security issues."""
207
208
  results = {
208
- "status": "success",
209
+ "status": OperationResult.SUCCESS,
209
210
  "type": "file",
210
211
  "path": str(file_path),
211
212
  "vulnerabilities": [],
@@ -241,7 +242,7 @@ class SecurityAnalyzerStrategy(AnalyzerStrategy):
241
242
 
242
243
  except Exception as e:
243
244
  logger.error(f"Error analyzing file {file_path}: {e}")
244
- results["status"] = "error"
245
+ results["status"] = OperationResult.ERROR
245
246
  results["error"] = str(e)
246
247
 
247
248
  return results
@@ -251,7 +252,7 @@ class SecurityAnalyzerStrategy(AnalyzerStrategy):
251
252
  ) -> Dict[str, Any]:
252
253
  """Analyze all files in a directory for security issues."""
253
254
  results = {
254
- "status": "success",
255
+ "status": OperationResult.SUCCESS,
255
256
  "type": "directory",
256
257
  "path": str(dir_path),
257
258
  "files_analyzed": 0,