claude-mpm 4.14.6__py3-none-any.whl → 4.14.8__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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/frontmatter_validator.py +284 -253
- claude_mpm/cli/__init__.py +34 -740
- claude_mpm/cli/commands/agent_manager.py +25 -12
- claude_mpm/cli/commands/agent_state_manager.py +186 -0
- claude_mpm/cli/commands/agents.py +204 -148
- claude_mpm/cli/commands/aggregate.py +7 -3
- claude_mpm/cli/commands/analyze.py +9 -4
- claude_mpm/cli/commands/analyze_code.py +7 -2
- claude_mpm/cli/commands/config.py +47 -13
- claude_mpm/cli/commands/configure.py +159 -1801
- claude_mpm/cli/commands/configure_agent_display.py +261 -0
- claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
- claude_mpm/cli/commands/configure_hook_manager.py +225 -0
- claude_mpm/cli/commands/configure_models.py +18 -0
- claude_mpm/cli/commands/configure_navigation.py +165 -0
- claude_mpm/cli/commands/configure_paths.py +104 -0
- claude_mpm/cli/commands/configure_persistence.py +254 -0
- claude_mpm/cli/commands/configure_startup_manager.py +646 -0
- claude_mpm/cli/commands/configure_template_editor.py +497 -0
- claude_mpm/cli/commands/configure_validators.py +73 -0
- claude_mpm/cli/commands/memory.py +54 -20
- claude_mpm/cli/commands/mpm_init.py +35 -21
- claude_mpm/cli/executor.py +202 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/shared/output_formatters.py +28 -19
- claude_mpm/cli/startup.py +455 -0
- claude_mpm/core/enums.py +322 -0
- claude_mpm/core/instruction_reinforcement_hook.py +2 -1
- claude_mpm/core/interactive_session.py +6 -3
- claude_mpm/core/logging_config.py +6 -2
- claude_mpm/core/oneshot_session.py +8 -4
- claude_mpm/core/output_style_manager.py +12 -192
- claude_mpm/core/service_registry.py +5 -1
- claude_mpm/core/typing_utils.py +7 -6
- claude_mpm/hooks/instruction_reinforcement.py +7 -2
- claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +3 -2
- claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
- claude_mpm/services/diagnostics/checks/installation_check.py +3 -2
- claude_mpm/services/diagnostics/checks/mcp_check.py +20 -6
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +8 -7
- claude_mpm/services/memory_hook_service.py +4 -1
- claude_mpm/services/monitor/daemon_manager.py +3 -2
- claude_mpm/services/monitor/handlers/dashboard.py +2 -1
- claude_mpm/services/monitor/handlers/hooks.py +2 -1
- claude_mpm/services/monitor/management/lifecycle.py +3 -2
- claude_mpm/services/monitor/server.py +2 -1
- claude_mpm/services/session_management_service.py +3 -2
- claude_mpm/services/socketio/handlers/hook.py +3 -2
- claude_mpm/services/socketio/server/main.py +3 -1
- claude_mpm/services/subprocess_launcher_service.py +14 -5
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +6 -5
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +5 -4
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +5 -4
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +4 -3
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +4 -3
- claude_mpm/services/unified/config_strategies/validation_strategy.py +13 -9
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +10 -3
- claude_mpm/services/unified/deployment_strategies/local.py +3 -2
- claude_mpm/services/unified/deployment_strategies/utils.py +2 -1
- claude_mpm/services/unified/deployment_strategies/vercel.py +2 -1
- claude_mpm/services/unified/interfaces.py +3 -1
- claude_mpm/services/unified/unified_analyzer.py +7 -6
- claude_mpm/services/unified/unified_config.py +2 -1
- claude_mpm/services/unified/unified_deployment.py +7 -2
- claude_mpm/tools/code_tree_analyzer.py +177 -141
- claude_mpm/tools/code_tree_events.py +4 -2
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.14.8.dist-info}/METADATA +1 -1
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.14.8.dist-info}/RECORD +74 -64
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
- claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1041
- claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
- claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
- claude_mpm/services/project/analyzer_refactored.py +0 -450
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.14.8.dist-info}/WHEEL +0 -0
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.14.8.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.14.8.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.14.8.dist-info}/top_level.txt +0 -0
claude_mpm/core/typing_utils.py
CHANGED
|
@@ -32,6 +32,8 @@ from typing import (
|
|
|
32
32
|
|
|
33
33
|
from typing_extensions import NotRequired, TypeAlias, TypedDict
|
|
34
34
|
|
|
35
|
+
from claude_mpm.core.enums import OperationResult, ServiceState
|
|
36
|
+
|
|
35
37
|
# Generic type variables
|
|
36
38
|
T = TypeVar("T")
|
|
37
39
|
TSession = TypeVar("TSession") # Generic session type
|
|
@@ -42,15 +44,14 @@ TService = TypeVar("TService") # Generic service type
|
|
|
42
44
|
PathLike: TypeAlias = Union[str, Path]
|
|
43
45
|
JSONValue: TypeAlias = Union[str, int, float, bool, None, Dict[str, Any], List[Any]]
|
|
44
46
|
JSONDict: TypeAlias = Dict[str, JSONValue]
|
|
47
|
+
|
|
45
48
|
Headers: TypeAlias = Dict[str, str]
|
|
46
49
|
ErrorCode: TypeAlias = Union[int, str]
|
|
47
50
|
LogLevel: TypeAlias = Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
|
48
51
|
|
|
49
52
|
# Session types
|
|
50
53
|
SessionId: TypeAlias = str
|
|
51
|
-
SessionStatus: TypeAlias = Literal
|
|
52
|
-
"initializing", "running", "stopped", "error", "completed"
|
|
53
|
-
]
|
|
54
|
+
SessionStatus: TypeAlias = ServiceState # Replaced Literal with ServiceState enum
|
|
54
55
|
LaunchMethod: TypeAlias = Literal["exec", "subprocess", "oneshot"]
|
|
55
56
|
|
|
56
57
|
|
|
@@ -152,7 +153,7 @@ class WebSocketMessage(TypedDict):
|
|
|
152
153
|
class ClaudeStatus(TypedDict):
|
|
153
154
|
"""Claude process status."""
|
|
154
155
|
|
|
155
|
-
status: Literal
|
|
156
|
+
status: ServiceState # Replaced Literal with ServiceState enum
|
|
156
157
|
message: str
|
|
157
158
|
timestamp: NotRequired[datetime]
|
|
158
159
|
pid: NotRequired[int]
|
|
@@ -163,7 +164,7 @@ class DelegationInfo(TypedDict):
|
|
|
163
164
|
|
|
164
165
|
agent: AgentId
|
|
165
166
|
task: str
|
|
166
|
-
status: Literal
|
|
167
|
+
status: OperationResult # Replaced Literal with OperationResult enum
|
|
167
168
|
timestamp: NotRequired[datetime]
|
|
168
169
|
result: NotRequired[str]
|
|
169
170
|
|
|
@@ -194,7 +195,7 @@ class HookContext(TypedDict):
|
|
|
194
195
|
|
|
195
196
|
# Service types
|
|
196
197
|
ServiceName: TypeAlias = str
|
|
197
|
-
ServiceStatus: TypeAlias = Literal
|
|
198
|
+
ServiceStatus: TypeAlias = ServiceState # Replaced Literal with ServiceState enum
|
|
198
199
|
|
|
199
200
|
|
|
200
201
|
class ServiceConfig(TypedDict):
|
|
@@ -10,6 +10,7 @@ from dataclasses import dataclass
|
|
|
10
10
|
from enum import Enum
|
|
11
11
|
from typing import Dict, List, Optional, Tuple
|
|
12
12
|
|
|
13
|
+
from claude_mpm.core.enums import OperationResult
|
|
13
14
|
from claude_mpm.core.logging_utils import get_logger
|
|
14
15
|
|
|
15
16
|
logger = get_logger(__name__)
|
|
@@ -267,7 +268,7 @@ class InstructionReinforcementHook:
|
|
|
267
268
|
if not self.violations:
|
|
268
269
|
return {
|
|
269
270
|
"total_violations": 0,
|
|
270
|
-
"status":
|
|
271
|
+
"status": OperationResult.SUCCESS,
|
|
271
272
|
"message": "No PM delegation violations detected",
|
|
272
273
|
}
|
|
273
274
|
|
|
@@ -276,7 +277,11 @@ class InstructionReinforcementHook:
|
|
|
276
277
|
vtype = v.violation_type.value
|
|
277
278
|
violation_types[vtype] = violation_types.get(vtype, 0) + 1
|
|
278
279
|
|
|
279
|
-
status =
|
|
280
|
+
status = (
|
|
281
|
+
OperationResult.ERROR
|
|
282
|
+
if self.violation_count < 3
|
|
283
|
+
else OperationResult.FAILED
|
|
284
|
+
)
|
|
280
285
|
|
|
281
286
|
return {
|
|
282
287
|
"total_violations": self.violation_count,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import Any, Dict, List, Tuple
|
|
5
5
|
|
|
6
|
+
from claude_mpm.core.enums import OperationResult
|
|
6
7
|
from claude_mpm.core.interfaces import AgentDeploymentInterface
|
|
7
8
|
from claude_mpm.core.logger import get_logger
|
|
8
9
|
|
|
@@ -195,7 +196,7 @@ class AgentDeploymentInterfaceAdapter(AgentDeploymentInterface):
|
|
|
195
196
|
# Ensure the result is a dictionary
|
|
196
197
|
if not isinstance(status, dict):
|
|
197
198
|
return {
|
|
198
|
-
"status":
|
|
199
|
+
"status": OperationResult.UNKNOWN,
|
|
199
200
|
"error": "Invalid status format from deployment service",
|
|
200
201
|
"interface_version": "1.0.0",
|
|
201
202
|
"adapter_used": True,
|
|
@@ -210,7 +211,7 @@ class AgentDeploymentInterfaceAdapter(AgentDeploymentInterface):
|
|
|
210
211
|
except Exception as e:
|
|
211
212
|
self.logger.error(f"Failed to get deployment status: {e}", exc_info=True)
|
|
212
213
|
return {
|
|
213
|
-
"status":
|
|
214
|
+
"status": OperationResult.ERROR,
|
|
214
215
|
"error": str(e),
|
|
215
216
|
"interface_version": "1.0.0",
|
|
216
217
|
"adapter_used": True,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import Any, Dict, List, Optional, Tuple
|
|
5
5
|
|
|
6
|
+
from claude_mpm.core.enums import OperationResult
|
|
6
7
|
from claude_mpm.core.interfaces import AgentDeploymentInterface
|
|
7
8
|
from claude_mpm.core.logger import get_logger
|
|
8
9
|
|
|
@@ -235,7 +236,7 @@ class RefactoredAgentDeploymentService(AgentDeploymentInterface):
|
|
|
235
236
|
# Build status information
|
|
236
237
|
return {
|
|
237
238
|
"service_version": "refactored-1.0.0",
|
|
238
|
-
"status":
|
|
239
|
+
"status": OperationResult.SUCCESS,
|
|
239
240
|
"templates_dir": str(self.templates_dir),
|
|
240
241
|
"base_agent_path": str(self.base_agent_path),
|
|
241
242
|
"working_directory": str(self.working_directory),
|
|
@@ -255,7 +256,7 @@ class RefactoredAgentDeploymentService(AgentDeploymentInterface):
|
|
|
255
256
|
self.logger.error(f"Failed to get deployment status: {e}", exc_info=True)
|
|
256
257
|
return {
|
|
257
258
|
"service_version": "refactored-1.0.0",
|
|
258
|
-
"status":
|
|
259
|
+
"status": OperationResult.ERROR,
|
|
259
260
|
"error": str(e),
|
|
260
261
|
}
|
|
261
262
|
|
|
@@ -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":
|
|
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":
|
|
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":
|
|
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":
|
|
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
|
|
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={
|
|
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={
|
|
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={
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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 ==
|
|
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(
|
|
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":
|
|
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":
|
|
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 ==
|
|
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(
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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 {
|
|
66
|
+
return {
|
|
67
|
+
"status": OperationResult.SUCCESS,
|
|
68
|
+
"command": command,
|
|
69
|
+
"method": "interactive",
|
|
70
|
+
}
|
|
66
71
|
except Exception as e:
|
|
67
|
-
return {
|
|
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":
|
|
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=
|
|
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=
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
289
|
+
"status": OperationResult.SUCCESS,
|
|
289
290
|
"type": "ast",
|
|
290
291
|
"metrics": metrics,
|
|
291
292
|
}
|