claude-mpm 4.7.4__py3-none-any.whl → 4.18.2__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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +118 -0
- claude_mpm/agents/BASE_ENGINEER.md +286 -0
- claude_mpm/agents/BASE_PM.md +106 -1
- claude_mpm/agents/OUTPUT_STYLE.md +329 -11
- claude_mpm/agents/PM_INSTRUCTIONS.md +397 -459
- claude_mpm/agents/agent_loader.py +17 -5
- claude_mpm/agents/frontmatter_validator.py +284 -253
- claude_mpm/agents/templates/README.md +465 -0
- claude_mpm/agents/templates/agent-manager.json +4 -1
- claude_mpm/agents/templates/agentic-coder-optimizer.json +13 -3
- claude_mpm/agents/templates/api_qa.json +11 -2
- claude_mpm/agents/templates/circuit_breakers.md +638 -0
- claude_mpm/agents/templates/clerk-ops.json +12 -2
- claude_mpm/agents/templates/code_analyzer.json +8 -2
- claude_mpm/agents/templates/content-agent.json +358 -0
- claude_mpm/agents/templates/dart_engineer.json +15 -2
- claude_mpm/agents/templates/data_engineer.json +15 -2
- claude_mpm/agents/templates/documentation.json +10 -2
- claude_mpm/agents/templates/engineer.json +21 -1
- claude_mpm/agents/templates/gcp_ops_agent.json +12 -2
- claude_mpm/agents/templates/git_file_tracking.md +584 -0
- claude_mpm/agents/templates/golang_engineer.json +270 -0
- claude_mpm/agents/templates/imagemagick.json +4 -1
- claude_mpm/agents/templates/java_engineer.json +346 -0
- claude_mpm/agents/templates/local_ops_agent.json +1227 -6
- claude_mpm/agents/templates/memory_manager.json +4 -1
- claude_mpm/agents/templates/nextjs_engineer.json +141 -133
- claude_mpm/agents/templates/ops.json +12 -2
- claude_mpm/agents/templates/php-engineer.json +270 -174
- claude_mpm/agents/templates/pm_examples.md +474 -0
- claude_mpm/agents/templates/pm_red_flags.md +240 -0
- claude_mpm/agents/templates/product_owner.json +338 -0
- claude_mpm/agents/templates/project_organizer.json +14 -4
- claude_mpm/agents/templates/prompt-engineer.json +13 -2
- claude_mpm/agents/templates/python_engineer.json +174 -81
- claude_mpm/agents/templates/qa.json +11 -2
- claude_mpm/agents/templates/react_engineer.json +16 -3
- claude_mpm/agents/templates/refactoring_engineer.json +12 -2
- claude_mpm/agents/templates/research.json +34 -21
- claude_mpm/agents/templates/response_format.md +583 -0
- claude_mpm/agents/templates/ruby-engineer.json +129 -192
- claude_mpm/agents/templates/rust_engineer.json +270 -0
- claude_mpm/agents/templates/security.json +10 -2
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/agents/templates/ticketing.json +10 -2
- claude_mpm/agents/templates/typescript_engineer.json +116 -125
- claude_mpm/agents/templates/validation_templates.md +312 -0
- claude_mpm/agents/templates/vercel_ops_agent.json +12 -2
- claude_mpm/agents/templates/version_control.json +12 -2
- claude_mpm/agents/templates/web_qa.json +11 -2
- claude_mpm/agents/templates/web_ui.json +15 -2
- claude_mpm/cli/__init__.py +34 -614
- 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 +235 -148
- claude_mpm/cli/commands/agents_detect.py +380 -0
- claude_mpm/cli/commands/agents_recommend.py +309 -0
- 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/auto_configure.py +570 -0
- claude_mpm/cli/commands/config.py +47 -13
- claude_mpm/cli/commands/configure.py +419 -1571
- 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 +167 -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/local_deploy.py +537 -0
- claude_mpm/cli/commands/memory.py +54 -20
- claude_mpm/cli/commands/mpm_init.py +585 -196
- claude_mpm/cli/commands/mpm_init_handler.py +37 -3
- claude_mpm/cli/commands/search.py +170 -4
- claude_mpm/cli/commands/upgrade.py +152 -0
- claude_mpm/cli/executor.py +202 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +3 -0
- claude_mpm/cli/interactive/skills_wizard.py +491 -0
- claude_mpm/cli/parsers/__init__.py +7 -1
- claude_mpm/cli/parsers/agents_parser.py +9 -0
- claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
- claude_mpm/cli/parsers/base_parser.py +110 -3
- claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +65 -5
- claude_mpm/cli/shared/output_formatters.py +28 -19
- claude_mpm/cli/startup.py +481 -0
- claude_mpm/cli/utils.py +52 -1
- claude_mpm/commands/mpm-agents-detect.md +168 -0
- claude_mpm/commands/mpm-agents-recommend.md +214 -0
- claude_mpm/commands/mpm-agents.md +75 -1
- claude_mpm/commands/mpm-auto-configure.md +217 -0
- claude_mpm/commands/mpm-help.md +163 -0
- claude_mpm/commands/mpm-init.md +148 -3
- claude_mpm/commands/mpm-version.md +113 -0
- claude_mpm/commands/mpm.md +1 -0
- claude_mpm/config/agent_config.py +2 -2
- claude_mpm/config/model_config.py +428 -0
- claude_mpm/constants.py +1 -0
- claude_mpm/core/base_service.py +13 -12
- claude_mpm/core/enums.py +452 -0
- claude_mpm/core/factories.py +1 -1
- claude_mpm/core/instruction_reinforcement_hook.py +2 -1
- claude_mpm/core/interactive_session.py +9 -3
- claude_mpm/core/log_manager.py +2 -0
- claude_mpm/core/logging_config.py +6 -2
- claude_mpm/core/oneshot_session.py +8 -4
- claude_mpm/core/optimized_agent_loader.py +3 -3
- claude_mpm/core/output_style_manager.py +12 -192
- claude_mpm/core/service_registry.py +5 -1
- claude_mpm/core/types.py +2 -9
- claude_mpm/core/typing_utils.py +7 -6
- claude_mpm/dashboard/static/js/dashboard.js +0 -14
- claude_mpm/dashboard/templates/index.html +3 -41
- claude_mpm/hooks/__init__.py +20 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +4 -2
- claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +23 -2
- claude_mpm/hooks/failure_learning/__init__.py +60 -0
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +235 -0
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +217 -0
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +286 -0
- claude_mpm/hooks/instruction_reinforcement.py +7 -2
- claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
- claude_mpm/hooks/kuzu_memory_hook.py +37 -12
- claude_mpm/hooks/kuzu_response_hook.py +183 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/services/agents/__init__.py +18 -5
- claude_mpm/services/agents/auto_config_manager.py +796 -0
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
- claude_mpm/services/agents/deployment/agent_validator.py +17 -1
- claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
- claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
- claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +7 -6
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +5 -3
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
- claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
- claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
- claude_mpm/services/agents/local_template_manager.py +1 -1
- claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
- claude_mpm/services/agents/observers.py +547 -0
- claude_mpm/services/agents/recommender.py +568 -0
- claude_mpm/services/agents/registry/modification_tracker.py +5 -2
- claude_mpm/services/command_handler_service.py +11 -5
- claude_mpm/services/core/__init__.py +33 -1
- claude_mpm/services/core/interfaces/__init__.py +90 -3
- claude_mpm/services/core/interfaces/agent.py +184 -0
- claude_mpm/services/core/interfaces/health.py +172 -0
- claude_mpm/services/core/interfaces/model.py +281 -0
- claude_mpm/services/core/interfaces/process.py +372 -0
- claude_mpm/services/core/interfaces/project.py +121 -0
- claude_mpm/services/core/interfaces/restart.py +307 -0
- claude_mpm/services/core/interfaces/stability.py +260 -0
- claude_mpm/services/core/memory_manager.py +11 -24
- claude_mpm/services/core/models/__init__.py +79 -0
- claude_mpm/services/core/models/agent_config.py +381 -0
- claude_mpm/services/core/models/health.py +162 -0
- claude_mpm/services/core/models/process.py +235 -0
- claude_mpm/services/core/models/restart.py +302 -0
- claude_mpm/services/core/models/stability.py +264 -0
- claude_mpm/services/core/models/toolchain.py +306 -0
- claude_mpm/services/core/path_resolver.py +23 -7
- claude_mpm/services/diagnostics/__init__.py +2 -2
- claude_mpm/services/diagnostics/checks/agent_check.py +25 -24
- claude_mpm/services/diagnostics/checks/claude_code_check.py +24 -23
- claude_mpm/services/diagnostics/checks/common_issues_check.py +25 -24
- claude_mpm/services/diagnostics/checks/configuration_check.py +24 -23
- claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
- claude_mpm/services/diagnostics/checks/installation_check.py +30 -29
- claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
- claude_mpm/services/diagnostics/checks/mcp_check.py +50 -36
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +38 -33
- claude_mpm/services/diagnostics/checks/monitor_check.py +23 -22
- claude_mpm/services/diagnostics/checks/startup_log_check.py +9 -8
- claude_mpm/services/diagnostics/diagnostic_runner.py +6 -5
- claude_mpm/services/diagnostics/doctor_reporter.py +28 -25
- claude_mpm/services/diagnostics/models.py +19 -24
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
- claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
- claude_mpm/services/infrastructure/monitoring/base.py +5 -13
- claude_mpm/services/infrastructure/monitoring/network.py +7 -6
- claude_mpm/services/infrastructure/monitoring/process.py +13 -12
- claude_mpm/services/infrastructure/monitoring/resources.py +7 -6
- claude_mpm/services/infrastructure/monitoring/service.py +16 -15
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/local_ops/__init__.py +163 -0
- claude_mpm/services/local_ops/crash_detector.py +257 -0
- claude_mpm/services/local_ops/health_checks/__init__.py +28 -0
- claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
- claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
- claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
- claude_mpm/services/local_ops/health_manager.py +430 -0
- claude_mpm/services/local_ops/log_monitor.py +396 -0
- claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
- claude_mpm/services/local_ops/process_manager.py +595 -0
- claude_mpm/services/local_ops/resource_monitor.py +331 -0
- claude_mpm/services/local_ops/restart_manager.py +401 -0
- claude_mpm/services/local_ops/restart_policy.py +387 -0
- claude_mpm/services/local_ops/state_manager.py +372 -0
- claude_mpm/services/local_ops/unified_manager.py +600 -0
- claude_mpm/services/mcp_config_manager.py +9 -4
- claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
- claude_mpm/services/mcp_gateway/core/base.py +18 -31
- claude_mpm/services/mcp_gateway/main.py +30 -0
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +206 -32
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +30 -28
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +25 -5
- claude_mpm/services/mcp_service_verifier.py +1 -1
- claude_mpm/services/memory/failure_tracker.py +563 -0
- claude_mpm/services/memory_hook_service.py +165 -4
- claude_mpm/services/model/__init__.py +147 -0
- claude_mpm/services/model/base_provider.py +365 -0
- claude_mpm/services/model/claude_provider.py +412 -0
- claude_mpm/services/model/model_router.py +453 -0
- claude_mpm/services/model/ollama_provider.py +415 -0
- 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/project/__init__.py +23 -0
- claude_mpm/services/project/detection_strategies.py +719 -0
- claude_mpm/services/project/toolchain_analyzer.py +581 -0
- claude_mpm/services/self_upgrade_service.py +342 -0
- claude_mpm/services/session_management_service.py +3 -2
- claude_mpm/services/session_manager.py +205 -1
- claude_mpm/services/shared/async_service_base.py +16 -27
- claude_mpm/services/shared/lifecycle_service_base.py +1 -14
- claude_mpm/services/socketio/handlers/__init__.py +5 -2
- claude_mpm/services/socketio/handlers/hook.py +13 -2
- claude_mpm/services/socketio/handlers/registry.py +4 -2
- claude_mpm/services/socketio/server/main.py +10 -8
- claude_mpm/services/subprocess_launcher_service.py +14 -5
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +8 -7
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +6 -5
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +8 -7
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +7 -6
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +5 -4
- 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 +6 -5
- claude_mpm/services/unified/deployment_strategies/utils.py +6 -5
- claude_mpm/services/unified/deployment_strategies/vercel.py +7 -6
- claude_mpm/services/unified/interfaces.py +3 -1
- claude_mpm/services/unified/unified_analyzer.py +14 -10
- claude_mpm/services/unified/unified_config.py +2 -1
- claude_mpm/services/unified/unified_deployment.py +9 -4
- claude_mpm/services/version_service.py +104 -1
- claude_mpm/skills/__init__.py +21 -0
- claude_mpm/skills/bundled/__init__.py +6 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +567 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/security-scanning.md +327 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +286 -0
- claude_mpm/skills/skill_manager.py +310 -0
- claude_mpm/storage/state_storage.py +15 -15
- claude_mpm/tools/code_tree_analyzer.py +177 -141
- claude_mpm/tools/code_tree_events.py +4 -2
- claude_mpm/utils/agent_dependency_loader.py +40 -20
- claude_mpm/utils/display_helper.py +260 -0
- claude_mpm/utils/git_analyzer.py +407 -0
- claude_mpm/utils/robust_installer.py +73 -19
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/METADATA +129 -12
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/RECORD +295 -193
- claude_mpm/dashboard/static/css/code-tree.css +0 -1639
- claude_mpm/dashboard/static/index-hub-backup.html +0 -713
- claude_mpm/dashboard/static/js/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/js/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/js/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/js/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/js/components/code-tree.js +0 -5869
- claude_mpm/dashboard/static/js/components/code-viewer.js +0 -1386
- 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.7.4.dist-info → claude_mpm-4.18.2.dist-info}/WHEEL +0 -0
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/top_level.txt +0 -0
|
@@ -4,23 +4,12 @@ Base class for asynchronous services to reduce duplication.
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
from abc import ABC, abstractmethod
|
|
7
|
-
from enum import Enum
|
|
8
7
|
from typing import Any, Dict, Optional
|
|
9
8
|
|
|
9
|
+
from ...core.enums import ServiceState
|
|
10
10
|
from ...core.mixins import LoggerMixin
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class AsyncServiceState(Enum):
|
|
14
|
-
"""Standard states for async services."""
|
|
15
|
-
|
|
16
|
-
UNINITIALIZED = "uninitialized"
|
|
17
|
-
INITIALIZING = "initializing"
|
|
18
|
-
RUNNING = "running"
|
|
19
|
-
STOPPING = "stopping"
|
|
20
|
-
STOPPED = "stopped"
|
|
21
|
-
ERROR = "error"
|
|
22
|
-
|
|
23
|
-
|
|
24
13
|
class AsyncServiceBase(LoggerMixin, ABC):
|
|
25
14
|
"""
|
|
26
15
|
Base class for asynchronous services.
|
|
@@ -45,7 +34,7 @@ class AsyncServiceBase(LoggerMixin, ABC):
|
|
|
45
34
|
self.config = config or {}
|
|
46
35
|
|
|
47
36
|
# State management
|
|
48
|
-
self._state =
|
|
37
|
+
self._state = ServiceState.UNINITIALIZED
|
|
49
38
|
self._state_lock = asyncio.Lock()
|
|
50
39
|
|
|
51
40
|
# Background tasks
|
|
@@ -57,19 +46,19 @@ class AsyncServiceBase(LoggerMixin, ABC):
|
|
|
57
46
|
self._error_count = 0
|
|
58
47
|
|
|
59
48
|
@property
|
|
60
|
-
def state(self) ->
|
|
49
|
+
def state(self) -> ServiceState:
|
|
61
50
|
"""Get current service state."""
|
|
62
51
|
return self._state
|
|
63
52
|
|
|
64
53
|
@property
|
|
65
54
|
def is_running(self) -> bool:
|
|
66
55
|
"""Check if service is running."""
|
|
67
|
-
return self._state ==
|
|
56
|
+
return self._state == ServiceState.RUNNING
|
|
68
57
|
|
|
69
58
|
@property
|
|
70
59
|
def is_healthy(self) -> bool:
|
|
71
60
|
"""Check if service is healthy."""
|
|
72
|
-
return self._state ==
|
|
61
|
+
return self._state == ServiceState.RUNNING and self._last_error is None
|
|
73
62
|
|
|
74
63
|
async def initialize(self) -> bool:
|
|
75
64
|
"""
|
|
@@ -79,22 +68,22 @@ class AsyncServiceBase(LoggerMixin, ABC):
|
|
|
79
68
|
True if initialization successful
|
|
80
69
|
"""
|
|
81
70
|
async with self._state_lock:
|
|
82
|
-
if self._state !=
|
|
71
|
+
if self._state != ServiceState.UNINITIALIZED:
|
|
83
72
|
self.logger.warning(f"Service {self.service_name} already initialized")
|
|
84
|
-
return self._state ==
|
|
73
|
+
return self._state == ServiceState.RUNNING
|
|
85
74
|
|
|
86
|
-
self._state =
|
|
75
|
+
self._state = ServiceState.INITIALIZING
|
|
87
76
|
self.logger.info(f"Initializing service: {self.service_name}")
|
|
88
77
|
|
|
89
78
|
try:
|
|
90
79
|
success = await self._do_initialize()
|
|
91
80
|
if success:
|
|
92
|
-
self._state =
|
|
81
|
+
self._state = ServiceState.RUNNING
|
|
93
82
|
self.logger.info(
|
|
94
83
|
f"Service {self.service_name} initialized successfully"
|
|
95
84
|
)
|
|
96
85
|
else:
|
|
97
|
-
self._state =
|
|
86
|
+
self._state = ServiceState.ERROR
|
|
98
87
|
self.logger.error(
|
|
99
88
|
f"Service {self.service_name} initialization failed"
|
|
100
89
|
)
|
|
@@ -102,7 +91,7 @@ class AsyncServiceBase(LoggerMixin, ABC):
|
|
|
102
91
|
return success
|
|
103
92
|
|
|
104
93
|
except Exception as e:
|
|
105
|
-
self._state =
|
|
94
|
+
self._state = ServiceState.ERROR
|
|
106
95
|
self._last_error = e
|
|
107
96
|
self._error_count += 1
|
|
108
97
|
self.logger.error(
|
|
@@ -114,10 +103,10 @@ class AsyncServiceBase(LoggerMixin, ABC):
|
|
|
114
103
|
async def shutdown(self) -> None:
|
|
115
104
|
"""Shutdown the service gracefully."""
|
|
116
105
|
async with self._state_lock:
|
|
117
|
-
if self._state in (
|
|
106
|
+
if self._state in (ServiceState.STOPPED, ServiceState.STOPPING):
|
|
118
107
|
return
|
|
119
108
|
|
|
120
|
-
self._state =
|
|
109
|
+
self._state = ServiceState.STOPPING
|
|
121
110
|
self.logger.info(f"Shutting down service: {self.service_name}")
|
|
122
111
|
|
|
123
112
|
try:
|
|
@@ -130,11 +119,11 @@ class AsyncServiceBase(LoggerMixin, ABC):
|
|
|
130
119
|
# Service-specific shutdown
|
|
131
120
|
await self._do_shutdown()
|
|
132
121
|
|
|
133
|
-
self._state =
|
|
122
|
+
self._state = ServiceState.STOPPED
|
|
134
123
|
self.logger.info(f"Service {self.service_name} shut down successfully")
|
|
135
124
|
|
|
136
125
|
except Exception as e:
|
|
137
|
-
self._state =
|
|
126
|
+
self._state = ServiceState.ERROR
|
|
138
127
|
self._last_error = e
|
|
139
128
|
self.logger.error(
|
|
140
129
|
f"Service {self.service_name} shutdown error: {e}", exc_info=True
|
|
@@ -146,7 +135,7 @@ class AsyncServiceBase(LoggerMixin, ABC):
|
|
|
146
135
|
await self.shutdown()
|
|
147
136
|
|
|
148
137
|
# Reset state for restart
|
|
149
|
-
self._state =
|
|
138
|
+
self._state = ServiceState.UNINITIALIZED
|
|
150
139
|
self._shutdown_event.clear()
|
|
151
140
|
self._last_error = None
|
|
152
141
|
|
|
@@ -4,25 +4,12 @@ Base class for services with complex lifecycle management.
|
|
|
4
4
|
|
|
5
5
|
import time
|
|
6
6
|
from abc import ABC, abstractmethod
|
|
7
|
-
from enum import Enum
|
|
8
7
|
from typing import Any, Dict, List, Optional
|
|
9
8
|
|
|
9
|
+
from ...core.enums import ServiceState
|
|
10
10
|
from ...core.mixins import LoggerMixin
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class ServiceState(Enum):
|
|
14
|
-
"""Standard service states."""
|
|
15
|
-
|
|
16
|
-
UNINITIALIZED = "uninitialized"
|
|
17
|
-
INITIALIZING = "initializing"
|
|
18
|
-
INITIALIZED = "initialized"
|
|
19
|
-
STARTING = "starting"
|
|
20
|
-
RUNNING = "running"
|
|
21
|
-
STOPPING = "stopping"
|
|
22
|
-
STOPPED = "stopped"
|
|
23
|
-
ERROR = "error"
|
|
24
|
-
|
|
25
|
-
|
|
26
13
|
class LifecycleServiceBase(LoggerMixin, ABC):
|
|
27
14
|
"""
|
|
28
15
|
Base class for services with complex lifecycle management.
|
|
@@ -7,7 +7,9 @@ and maintainability.
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
from .base import BaseEventHandler
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
# DISABLED: File Tree interface removed from dashboard
|
|
12
|
+
# from .code_analysis import CodeAnalysisEventHandler
|
|
11
13
|
from .connection import ConnectionEventHandler
|
|
12
14
|
from .file import FileEventHandler
|
|
13
15
|
from .git import GitEventHandler
|
|
@@ -17,7 +19,8 @@ from .registry import EventHandlerRegistry
|
|
|
17
19
|
|
|
18
20
|
__all__ = [
|
|
19
21
|
"BaseEventHandler",
|
|
20
|
-
|
|
22
|
+
# DISABLED: File Tree interface removed from dashboard
|
|
23
|
+
# "CodeAnalysisEventHandler",
|
|
21
24
|
"ConnectionEventHandler",
|
|
22
25
|
"EventHandlerRegistry",
|
|
23
26
|
"FileEventHandler",
|
|
@@ -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
|
|
|
@@ -60,6 +61,10 @@ class HookEventHandler(BaseEventHandler):
|
|
|
60
61
|
|
|
61
62
|
hook_data = data.get("data", {})
|
|
62
63
|
|
|
64
|
+
# Log hook event processing
|
|
65
|
+
tool_name = hook_data.get("tool_name", "N/A")
|
|
66
|
+
self.logger.info(f"Processing hook event: {hook_event} - tool: {tool_name}")
|
|
67
|
+
|
|
63
68
|
# Create properly formatted event for history
|
|
64
69
|
# Note: add_to_history expects the event data directly, not wrapped
|
|
65
70
|
history_event = {
|
|
@@ -76,6 +81,12 @@ class HookEventHandler(BaseEventHandler):
|
|
|
76
81
|
|
|
77
82
|
# Broadcast the original event to all connected clients
|
|
78
83
|
# (preserves all original fields)
|
|
84
|
+
connected_clients = (
|
|
85
|
+
len(self.server.clients) if hasattr(self.server, "clients") else 0
|
|
86
|
+
)
|
|
87
|
+
self.logger.info(
|
|
88
|
+
f"Broadcasting claude_event to {connected_clients} clients: {hook_event}"
|
|
89
|
+
)
|
|
79
90
|
await self.broadcast_event("claude_event", data)
|
|
80
91
|
|
|
81
92
|
# Track sessions based on hook events
|
|
@@ -108,7 +119,7 @@ class HookEventHandler(BaseEventHandler):
|
|
|
108
119
|
"session_id": session_id,
|
|
109
120
|
"start_time": datetime.now(timezone.utc).isoformat(),
|
|
110
121
|
"agent": agent_type,
|
|
111
|
-
"status":
|
|
122
|
+
"status": ServiceState.RUNNING,
|
|
112
123
|
"prompt": data.get("prompt", "")[:100], # First 100 chars
|
|
113
124
|
"last_activity": datetime.now(timezone.utc).isoformat(),
|
|
114
125
|
}
|
|
@@ -159,7 +170,7 @@ class HookEventHandler(BaseEventHandler):
|
|
|
159
170
|
"session_id": session_id,
|
|
160
171
|
"start_time": datetime.now(timezone.utc).isoformat(),
|
|
161
172
|
"agent": "pm", # Default to PM
|
|
162
|
-
"status":
|
|
173
|
+
"status": ServiceState.RUNNING,
|
|
163
174
|
"prompt": data.get("prompt_text", "")[:100],
|
|
164
175
|
"working_directory": data.get("working_directory", ""),
|
|
165
176
|
"last_activity": datetime.now(timezone.utc).isoformat(),
|
|
@@ -15,7 +15,8 @@ if TYPE_CHECKING:
|
|
|
15
15
|
|
|
16
16
|
from ..server import SocketIOServer
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
# DISABLED: File Tree interface removed from dashboard
|
|
19
|
+
# from .code_analysis import CodeAnalysisEventHandler
|
|
19
20
|
from .connection import ConnectionEventHandler
|
|
20
21
|
from .file import FileEventHandler
|
|
21
22
|
from .git import GitEventHandler
|
|
@@ -38,7 +39,8 @@ class EventHandlerRegistry:
|
|
|
38
39
|
HookEventHandler, # Hook events for session tracking
|
|
39
40
|
GitEventHandler, # Git operations
|
|
40
41
|
FileEventHandler, # File operations
|
|
41
|
-
|
|
42
|
+
# DISABLED: File Tree interface removed from dashboard
|
|
43
|
+
# CodeAnalysisEventHandler, # Code analysis for dashboard
|
|
42
44
|
ProjectEventHandler, # Project management (future)
|
|
43
45
|
MemoryEventHandler, # Memory management (future)
|
|
44
46
|
]
|
|
@@ -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
|
|
@@ -265,15 +267,15 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
265
267
|
except Exception as e:
|
|
266
268
|
self.logger.error(f"Error during EventBus teardown: {e}")
|
|
267
269
|
|
|
268
|
-
# Stop
|
|
270
|
+
# Stop event handlers
|
|
269
271
|
if self.event_registry:
|
|
270
|
-
from ..handlers import
|
|
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()
|
|
272
|
+
from ..handlers import ConnectionEventHandler
|
|
276
273
|
|
|
274
|
+
# DISABLED: File Tree interface removed from dashboard
|
|
275
|
+
# Stop analysis runner (code analysis handler is disabled)
|
|
276
|
+
# analysis_handler = self.event_registry.get_handler(CodeAnalysisEventHandler)
|
|
277
|
+
# if analysis_handler and hasattr(analysis_handler, "cleanup"):
|
|
278
|
+
# analysis_handler.cleanup()
|
|
277
279
|
# Stop health monitoring in connection handler
|
|
278
280
|
conn_handler = self.event_registry.get_handler(ConnectionEventHandler)
|
|
279
281
|
if conn_handler and hasattr(conn_handler, "stop_health_monitoring"):
|
|
@@ -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": [],
|
|
@@ -195,7 +196,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
|
|
|
195
196
|
total_metrics = {}
|
|
196
197
|
for file_path in code_files:
|
|
197
198
|
file_result = self._analyze_file(file_path, options)
|
|
198
|
-
if file_result["status"] ==
|
|
199
|
+
if file_result["status"] == OperationResult.SUCCESS:
|
|
199
200
|
results["files"].append(file_result)
|
|
200
201
|
|
|
201
202
|
# Aggregate metrics
|
|
@@ -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
|
}
|
|
@@ -426,7 +427,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
|
|
|
426
427
|
"""Extract key metrics from analysis results."""
|
|
427
428
|
metrics = {}
|
|
428
429
|
|
|
429
|
-
if analysis_result.get("status") !=
|
|
430
|
+
if analysis_result.get("status") != OperationResult.SUCCESS:
|
|
430
431
|
return metrics
|
|
431
432
|
|
|
432
433
|
# Extract relevant metrics
|
|
@@ -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":
|
|
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":
|
|
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":
|
|
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":
|
|
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") !=
|
|
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":
|
|
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":
|
|
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"] =
|
|
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":
|
|
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"] ==
|
|
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":
|
|
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") !=
|
|
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":
|
|
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":
|
|
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"] =
|
|
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":
|
|
255
|
+
"status": OperationResult.SUCCESS,
|
|
255
256
|
"type": "directory",
|
|
256
257
|
"path": str(dir_path),
|
|
257
258
|
"files_analyzed": 0,
|
|
@@ -301,7 +302,7 @@ class SecurityAnalyzerStrategy(AnalyzerStrategy):
|
|
|
301
302
|
|
|
302
303
|
file_result = self._analyze_file(file_path, options)
|
|
303
304
|
if (
|
|
304
|
-
file_result["status"] ==
|
|
305
|
+
file_result["status"] == OperationResult.SUCCESS
|
|
305
306
|
and file_result["vulnerabilities"]
|
|
306
307
|
):
|
|
307
308
|
results["files"].append(file_result)
|
|
@@ -645,7 +646,7 @@ class SecurityAnalyzerStrategy(AnalyzerStrategy):
|
|
|
645
646
|
"""Extract key metrics from analysis results."""
|
|
646
647
|
metrics = {}
|
|
647
648
|
|
|
648
|
-
if analysis_result.get("status") !=
|
|
649
|
+
if analysis_result.get("status") != OperationResult.SUCCESS:
|
|
649
650
|
return metrics
|
|
650
651
|
|
|
651
652
|
if analysis_result.get("type") == "file":
|
|
@@ -13,6 +13,7 @@ import fnmatch
|
|
|
13
13
|
from pathlib import Path
|
|
14
14
|
from typing import Any, ClassVar, Dict, List, Optional, Tuple
|
|
15
15
|
|
|
16
|
+
from claude_mpm.core.enums import OperationResult
|
|
16
17
|
from claude_mpm.core.logging_utils import get_logger
|
|
17
18
|
|
|
18
19
|
from ..strategies import (
|
|
@@ -174,14 +175,14 @@ class StructureAnalyzerStrategy(AnalyzerStrategy):
|
|
|
174
175
|
|
|
175
176
|
if not target_path.is_dir():
|
|
176
177
|
return {
|
|
177
|
-
"status":
|
|
178
|
+
"status": OperationResult.ERROR,
|
|
178
179
|
"message": "Target must be a directory",
|
|
179
180
|
}
|
|
180
181
|
|
|
181
182
|
return self._analyze_structure(target_path, options)
|
|
182
183
|
|
|
183
184
|
return {
|
|
184
|
-
"status":
|
|
185
|
+
"status": OperationResult.ERROR,
|
|
185
186
|
"message": f"Unsupported target type: {type(target).__name__}",
|
|
186
187
|
}
|
|
187
188
|
|
|
@@ -190,7 +191,7 @@ class StructureAnalyzerStrategy(AnalyzerStrategy):
|
|
|
190
191
|
) -> Dict[str, Any]:
|
|
191
192
|
"""Analyze the structure of a project directory."""
|
|
192
193
|
results = {
|
|
193
|
-
"status":
|
|
194
|
+
"status": OperationResult.SUCCESS,
|
|
194
195
|
"type": "structure",
|
|
195
196
|
"path": str(root_path),
|
|
196
197
|
"tree": {},
|
|
@@ -640,7 +641,7 @@ class StructureAnalyzerStrategy(AnalyzerStrategy):
|
|
|
640
641
|
"""Extract key metrics from analysis results."""
|
|
641
642
|
metrics = {}
|
|
642
643
|
|
|
643
|
-
if analysis_result.get("status") !=
|
|
644
|
+
if analysis_result.get("status") != OperationResult.SUCCESS:
|
|
644
645
|
return metrics
|
|
645
646
|
|
|
646
647
|
# Extract structure statistics
|