claude-mpm 4.1.0__py3-none-any.whl → 4.1.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/BUILD_NUMBER +1 -1
- claude_mpm/VERSION +1 -1
- claude_mpm/__main__.py +1 -1
- claude_mpm/agents/BASE_PM.md +74 -46
- claude_mpm/agents/INSTRUCTIONS.md +11 -153
- claude_mpm/agents/WORKFLOW.md +61 -321
- claude_mpm/agents/__init__.py +11 -11
- claude_mpm/agents/agent_loader.py +23 -20
- claude_mpm/agents/agent_loader_integration.py +1 -1
- claude_mpm/agents/agents_metadata.py +27 -0
- claude_mpm/agents/async_agent_loader.py +5 -8
- claude_mpm/agents/base_agent_loader.py +36 -25
- claude_mpm/agents/frontmatter_validator.py +6 -6
- claude_mpm/agents/schema/agent_schema.json +1 -1
- claude_mpm/agents/system_agent_config.py +9 -9
- claude_mpm/agents/templates/api_qa.json +47 -2
- claude_mpm/agents/templates/imagemagick.json +256 -0
- claude_mpm/agents/templates/qa.json +41 -2
- claude_mpm/agents/templates/ticketing.json +5 -5
- claude_mpm/agents/templates/web_qa.json +133 -58
- claude_mpm/agents/templates/web_ui.json +3 -3
- claude_mpm/cli/__init__.py +51 -46
- claude_mpm/cli/__main__.py +1 -1
- claude_mpm/cli/commands/__init__.py +10 -12
- claude_mpm/cli/commands/agent_manager.py +186 -181
- claude_mpm/cli/commands/agents.py +271 -268
- claude_mpm/cli/commands/aggregate.py +30 -29
- claude_mpm/cli/commands/cleanup.py +50 -44
- claude_mpm/cli/commands/cleanup_orphaned_agents.py +25 -25
- claude_mpm/cli/commands/config.py +162 -127
- claude_mpm/cli/commands/doctor.py +52 -62
- claude_mpm/cli/commands/info.py +37 -25
- claude_mpm/cli/commands/mcp.py +3 -7
- claude_mpm/cli/commands/mcp_command_router.py +14 -18
- claude_mpm/cli/commands/mcp_install_commands.py +28 -23
- claude_mpm/cli/commands/mcp_pipx_config.py +58 -49
- claude_mpm/cli/commands/mcp_server_commands.py +23 -17
- claude_mpm/cli/commands/memory.py +192 -141
- claude_mpm/cli/commands/monitor.py +117 -88
- claude_mpm/cli/commands/run.py +120 -84
- claude_mpm/cli/commands/run_config_checker.py +4 -5
- claude_mpm/cli/commands/socketio_monitor.py +17 -19
- claude_mpm/cli/commands/tickets.py +92 -92
- claude_mpm/cli/parser.py +1 -5
- claude_mpm/cli/parsers/__init__.py +1 -1
- claude_mpm/cli/parsers/agent_manager_parser.py +50 -98
- claude_mpm/cli/parsers/agents_parser.py +2 -3
- claude_mpm/cli/parsers/base_parser.py +7 -5
- claude_mpm/cli/parsers/mcp_parser.py +4 -2
- claude_mpm/cli/parsers/monitor_parser.py +26 -18
- claude_mpm/cli/shared/__init__.py +10 -10
- claude_mpm/cli/shared/argument_patterns.py +57 -71
- claude_mpm/cli/shared/base_command.py +61 -53
- claude_mpm/cli/shared/error_handling.py +62 -58
- claude_mpm/cli/shared/output_formatters.py +78 -77
- claude_mpm/cli/startup_logging.py +204 -172
- claude_mpm/cli/utils.py +10 -11
- claude_mpm/cli_module/__init__.py +1 -1
- claude_mpm/cli_module/args.py +1 -1
- claude_mpm/cli_module/migration_example.py +5 -5
- claude_mpm/config/__init__.py +9 -9
- claude_mpm/config/agent_config.py +15 -14
- claude_mpm/config/experimental_features.py +4 -4
- claude_mpm/config/paths.py +0 -1
- claude_mpm/config/socketio_config.py +5 -6
- claude_mpm/constants.py +1 -2
- claude_mpm/core/__init__.py +8 -8
- claude_mpm/core/agent_name_normalizer.py +1 -1
- claude_mpm/core/agent_registry.py +20 -23
- claude_mpm/core/agent_session_manager.py +3 -3
- claude_mpm/core/base_service.py +7 -15
- claude_mpm/core/cache.py +4 -6
- claude_mpm/core/claude_runner.py +85 -113
- claude_mpm/core/config.py +43 -28
- claude_mpm/core/config_aliases.py +0 -9
- claude_mpm/core/config_constants.py +52 -30
- claude_mpm/core/constants.py +0 -1
- claude_mpm/core/container.py +18 -27
- claude_mpm/core/exceptions.py +2 -2
- claude_mpm/core/factories.py +10 -12
- claude_mpm/core/framework_loader.py +581 -280
- claude_mpm/core/hook_manager.py +26 -22
- claude_mpm/core/hook_performance_config.py +58 -47
- claude_mpm/core/injectable_service.py +1 -1
- claude_mpm/core/interactive_session.py +61 -152
- claude_mpm/core/interfaces.py +1 -100
- claude_mpm/core/lazy.py +5 -5
- claude_mpm/core/log_manager.py +587 -0
- claude_mpm/core/logger.py +125 -8
- claude_mpm/core/logging_config.py +15 -15
- claude_mpm/core/minimal_framework_loader.py +5 -8
- claude_mpm/core/oneshot_session.py +15 -33
- claude_mpm/core/optimized_agent_loader.py +4 -6
- claude_mpm/core/optimized_startup.py +2 -1
- claude_mpm/core/output_style_manager.py +147 -106
- claude_mpm/core/pm_hook_interceptor.py +0 -1
- claude_mpm/core/service_registry.py +11 -8
- claude_mpm/core/session_manager.py +1 -2
- claude_mpm/core/shared/__init__.py +1 -1
- claude_mpm/core/shared/config_loader.py +101 -97
- claude_mpm/core/shared/path_resolver.py +72 -68
- claude_mpm/core/shared/singleton_manager.py +56 -50
- claude_mpm/core/socketio_pool.py +26 -6
- claude_mpm/core/tool_access_control.py +4 -5
- claude_mpm/core/typing_utils.py +50 -59
- claude_mpm/core/unified_agent_registry.py +14 -19
- claude_mpm/core/unified_config.py +4 -6
- claude_mpm/core/unified_paths.py +197 -109
- claude_mpm/dashboard/open_dashboard.py +2 -4
- claude_mpm/experimental/cli_enhancements.py +51 -36
- claude_mpm/generators/agent_profile_generator.py +2 -4
- claude_mpm/hooks/base_hook.py +1 -2
- claude_mpm/hooks/claude_hooks/connection_pool.py +72 -26
- claude_mpm/hooks/claude_hooks/event_handlers.py +93 -38
- claude_mpm/hooks/claude_hooks/hook_handler.py +130 -76
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
- claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
- claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
- claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
- claude_mpm/hooks/memory_integration_hook.py +5 -5
- claude_mpm/hooks/tool_call_interceptor.py +1 -1
- claude_mpm/hooks/validation_hooks.py +4 -4
- claude_mpm/init.py +4 -9
- claude_mpm/models/__init__.py +2 -2
- claude_mpm/models/agent_session.py +11 -14
- claude_mpm/scripts/mcp_server.py +20 -11
- claude_mpm/scripts/mcp_wrapper.py +5 -5
- claude_mpm/scripts/mpm_doctor.py +321 -0
- claude_mpm/scripts/socketio_daemon.py +28 -25
- claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
- claude_mpm/scripts/socketio_server_manager.py +116 -95
- claude_mpm/services/__init__.py +49 -49
- claude_mpm/services/agent_capabilities_service.py +12 -18
- claude_mpm/services/agents/__init__.py +22 -22
- claude_mpm/services/agents/agent_builder.py +140 -119
- claude_mpm/services/agents/deployment/__init__.py +3 -3
- claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
- claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
- claude_mpm/services/agents/deployment/agent_deployment.py +136 -106
- claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
- claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
- claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
- claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
- claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
- claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
- claude_mpm/services/agents/deployment/agent_validator.py +0 -1
- claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
- claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
- claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
- claude_mpm/services/agents/deployment/config/__init__.py +1 -1
- claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
- claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
- claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
- claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
- claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
- claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
- claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
- claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
- claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
- claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
- claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
- claude_mpm/services/agents/deployment/results/__init__.py +1 -1
- claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
- claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
- claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
- claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
- claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
- claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
- claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
- claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
- claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
- claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
- claude_mpm/services/agents/loading/__init__.py +1 -1
- claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
- claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
- claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
- claude_mpm/services/agents/management/__init__.py +1 -1
- claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
- claude_mpm/services/agents/management/agent_management_service.py +5 -9
- claude_mpm/services/agents/memory/__init__.py +4 -4
- claude_mpm/services/agents/memory/agent_memory_manager.py +280 -160
- claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
- claude_mpm/services/agents/memory/content_manager.py +44 -38
- claude_mpm/services/agents/memory/template_generator.py +4 -6
- claude_mpm/services/agents/registry/__init__.py +10 -6
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
- claude_mpm/services/agents/registry/modification_tracker.py +3 -6
- claude_mpm/services/async_session_logger.py +1 -2
- claude_mpm/services/claude_session_logger.py +1 -2
- claude_mpm/services/command_deployment_service.py +173 -0
- claude_mpm/services/command_handler_service.py +20 -22
- claude_mpm/services/core/__init__.py +25 -25
- claude_mpm/services/core/base.py +0 -5
- claude_mpm/services/core/interfaces/__init__.py +32 -32
- claude_mpm/services/core/interfaces/agent.py +0 -21
- claude_mpm/services/core/interfaces/communication.py +0 -27
- claude_mpm/services/core/interfaces/infrastructure.py +0 -56
- claude_mpm/services/core/interfaces/service.py +0 -29
- claude_mpm/services/diagnostics/__init__.py +1 -1
- claude_mpm/services/diagnostics/checks/__init__.py +6 -6
- claude_mpm/services/diagnostics/checks/agent_check.py +89 -80
- claude_mpm/services/diagnostics/checks/base_check.py +12 -16
- claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
- claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
- claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
- claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
- claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
- claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
- claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
- claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
- claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
- claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
- claude_mpm/services/diagnostics/models.py +21 -19
- claude_mpm/services/event_aggregator.py +10 -17
- claude_mpm/services/event_bus/__init__.py +1 -1
- claude_mpm/services/event_bus/config.py +54 -35
- claude_mpm/services/event_bus/event_bus.py +76 -71
- claude_mpm/services/event_bus/relay.py +74 -64
- claude_mpm/services/events/__init__.py +11 -11
- claude_mpm/services/events/consumers/__init__.py +3 -3
- claude_mpm/services/events/consumers/dead_letter.py +71 -63
- claude_mpm/services/events/consumers/logging.py +39 -37
- claude_mpm/services/events/consumers/metrics.py +56 -57
- claude_mpm/services/events/consumers/socketio.py +82 -81
- claude_mpm/services/events/core.py +110 -99
- claude_mpm/services/events/interfaces.py +56 -72
- claude_mpm/services/events/producers/__init__.py +1 -1
- claude_mpm/services/events/producers/hook.py +38 -38
- claude_mpm/services/events/producers/system.py +46 -44
- claude_mpm/services/exceptions.py +81 -80
- claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
- claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
- claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
- claude_mpm/services/hook_service.py +6 -9
- claude_mpm/services/infrastructure/__init__.py +1 -1
- claude_mpm/services/infrastructure/context_preservation.py +8 -12
- claude_mpm/services/infrastructure/monitoring.py +21 -23
- claude_mpm/services/mcp_gateway/__init__.py +37 -37
- claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
- claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
- claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
- claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
- claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
- claude_mpm/services/mcp_gateway/core/base.py +0 -3
- claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
- claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
- claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
- claude_mpm/services/mcp_gateway/main.py +2 -1
- claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
- claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
- claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
- claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
- claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
- claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
- claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
- claude_mpm/services/memory/__init__.py +3 -3
- claude_mpm/services/memory/builder.py +3 -6
- claude_mpm/services/memory/cache/__init__.py +1 -1
- claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
- claude_mpm/services/memory/cache/simple_cache.py +1 -1
- claude_mpm/services/memory/indexed_memory.py +5 -7
- claude_mpm/services/memory/optimizer.py +7 -10
- claude_mpm/services/memory/router.py +8 -9
- claude_mpm/services/memory_hook_service.py +48 -34
- claude_mpm/services/monitor_build_service.py +77 -73
- claude_mpm/services/port_manager.py +130 -108
- claude_mpm/services/project/analyzer.py +12 -10
- claude_mpm/services/project/registry.py +11 -11
- claude_mpm/services/recovery_manager.py +10 -19
- claude_mpm/services/response_tracker.py +0 -1
- claude_mpm/services/runner_configuration_service.py +19 -20
- claude_mpm/services/session_management_service.py +7 -11
- claude_mpm/services/shared/__init__.py +1 -1
- claude_mpm/services/shared/async_service_base.py +58 -50
- claude_mpm/services/shared/config_service_base.py +73 -67
- claude_mpm/services/shared/lifecycle_service_base.py +82 -78
- claude_mpm/services/shared/manager_base.py +94 -82
- claude_mpm/services/shared/service_factory.py +96 -98
- claude_mpm/services/socketio/__init__.py +3 -3
- claude_mpm/services/socketio/client_proxy.py +5 -5
- claude_mpm/services/socketio/event_normalizer.py +199 -181
- claude_mpm/services/socketio/handlers/__init__.py +3 -3
- claude_mpm/services/socketio/handlers/base.py +5 -4
- claude_mpm/services/socketio/handlers/connection.py +163 -136
- claude_mpm/services/socketio/handlers/file.py +13 -14
- claude_mpm/services/socketio/handlers/git.py +12 -7
- claude_mpm/services/socketio/handlers/hook.py +49 -44
- claude_mpm/services/socketio/handlers/memory.py +0 -1
- claude_mpm/services/socketio/handlers/project.py +0 -1
- claude_mpm/services/socketio/handlers/registry.py +37 -19
- claude_mpm/services/socketio/migration_utils.py +98 -84
- claude_mpm/services/socketio/server/__init__.py +1 -1
- claude_mpm/services/socketio/server/broadcaster.py +81 -87
- claude_mpm/services/socketio/server/core.py +65 -54
- claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
- claude_mpm/services/socketio/server/main.py +64 -38
- claude_mpm/services/socketio_client_manager.py +10 -12
- claude_mpm/services/subprocess_launcher_service.py +4 -7
- claude_mpm/services/system_instructions_service.py +13 -14
- claude_mpm/services/ticket_manager.py +2 -2
- claude_mpm/services/utility_service.py +5 -13
- claude_mpm/services/version_control/__init__.py +16 -16
- claude_mpm/services/version_control/branch_strategy.py +5 -8
- claude_mpm/services/version_control/conflict_resolution.py +9 -23
- claude_mpm/services/version_control/git_operations.py +5 -7
- claude_mpm/services/version_control/semantic_versioning.py +16 -17
- claude_mpm/services/version_control/version_parser.py +13 -18
- claude_mpm/services/version_service.py +10 -11
- claude_mpm/storage/__init__.py +1 -1
- claude_mpm/storage/state_storage.py +22 -28
- claude_mpm/utils/__init__.py +6 -6
- claude_mpm/utils/agent_dependency_loader.py +47 -33
- claude_mpm/utils/config_manager.py +11 -14
- claude_mpm/utils/dependency_cache.py +1 -1
- claude_mpm/utils/dependency_manager.py +13 -17
- claude_mpm/utils/dependency_strategies.py +8 -10
- claude_mpm/utils/environment_context.py +3 -9
- claude_mpm/utils/error_handler.py +3 -13
- claude_mpm/utils/file_utils.py +1 -1
- claude_mpm/utils/path_operations.py +8 -12
- claude_mpm/utils/robust_installer.py +110 -33
- claude_mpm/utils/subprocess_utils.py +5 -6
- claude_mpm/validation/agent_validator.py +3 -6
- claude_mpm/validation/frontmatter_validator.py +1 -1
- {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/METADATA +1 -1
- claude_mpm-4.1.2.dist-info/RECORD +498 -0
- claude_mpm-4.1.0.dist-info/RECORD +0 -494
- {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/WHEEL +0 -0
- {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/top_level.txt +0 -0
|
@@ -7,7 +7,7 @@ and properly structured.
|
|
|
7
7
|
|
|
8
8
|
import os
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import
|
|
10
|
+
from typing import Any, Dict
|
|
11
11
|
|
|
12
12
|
import yaml
|
|
13
13
|
|
|
@@ -17,40 +17,40 @@ from .base_check import BaseDiagnosticCheck
|
|
|
17
17
|
|
|
18
18
|
class ConfigurationCheck(BaseDiagnosticCheck):
|
|
19
19
|
"""Check configuration files and settings."""
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
@property
|
|
22
22
|
def name(self) -> str:
|
|
23
23
|
return "configuration_check"
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
@property
|
|
26
26
|
def category(self) -> str:
|
|
27
27
|
return "Configuration"
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
def run(self) -> DiagnosticResult:
|
|
30
30
|
"""Run configuration diagnostics."""
|
|
31
31
|
try:
|
|
32
32
|
sub_results = []
|
|
33
33
|
details = {}
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
# Check user configuration
|
|
36
36
|
user_result = self._check_user_config()
|
|
37
37
|
sub_results.append(user_result)
|
|
38
38
|
details["user_config"] = user_result.details
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
# Check project configuration
|
|
41
41
|
project_result = self._check_project_config()
|
|
42
42
|
sub_results.append(project_result)
|
|
43
43
|
details["project_config"] = project_result.details
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
# Check environment variables
|
|
46
46
|
env_result = self._check_environment_variables()
|
|
47
47
|
sub_results.append(env_result)
|
|
48
48
|
details["environment"] = env_result.details
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
# Check configuration permissions
|
|
51
51
|
perm_result = self._check_config_permissions()
|
|
52
52
|
sub_results.append(perm_result)
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
# Determine overall status
|
|
55
55
|
if any(r.status == DiagnosticStatus.ERROR for r in sub_results):
|
|
56
56
|
status = DiagnosticStatus.ERROR
|
|
@@ -61,48 +61,48 @@ class ConfigurationCheck(BaseDiagnosticCheck):
|
|
|
61
61
|
else:
|
|
62
62
|
status = DiagnosticStatus.OK
|
|
63
63
|
message = "Configuration is valid"
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
return DiagnosticResult(
|
|
66
66
|
category=self.category,
|
|
67
67
|
status=status,
|
|
68
68
|
message=message,
|
|
69
69
|
details=details,
|
|
70
|
-
sub_results=sub_results if self.verbose else []
|
|
70
|
+
sub_results=sub_results if self.verbose else [],
|
|
71
71
|
)
|
|
72
|
-
|
|
72
|
+
|
|
73
73
|
except Exception as e:
|
|
74
74
|
return DiagnosticResult(
|
|
75
75
|
category=self.category,
|
|
76
76
|
status=DiagnosticStatus.ERROR,
|
|
77
|
-
message=f"Configuration check failed: {
|
|
78
|
-
details={"error": str(e)}
|
|
77
|
+
message=f"Configuration check failed: {e!s}",
|
|
78
|
+
details={"error": str(e)},
|
|
79
79
|
)
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
def _check_user_config(self) -> DiagnosticResult:
|
|
82
82
|
"""Check user-level configuration."""
|
|
83
83
|
config_path = Path.home() / ".claude" / "claude-mpm.yaml"
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
if not config_path.exists():
|
|
86
86
|
return DiagnosticResult(
|
|
87
87
|
category="User Config",
|
|
88
88
|
status=DiagnosticStatus.OK,
|
|
89
89
|
message="No user configuration (using defaults)",
|
|
90
|
-
details={"path": str(config_path), "exists": False}
|
|
90
|
+
details={"path": str(config_path), "exists": False},
|
|
91
91
|
)
|
|
92
|
-
|
|
92
|
+
|
|
93
93
|
try:
|
|
94
|
-
with open(config_path
|
|
94
|
+
with open(config_path) as f:
|
|
95
95
|
config = yaml.safe_load(f)
|
|
96
|
-
|
|
96
|
+
|
|
97
97
|
issues = self._validate_config_structure(config)
|
|
98
98
|
if issues:
|
|
99
99
|
return DiagnosticResult(
|
|
100
100
|
category="User Config",
|
|
101
101
|
status=DiagnosticStatus.WARNING,
|
|
102
102
|
message=f"User config has issues: {', '.join(issues)}",
|
|
103
|
-
details={"path": str(config_path), "issues": issues}
|
|
103
|
+
details={"path": str(config_path), "issues": issues},
|
|
104
104
|
)
|
|
105
|
-
|
|
105
|
+
|
|
106
106
|
return DiagnosticResult(
|
|
107
107
|
category="User Config",
|
|
108
108
|
status=DiagnosticStatus.OK,
|
|
@@ -110,51 +110,51 @@ class ConfigurationCheck(BaseDiagnosticCheck):
|
|
|
110
110
|
details={
|
|
111
111
|
"path": str(config_path),
|
|
112
112
|
"size": config_path.stat().st_size,
|
|
113
|
-
"exists": True
|
|
114
|
-
}
|
|
113
|
+
"exists": True,
|
|
114
|
+
},
|
|
115
115
|
)
|
|
116
|
-
|
|
116
|
+
|
|
117
117
|
except yaml.YAMLError as e:
|
|
118
118
|
return DiagnosticResult(
|
|
119
119
|
category="User Config",
|
|
120
120
|
status=DiagnosticStatus.ERROR,
|
|
121
121
|
message="User config has invalid YAML",
|
|
122
122
|
details={"path": str(config_path), "error": str(e)},
|
|
123
|
-
fix_description="Fix YAML syntax errors in the configuration file"
|
|
123
|
+
fix_description="Fix YAML syntax errors in the configuration file",
|
|
124
124
|
)
|
|
125
125
|
except Exception as e:
|
|
126
126
|
return DiagnosticResult(
|
|
127
127
|
category="User Config",
|
|
128
128
|
status=DiagnosticStatus.WARNING,
|
|
129
|
-
message=f"Could not read user config: {
|
|
130
|
-
details={"path": str(config_path), "error": str(e)}
|
|
129
|
+
message=f"Could not read user config: {e!s}",
|
|
130
|
+
details={"path": str(config_path), "error": str(e)},
|
|
131
131
|
)
|
|
132
|
-
|
|
132
|
+
|
|
133
133
|
def _check_project_config(self) -> DiagnosticResult:
|
|
134
134
|
"""Check project-level configuration."""
|
|
135
135
|
config_path = Path.cwd() / ".claude" / "claude-mpm.yaml"
|
|
136
|
-
|
|
136
|
+
|
|
137
137
|
if not config_path.exists():
|
|
138
138
|
return DiagnosticResult(
|
|
139
139
|
category="Project Config",
|
|
140
140
|
status=DiagnosticStatus.OK,
|
|
141
141
|
message="No project configuration (using defaults)",
|
|
142
|
-
details={"path": str(config_path), "exists": False}
|
|
142
|
+
details={"path": str(config_path), "exists": False},
|
|
143
143
|
)
|
|
144
|
-
|
|
144
|
+
|
|
145
145
|
try:
|
|
146
|
-
with open(config_path
|
|
146
|
+
with open(config_path) as f:
|
|
147
147
|
config = yaml.safe_load(f)
|
|
148
|
-
|
|
148
|
+
|
|
149
149
|
issues = self._validate_config_structure(config)
|
|
150
150
|
if issues:
|
|
151
151
|
return DiagnosticResult(
|
|
152
152
|
category="Project Config",
|
|
153
153
|
status=DiagnosticStatus.WARNING,
|
|
154
154
|
message=f"Project config has issues: {', '.join(issues)}",
|
|
155
|
-
details={"path": str(config_path), "issues": issues}
|
|
155
|
+
details={"path": str(config_path), "issues": issues},
|
|
156
156
|
)
|
|
157
|
-
|
|
157
|
+
|
|
158
158
|
# Check for deprecated keys
|
|
159
159
|
deprecated = self._check_deprecated_keys(config)
|
|
160
160
|
if deprecated:
|
|
@@ -162,13 +162,10 @@ class ConfigurationCheck(BaseDiagnosticCheck):
|
|
|
162
162
|
category="Project Config",
|
|
163
163
|
status=DiagnosticStatus.WARNING,
|
|
164
164
|
message=f"Using deprecated config keys: {', '.join(deprecated)}",
|
|
165
|
-
details={
|
|
166
|
-
|
|
167
|
-
"deprecated_keys": deprecated
|
|
168
|
-
},
|
|
169
|
-
fix_description="Remove deprecated configuration keys"
|
|
165
|
+
details={"path": str(config_path), "deprecated_keys": deprecated},
|
|
166
|
+
fix_description="Remove deprecated configuration keys",
|
|
170
167
|
)
|
|
171
|
-
|
|
168
|
+
|
|
172
169
|
return DiagnosticResult(
|
|
173
170
|
category="Project Config",
|
|
174
171
|
status=DiagnosticStatus.OK,
|
|
@@ -176,26 +173,26 @@ class ConfigurationCheck(BaseDiagnosticCheck):
|
|
|
176
173
|
details={
|
|
177
174
|
"path": str(config_path),
|
|
178
175
|
"size": config_path.stat().st_size,
|
|
179
|
-
"exists": True
|
|
180
|
-
}
|
|
176
|
+
"exists": True,
|
|
177
|
+
},
|
|
181
178
|
)
|
|
182
|
-
|
|
179
|
+
|
|
183
180
|
except yaml.YAMLError as e:
|
|
184
181
|
return DiagnosticResult(
|
|
185
182
|
category="Project Config",
|
|
186
183
|
status=DiagnosticStatus.ERROR,
|
|
187
184
|
message="Project config has invalid YAML",
|
|
188
185
|
details={"path": str(config_path), "error": str(e)},
|
|
189
|
-
fix_description="Fix YAML syntax errors in the configuration file"
|
|
186
|
+
fix_description="Fix YAML syntax errors in the configuration file",
|
|
190
187
|
)
|
|
191
188
|
except Exception as e:
|
|
192
189
|
return DiagnosticResult(
|
|
193
190
|
category="Project Config",
|
|
194
191
|
status=DiagnosticStatus.WARNING,
|
|
195
|
-
message=f"Could not read project config: {
|
|
196
|
-
details={"path": str(config_path), "error": str(e)}
|
|
192
|
+
message=f"Could not read project config: {e!s}",
|
|
193
|
+
details={"path": str(config_path), "error": str(e)},
|
|
197
194
|
)
|
|
198
|
-
|
|
195
|
+
|
|
199
196
|
def _check_environment_variables(self) -> DiagnosticResult:
|
|
200
197
|
"""Check relevant environment variables."""
|
|
201
198
|
env_vars = {
|
|
@@ -204,53 +201,55 @@ class ConfigurationCheck(BaseDiagnosticCheck):
|
|
|
204
201
|
"CLAUDE_MPM_PROJECT_DIR": os.environ.get("CLAUDE_MPM_PROJECT_DIR"),
|
|
205
202
|
"PYTHONPATH": os.environ.get("PYTHONPATH"),
|
|
206
203
|
}
|
|
207
|
-
|
|
204
|
+
|
|
208
205
|
set_vars = {k: v for k, v in env_vars.items() if v is not None}
|
|
209
|
-
|
|
206
|
+
|
|
210
207
|
if not set_vars:
|
|
211
208
|
return DiagnosticResult(
|
|
212
209
|
category="Environment Variables",
|
|
213
210
|
status=DiagnosticStatus.OK,
|
|
214
211
|
message="No claude-mpm environment variables set",
|
|
215
|
-
details={"variables": {}}
|
|
212
|
+
details={"variables": {}},
|
|
216
213
|
)
|
|
217
|
-
|
|
214
|
+
|
|
218
215
|
return DiagnosticResult(
|
|
219
216
|
category="Environment Variables",
|
|
220
217
|
status=DiagnosticStatus.OK,
|
|
221
218
|
message=f"{len(set_vars)} environment variable(s) configured",
|
|
222
|
-
details={"variables": set_vars}
|
|
219
|
+
details={"variables": set_vars},
|
|
223
220
|
)
|
|
224
|
-
|
|
221
|
+
|
|
225
222
|
def _check_config_permissions(self) -> DiagnosticResult:
|
|
226
223
|
"""Check configuration file permissions."""
|
|
227
224
|
issues = []
|
|
228
225
|
paths_checked = []
|
|
229
|
-
|
|
226
|
+
|
|
230
227
|
for config_path in [
|
|
231
228
|
Path.home() / ".claude" / "claude-mpm.yaml",
|
|
232
|
-
Path.cwd() / ".claude" / "claude-mpm.yaml"
|
|
229
|
+
Path.cwd() / ".claude" / "claude-mpm.yaml",
|
|
233
230
|
]:
|
|
234
231
|
if config_path.exists():
|
|
235
232
|
paths_checked.append(str(config_path))
|
|
236
|
-
|
|
233
|
+
|
|
237
234
|
# Check readability
|
|
238
235
|
if not os.access(config_path, os.R_OK):
|
|
239
236
|
issues.append(f"{config_path.name} is not readable")
|
|
240
|
-
|
|
237
|
+
|
|
241
238
|
# Check if world-writable (security concern)
|
|
242
239
|
stat_info = config_path.stat()
|
|
243
240
|
if stat_info.st_mode & 0o002:
|
|
244
|
-
issues.append(
|
|
245
|
-
|
|
241
|
+
issues.append(
|
|
242
|
+
f"{config_path.name} is world-writable (security risk)"
|
|
243
|
+
)
|
|
244
|
+
|
|
246
245
|
if not paths_checked:
|
|
247
246
|
return DiagnosticResult(
|
|
248
247
|
category="Config Permissions",
|
|
249
248
|
status=DiagnosticStatus.OK,
|
|
250
249
|
message="No configuration files to check",
|
|
251
|
-
details={"paths_checked": []}
|
|
250
|
+
details={"paths_checked": []},
|
|
252
251
|
)
|
|
253
|
-
|
|
252
|
+
|
|
254
253
|
if issues:
|
|
255
254
|
return DiagnosticResult(
|
|
256
255
|
category="Config Permissions",
|
|
@@ -258,43 +257,49 @@ class ConfigurationCheck(BaseDiagnosticCheck):
|
|
|
258
257
|
message=f"Permission issues: {', '.join(issues)}",
|
|
259
258
|
details={"issues": issues, "paths_checked": paths_checked},
|
|
260
259
|
fix_command="chmod 644 ~/.claude/claude-mpm.yaml",
|
|
261
|
-
fix_description="Fix file permissions for configuration files"
|
|
260
|
+
fix_description="Fix file permissions for configuration files",
|
|
262
261
|
)
|
|
263
|
-
|
|
262
|
+
|
|
264
263
|
return DiagnosticResult(
|
|
265
264
|
category="Config Permissions",
|
|
266
265
|
status=DiagnosticStatus.OK,
|
|
267
266
|
message="Configuration file permissions are correct",
|
|
268
|
-
details={"paths_checked": paths_checked}
|
|
267
|
+
details={"paths_checked": paths_checked},
|
|
269
268
|
)
|
|
270
|
-
|
|
269
|
+
|
|
271
270
|
def _validate_config_structure(self, config: Dict[str, Any]) -> list:
|
|
272
271
|
"""Validate configuration structure and return issues."""
|
|
273
272
|
issues = []
|
|
274
|
-
|
|
273
|
+
|
|
275
274
|
if not isinstance(config, dict):
|
|
276
275
|
issues.append("Configuration is not a dictionary")
|
|
277
276
|
return issues
|
|
278
|
-
|
|
277
|
+
|
|
279
278
|
# Check for invalid top-level keys
|
|
280
279
|
valid_keys = {
|
|
281
|
-
"response_logging",
|
|
282
|
-
"
|
|
280
|
+
"response_logging",
|
|
281
|
+
"agent_deployment",
|
|
282
|
+
"memory_management",
|
|
283
|
+
"monitoring",
|
|
284
|
+
"mcp",
|
|
285
|
+
"hooks",
|
|
286
|
+
"paths",
|
|
287
|
+
"debug",
|
|
283
288
|
}
|
|
284
|
-
|
|
289
|
+
|
|
285
290
|
invalid_keys = set(config.keys()) - valid_keys
|
|
286
291
|
if invalid_keys:
|
|
287
292
|
issues.append(f"Unknown keys: {', '.join(invalid_keys)}")
|
|
288
|
-
|
|
293
|
+
|
|
289
294
|
return issues
|
|
290
|
-
|
|
295
|
+
|
|
291
296
|
def _check_deprecated_keys(self, config: Dict[str, Any]) -> list:
|
|
292
297
|
"""Check for deprecated configuration keys."""
|
|
293
298
|
deprecated_keys = ["legacy_mode", "old_agent_format", "deprecated_logging"]
|
|
294
299
|
found_deprecated = []
|
|
295
|
-
|
|
300
|
+
|
|
296
301
|
for key in deprecated_keys:
|
|
297
302
|
if key in config:
|
|
298
303
|
found_deprecated.append(key)
|
|
299
|
-
|
|
300
|
-
return found_deprecated
|
|
304
|
+
|
|
305
|
+
return found_deprecated
|
|
@@ -8,7 +8,6 @@ disk space for operation.
|
|
|
8
8
|
import os
|
|
9
9
|
import shutil
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import Dict, Any
|
|
12
11
|
|
|
13
12
|
from ..models import DiagnosticResult, DiagnosticStatus
|
|
14
13
|
from .base_check import BaseDiagnosticCheck
|
|
@@ -16,36 +15,36 @@ from .base_check import BaseDiagnosticCheck
|
|
|
16
15
|
|
|
17
16
|
class FilesystemCheck(BaseDiagnosticCheck):
|
|
18
17
|
"""Check filesystem health and permissions."""
|
|
19
|
-
|
|
18
|
+
|
|
20
19
|
@property
|
|
21
20
|
def name(self) -> str:
|
|
22
21
|
return "filesystem_check"
|
|
23
|
-
|
|
22
|
+
|
|
24
23
|
@property
|
|
25
24
|
def category(self) -> str:
|
|
26
25
|
return "File System"
|
|
27
|
-
|
|
26
|
+
|
|
28
27
|
def run(self) -> DiagnosticResult:
|
|
29
28
|
"""Run filesystem diagnostics."""
|
|
30
29
|
try:
|
|
31
30
|
sub_results = []
|
|
32
31
|
details = {}
|
|
33
|
-
|
|
32
|
+
|
|
34
33
|
# Check critical directory permissions
|
|
35
34
|
perm_result = self._check_permissions()
|
|
36
35
|
sub_results.append(perm_result)
|
|
37
36
|
details["permissions"] = perm_result.details
|
|
38
|
-
|
|
37
|
+
|
|
39
38
|
# Check disk space
|
|
40
39
|
space_result = self._check_disk_space()
|
|
41
40
|
sub_results.append(space_result)
|
|
42
41
|
details["disk_space"] = space_result.details
|
|
43
|
-
|
|
42
|
+
|
|
44
43
|
# Check .claude directory structure
|
|
45
44
|
structure_result = self._check_directory_structure()
|
|
46
45
|
sub_results.append(structure_result)
|
|
47
46
|
details["structure"] = structure_result.details
|
|
48
|
-
|
|
47
|
+
|
|
49
48
|
# Determine overall status
|
|
50
49
|
if any(r.status == DiagnosticStatus.ERROR for r in sub_results):
|
|
51
50
|
status = DiagnosticStatus.ERROR
|
|
@@ -56,94 +55,97 @@ class FilesystemCheck(BaseDiagnosticCheck):
|
|
|
56
55
|
else:
|
|
57
56
|
status = DiagnosticStatus.OK
|
|
58
57
|
message = "File system healthy"
|
|
59
|
-
|
|
58
|
+
|
|
60
59
|
return DiagnosticResult(
|
|
61
60
|
category=self.category,
|
|
62
61
|
status=status,
|
|
63
62
|
message=message,
|
|
64
63
|
details=details,
|
|
65
|
-
sub_results=sub_results if self.verbose else []
|
|
64
|
+
sub_results=sub_results if self.verbose else [],
|
|
66
65
|
)
|
|
67
|
-
|
|
66
|
+
|
|
68
67
|
except Exception as e:
|
|
69
68
|
return DiagnosticResult(
|
|
70
69
|
category=self.category,
|
|
71
70
|
status=DiagnosticStatus.ERROR,
|
|
72
|
-
message=f"Filesystem check failed: {
|
|
73
|
-
details={"error": str(e)}
|
|
71
|
+
message=f"Filesystem check failed: {e!s}",
|
|
72
|
+
details={"error": str(e)},
|
|
74
73
|
)
|
|
75
|
-
|
|
74
|
+
|
|
76
75
|
def _check_permissions(self) -> DiagnosticResult:
|
|
77
76
|
"""Check permissions for critical directories."""
|
|
77
|
+
# Focus on project-level directories as per v4.0.32+ architecture
|
|
78
|
+
project_claude_dir = Path.cwd() / ".claude"
|
|
78
79
|
critical_dirs = [
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
project_claude_dir,
|
|
81
|
+
project_claude_dir / "agents",
|
|
82
|
+
project_claude_dir / "responses",
|
|
83
|
+
project_claude_dir / "memory",
|
|
84
|
+
project_claude_dir / "logs",
|
|
83
85
|
]
|
|
84
|
-
|
|
86
|
+
|
|
85
87
|
issues = []
|
|
86
88
|
checked = []
|
|
87
|
-
|
|
89
|
+
|
|
88
90
|
for dir_path in critical_dirs:
|
|
89
91
|
if dir_path.exists():
|
|
90
92
|
checked.append(str(dir_path))
|
|
91
|
-
|
|
93
|
+
|
|
92
94
|
# Check read permission
|
|
93
95
|
if not os.access(dir_path, os.R_OK):
|
|
94
96
|
issues.append(f"{dir_path} not readable")
|
|
95
|
-
|
|
97
|
+
|
|
96
98
|
# Check write permission
|
|
97
99
|
if not os.access(dir_path, os.W_OK):
|
|
98
100
|
issues.append(f"{dir_path} not writable")
|
|
99
|
-
|
|
101
|
+
|
|
100
102
|
# Check execute permission (needed to list directory)
|
|
101
103
|
if not os.access(dir_path, os.X_OK):
|
|
102
104
|
issues.append(f"{dir_path} not accessible")
|
|
103
|
-
|
|
105
|
+
|
|
104
106
|
if issues:
|
|
105
107
|
return DiagnosticResult(
|
|
106
108
|
category="Permissions",
|
|
107
109
|
status=DiagnosticStatus.ERROR,
|
|
108
110
|
message=f"{len(issues)} permission issue(s)",
|
|
109
111
|
details={"issues": issues, "checked": checked},
|
|
110
|
-
fix_command="chmod -R 755
|
|
111
|
-
fix_description="Fix directory permissions"
|
|
112
|
+
fix_command="chmod -R 755 .claude",
|
|
113
|
+
fix_description="Fix project .claude directory permissions",
|
|
112
114
|
)
|
|
113
|
-
|
|
115
|
+
|
|
114
116
|
if not checked:
|
|
115
117
|
return DiagnosticResult(
|
|
116
118
|
category="Permissions",
|
|
117
119
|
status=DiagnosticStatus.WARNING,
|
|
118
|
-
message="No claude directories found",
|
|
119
|
-
details={"checked": [], "missing": [str(d) for d in critical_dirs]}
|
|
120
|
+
message="No project .claude directories found",
|
|
121
|
+
details={"checked": [], "missing": [str(d) for d in critical_dirs]},
|
|
120
122
|
)
|
|
121
|
-
|
|
123
|
+
|
|
122
124
|
return DiagnosticResult(
|
|
123
125
|
category="Permissions",
|
|
124
126
|
status=DiagnosticStatus.OK,
|
|
125
127
|
message="All permissions valid",
|
|
126
|
-
details={"checked": checked}
|
|
128
|
+
details={"checked": checked},
|
|
127
129
|
)
|
|
128
|
-
|
|
130
|
+
|
|
129
131
|
def _check_disk_space(self) -> DiagnosticResult:
|
|
130
132
|
"""Check available disk space."""
|
|
131
133
|
try:
|
|
132
134
|
# Check home directory disk usage
|
|
133
135
|
home_path = Path.home()
|
|
134
136
|
stat = shutil.disk_usage(home_path)
|
|
135
|
-
|
|
136
|
-
free_gb = stat.free / (1024
|
|
137
|
-
total_gb = stat.total / (1024
|
|
137
|
+
|
|
138
|
+
free_gb = stat.free / (1024**3)
|
|
139
|
+
total_gb = stat.total / (1024**3)
|
|
138
140
|
used_percent = (stat.used / stat.total) * 100
|
|
139
|
-
|
|
141
|
+
|
|
140
142
|
details = {
|
|
141
143
|
"free_gb": round(free_gb, 2),
|
|
142
144
|
"total_gb": round(total_gb, 2),
|
|
143
145
|
"used_percent": round(used_percent, 1),
|
|
144
|
-
"path": str(home_path)
|
|
146
|
+
"path": str(home_path),
|
|
145
147
|
}
|
|
146
|
-
|
|
148
|
+
|
|
147
149
|
# Check for low disk space
|
|
148
150
|
if free_gb < 0.1: # Less than 100MB
|
|
149
151
|
return DiagnosticResult(
|
|
@@ -151,63 +153,63 @@ class FilesystemCheck(BaseDiagnosticCheck):
|
|
|
151
153
|
status=DiagnosticStatus.ERROR,
|
|
152
154
|
message=f"Critical: Only {free_gb:.2f}GB free",
|
|
153
155
|
details=details,
|
|
154
|
-
fix_description="Free up disk space immediately"
|
|
156
|
+
fix_description="Free up disk space immediately",
|
|
155
157
|
)
|
|
156
|
-
|
|
158
|
+
if free_gb < 1: # Less than 1GB
|
|
157
159
|
return DiagnosticResult(
|
|
158
160
|
category="Disk Space",
|
|
159
161
|
status=DiagnosticStatus.WARNING,
|
|
160
162
|
message=f"Low disk space: {free_gb:.2f}GB free",
|
|
161
163
|
details=details,
|
|
162
|
-
fix_description="Consider freeing up disk space"
|
|
164
|
+
fix_description="Consider freeing up disk space",
|
|
163
165
|
)
|
|
164
|
-
|
|
166
|
+
|
|
165
167
|
return DiagnosticResult(
|
|
166
168
|
category="Disk Space",
|
|
167
169
|
status=DiagnosticStatus.OK,
|
|
168
170
|
message=f"{free_gb:.1f}GB available",
|
|
169
|
-
details=details
|
|
171
|
+
details=details,
|
|
170
172
|
)
|
|
171
|
-
|
|
173
|
+
|
|
172
174
|
except Exception as e:
|
|
173
175
|
return DiagnosticResult(
|
|
174
176
|
category="Disk Space",
|
|
175
177
|
status=DiagnosticStatus.WARNING,
|
|
176
|
-
message=f"Could not check disk space: {
|
|
177
|
-
details={"error": str(e)}
|
|
178
|
+
message=f"Could not check disk space: {e!s}",
|
|
179
|
+
details={"error": str(e)},
|
|
178
180
|
)
|
|
179
|
-
|
|
181
|
+
|
|
180
182
|
def _check_directory_structure(self) -> DiagnosticResult:
|
|
181
|
-
"""Check claude directory structure."""
|
|
182
|
-
base_dir = Path.
|
|
183
|
-
|
|
183
|
+
"""Check project claude directory structure."""
|
|
184
|
+
base_dir = Path.cwd() / ".claude"
|
|
185
|
+
|
|
184
186
|
expected_dirs = {
|
|
185
187
|
"agents": "Agent deployment directory",
|
|
186
188
|
"responses": "Response logging directory",
|
|
187
189
|
"memory": "Agent memory storage",
|
|
188
|
-
"logs": "Application logs"
|
|
190
|
+
"logs": "Application logs",
|
|
189
191
|
}
|
|
190
|
-
|
|
192
|
+
|
|
191
193
|
missing = []
|
|
192
194
|
present = []
|
|
193
|
-
|
|
195
|
+
|
|
194
196
|
if not base_dir.exists():
|
|
195
197
|
return DiagnosticResult(
|
|
196
198
|
category="Directory Structure",
|
|
197
199
|
status=DiagnosticStatus.WARNING,
|
|
198
|
-
message="
|
|
200
|
+
message="Project .claude directory missing",
|
|
199
201
|
details={"base_dir": str(base_dir), "exists": False},
|
|
200
|
-
fix_command="mkdir -p
|
|
201
|
-
fix_description="Create claude directory structure"
|
|
202
|
+
fix_command="mkdir -p .claude/{agents,responses,memory,logs}",
|
|
203
|
+
fix_description="Create project claude directory structure",
|
|
202
204
|
)
|
|
203
|
-
|
|
204
|
-
for dir_name,
|
|
205
|
+
|
|
206
|
+
for dir_name, _description in expected_dirs.items():
|
|
205
207
|
dir_path = base_dir / dir_name
|
|
206
208
|
if dir_path.exists():
|
|
207
209
|
present.append(dir_name)
|
|
208
210
|
else:
|
|
209
211
|
missing.append(dir_name)
|
|
210
|
-
|
|
212
|
+
|
|
211
213
|
if missing:
|
|
212
214
|
return DiagnosticResult(
|
|
213
215
|
category="Directory Structure",
|
|
@@ -216,18 +218,15 @@ class FilesystemCheck(BaseDiagnosticCheck):
|
|
|
216
218
|
details={
|
|
217
219
|
"base_dir": str(base_dir),
|
|
218
220
|
"missing": missing,
|
|
219
|
-
"present": present
|
|
221
|
+
"present": present,
|
|
220
222
|
},
|
|
221
|
-
fix_command=f"mkdir -p
|
|
222
|
-
fix_description="Create missing directories"
|
|
223
|
+
fix_command=f"mkdir -p .claude/{{{','.join(missing)}}}",
|
|
224
|
+
fix_description="Create missing project directories",
|
|
223
225
|
)
|
|
224
|
-
|
|
226
|
+
|
|
225
227
|
return DiagnosticResult(
|
|
226
228
|
category="Directory Structure",
|
|
227
229
|
status=DiagnosticStatus.OK,
|
|
228
230
|
message="Directory structure complete",
|
|
229
|
-
details={
|
|
230
|
-
|
|
231
|
-
"directories": present
|
|
232
|
-
}
|
|
233
|
-
)
|
|
231
|
+
details={"base_dir": str(base_dir), "directories": present},
|
|
232
|
+
)
|