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
|
@@ -11,13 +11,11 @@ This module provides conflict resolution management including:
|
|
|
11
11
|
5. Resolution validation
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
-
import difflib
|
|
15
14
|
import logging
|
|
16
15
|
import re
|
|
17
16
|
from dataclasses import dataclass, field
|
|
18
|
-
from datetime import datetime
|
|
19
17
|
from enum import Enum
|
|
20
|
-
from typing import Any, Dict, List, Optional
|
|
18
|
+
from typing import Any, Dict, List, Optional
|
|
21
19
|
|
|
22
20
|
|
|
23
21
|
class ConflictType(Enum):
|
|
@@ -248,11 +246,7 @@ class ConflictResolutionManager:
|
|
|
248
246
|
|
|
249
247
|
conflicted_files = []
|
|
250
248
|
for line in result.stdout.strip().split("\n"):
|
|
251
|
-
if line.strip() and (
|
|
252
|
-
line.startswith("UU")
|
|
253
|
-
or line.startswith("AA")
|
|
254
|
-
or line.startswith("DD")
|
|
255
|
-
):
|
|
249
|
+
if line.strip() and (line.startswith(("UU", "AA", "DD"))):
|
|
256
250
|
# Extract filename
|
|
257
251
|
filename = line[3:].strip()
|
|
258
252
|
conflicted_files.append(filename)
|
|
@@ -280,7 +274,7 @@ class ConflictResolutionManager:
|
|
|
280
274
|
)
|
|
281
275
|
|
|
282
276
|
try:
|
|
283
|
-
with open(full_path,
|
|
277
|
+
with open(full_path, encoding="utf-8") as f:
|
|
284
278
|
content = f.read()
|
|
285
279
|
|
|
286
280
|
# Parse conflict markers
|
|
@@ -404,11 +398,7 @@ class ConflictResolutionManager:
|
|
|
404
398
|
return False
|
|
405
399
|
|
|
406
400
|
# Check if all conflicts are simple
|
|
407
|
-
for marker in markers
|
|
408
|
-
if not self._is_simple_conflict(marker):
|
|
409
|
-
return False
|
|
410
|
-
|
|
411
|
-
return True
|
|
401
|
+
return all(self._is_simple_conflict(marker) for marker in markers)
|
|
412
402
|
|
|
413
403
|
def _is_simple_conflict(self, marker: ConflictMarker) -> bool:
|
|
414
404
|
"""Check if a conflict marker represents a simple conflict."""
|
|
@@ -428,10 +418,7 @@ class ConflictResolutionManager:
|
|
|
428
418
|
return True
|
|
429
419
|
|
|
430
420
|
# Check if differences are only imports
|
|
431
|
-
|
|
432
|
-
return True
|
|
433
|
-
|
|
434
|
-
return False
|
|
421
|
+
return bool(self._only_import_differences(ours_lines, theirs_lines))
|
|
435
422
|
|
|
436
423
|
def _only_whitespace_differences(self, ours: List[str], theirs: List[str]) -> bool:
|
|
437
424
|
"""Check if differences are only whitespace."""
|
|
@@ -444,7 +431,7 @@ class ConflictResolutionManager:
|
|
|
444
431
|
# This is a simplified check
|
|
445
432
|
for line in ours + theirs:
|
|
446
433
|
stripped = line.strip()
|
|
447
|
-
if stripped and not (stripped.startswith("#"
|
|
434
|
+
if stripped and not (stripped.startswith(("#", "//"))):
|
|
448
435
|
return False
|
|
449
436
|
return True
|
|
450
437
|
|
|
@@ -516,10 +503,9 @@ class ConflictResolutionManager:
|
|
|
516
503
|
|
|
517
504
|
if auto_ratio > 0.8:
|
|
518
505
|
return "simple"
|
|
519
|
-
|
|
506
|
+
if auto_ratio > 0.5:
|
|
520
507
|
return "moderate"
|
|
521
|
-
|
|
522
|
-
return "complex"
|
|
508
|
+
return "complex"
|
|
523
509
|
|
|
524
510
|
def _estimate_resolution_time(self, file_conflicts: List[FileConflict]) -> int:
|
|
525
511
|
"""Estimate resolution time in minutes."""
|
|
@@ -601,7 +587,7 @@ class ConflictResolutionManager:
|
|
|
601
587
|
|
|
602
588
|
try:
|
|
603
589
|
# Read current content
|
|
604
|
-
with open(file_path,
|
|
590
|
+
with open(file_path, encoding="utf-8") as f:
|
|
605
591
|
content = f.read()
|
|
606
592
|
|
|
607
593
|
# Apply resolution strategy
|
|
@@ -13,11 +13,10 @@ This module provides comprehensive Git operation management including:
|
|
|
13
13
|
|
|
14
14
|
import logging
|
|
15
15
|
import os
|
|
16
|
-
import re
|
|
17
16
|
import subprocess
|
|
18
17
|
from dataclasses import dataclass, field
|
|
19
18
|
from datetime import datetime
|
|
20
|
-
from typing import Any, Dict, List, Optional
|
|
19
|
+
from typing import Any, Dict, List, Optional
|
|
21
20
|
|
|
22
21
|
|
|
23
22
|
@dataclass
|
|
@@ -128,7 +127,7 @@ class GitOperationsManager:
|
|
|
128
127
|
Raises:
|
|
129
128
|
GitOperationError: If command fails and check=True
|
|
130
129
|
"""
|
|
131
|
-
cmd = ["git"
|
|
130
|
+
cmd = ["git", *args]
|
|
132
131
|
cwd = cwd or str(self.project_root)
|
|
133
132
|
|
|
134
133
|
try:
|
|
@@ -444,7 +443,7 @@ class GitOperationsManager:
|
|
|
444
443
|
return GitOperationResult(
|
|
445
444
|
success=False,
|
|
446
445
|
operation="switch_branch",
|
|
447
|
-
message=
|
|
446
|
+
message="Cannot switch branch: uncommitted changes exist",
|
|
448
447
|
error=f"Modified files: {', '.join(modified_files)}",
|
|
449
448
|
branch_before=current_branch,
|
|
450
449
|
branch_after=current_branch,
|
|
@@ -599,10 +598,9 @@ class GitOperationsManager:
|
|
|
599
598
|
conflicted_files = []
|
|
600
599
|
if has_conflicts:
|
|
601
600
|
lines = result.stdout.split("\n")
|
|
602
|
-
current_file = None
|
|
603
601
|
|
|
604
602
|
for line in lines:
|
|
605
|
-
if line.startswith("+++"
|
|
603
|
+
if line.startswith(("+++", "---")):
|
|
606
604
|
# Extract filename
|
|
607
605
|
parts = line.split("\t")
|
|
608
606
|
if len(parts) > 1:
|
|
@@ -775,7 +773,7 @@ class GitOperationsManager:
|
|
|
775
773
|
for line in result.stdout.strip().split("\n"):
|
|
776
774
|
branch = line.strip().lstrip("* ").strip()
|
|
777
775
|
# Skip target branch and current branch
|
|
778
|
-
if branch and branch
|
|
776
|
+
if branch and branch not in (target_branch, current_branch):
|
|
779
777
|
merged_branches.append(branch)
|
|
780
778
|
|
|
781
779
|
# Delete merged branches
|
|
@@ -39,13 +39,12 @@ Change Analysis:
|
|
|
39
39
|
- Confidence scoring for version bump suggestions
|
|
40
40
|
"""
|
|
41
41
|
|
|
42
|
-
import json
|
|
43
42
|
import logging
|
|
44
43
|
import re
|
|
45
44
|
from dataclasses import dataclass, field
|
|
46
45
|
from datetime import datetime
|
|
47
46
|
from enum import Enum
|
|
48
|
-
from typing import
|
|
47
|
+
from typing import Dict, List, Optional, Tuple
|
|
49
48
|
|
|
50
49
|
from ...utils.config_manager import ConfigurationManager
|
|
51
50
|
|
|
@@ -167,13 +166,13 @@ class SemanticVersion:
|
|
|
167
166
|
if bump_type == VersionBumpType.MAJOR:
|
|
168
167
|
# Breaking changes - reset minor and patch
|
|
169
168
|
return SemanticVersion(self.major + 1, 0, 0)
|
|
170
|
-
|
|
169
|
+
if bump_type == VersionBumpType.MINOR:
|
|
171
170
|
# New features - reset patch only
|
|
172
171
|
return SemanticVersion(self.major, self.minor + 1, 0)
|
|
173
|
-
|
|
172
|
+
if bump_type == VersionBumpType.PATCH:
|
|
174
173
|
# Bug fixes - increment patch only
|
|
175
174
|
return SemanticVersion(self.major, self.minor, self.patch + 1)
|
|
176
|
-
|
|
175
|
+
if bump_type == VersionBumpType.PRERELEASE:
|
|
177
176
|
if self.prerelease:
|
|
178
177
|
# Increment existing prerelease number
|
|
179
178
|
match = re.match(r"(.+?)(\d+)$", self.prerelease)
|
|
@@ -423,7 +422,7 @@ class SemanticVersionManager:
|
|
|
423
422
|
# Try different locations for version
|
|
424
423
|
if "project" in data and "version" in data["project"]:
|
|
425
424
|
return data["project"]["version"]
|
|
426
|
-
|
|
425
|
+
if (
|
|
427
426
|
"tool" in data
|
|
428
427
|
and "poetry" in data["tool"]
|
|
429
428
|
and "version" in data["tool"]["poetry"]
|
|
@@ -438,7 +437,7 @@ class SemanticVersionManager:
|
|
|
438
437
|
def _parse_toml_version_regex(self, file_path: Path) -> Optional[str]:
|
|
439
438
|
"""Parse version from TOML file using regex."""
|
|
440
439
|
try:
|
|
441
|
-
with open(file_path
|
|
440
|
+
with open(file_path) as f:
|
|
442
441
|
content = f.read()
|
|
443
442
|
|
|
444
443
|
# Look for version = "x.y.z" pattern
|
|
@@ -464,7 +463,7 @@ class SemanticVersionManager:
|
|
|
464
463
|
def _parse_version_file(self, file_path: Path) -> Optional[str]:
|
|
465
464
|
"""Parse version from simple version file."""
|
|
466
465
|
try:
|
|
467
|
-
with open(file_path
|
|
466
|
+
with open(file_path) as f:
|
|
468
467
|
return f.read().strip()
|
|
469
468
|
except Exception:
|
|
470
469
|
return None
|
|
@@ -472,7 +471,7 @@ class SemanticVersionManager:
|
|
|
472
471
|
def _parse_pom_xml_version(self, file_path: Path) -> Optional[str]:
|
|
473
472
|
"""Parse version from Maven pom.xml."""
|
|
474
473
|
try:
|
|
475
|
-
with open(file_path
|
|
474
|
+
with open(file_path) as f:
|
|
476
475
|
content = f.read()
|
|
477
476
|
|
|
478
477
|
# Simple regex to find version in pom.xml
|
|
@@ -645,11 +644,11 @@ class SemanticVersionManager:
|
|
|
645
644
|
try:
|
|
646
645
|
if filename == "package.json":
|
|
647
646
|
return self._update_package_json_version(file_path, new_version)
|
|
648
|
-
|
|
647
|
+
if filename in ["pyproject.toml", "Cargo.toml"]:
|
|
649
648
|
return self._update_toml_version(file_path, new_version)
|
|
650
|
-
|
|
649
|
+
if filename in ["VERSION", "version.txt"]:
|
|
651
650
|
return self._update_simple_version_file(file_path, new_version)
|
|
652
|
-
|
|
651
|
+
if filename == "pom.xml":
|
|
653
652
|
return self._update_pom_xml_version(file_path, new_version)
|
|
654
653
|
|
|
655
654
|
return False
|
|
@@ -674,7 +673,7 @@ class SemanticVersionManager:
|
|
|
674
673
|
def _update_toml_version(self, file_path: Path, new_version: str) -> bool:
|
|
675
674
|
"""Update version in TOML file."""
|
|
676
675
|
try:
|
|
677
|
-
with open(file_path
|
|
676
|
+
with open(file_path) as f:
|
|
678
677
|
content = f.read()
|
|
679
678
|
|
|
680
679
|
# Replace version field
|
|
@@ -713,7 +712,7 @@ class SemanticVersionManager:
|
|
|
713
712
|
def _update_pom_xml_version(self, file_path: Path, new_version: str) -> bool:
|
|
714
713
|
"""Update version in Maven pom.xml."""
|
|
715
714
|
try:
|
|
716
|
-
with open(file_path
|
|
715
|
+
with open(file_path) as f:
|
|
717
716
|
content = f.read()
|
|
718
717
|
|
|
719
718
|
# Replace first version tag (project version)
|
|
@@ -842,7 +841,7 @@ class SemanticVersionManager:
|
|
|
842
841
|
|
|
843
842
|
# Read existing changelog or create new one
|
|
844
843
|
if changelog_path.exists():
|
|
845
|
-
with open(changelog_path
|
|
844
|
+
with open(changelog_path) as f:
|
|
846
845
|
existing_content = f.read()
|
|
847
846
|
|
|
848
847
|
# Insert new entry after title
|
|
@@ -851,7 +850,7 @@ class SemanticVersionManager:
|
|
|
851
850
|
|
|
852
851
|
# Find insertion point (after # Changelog title)
|
|
853
852
|
for i, line in enumerate(lines):
|
|
854
|
-
if line.startswith("# "
|
|
853
|
+
if line.startswith(("# ", "## [Unreleased]")):
|
|
855
854
|
insert_index = i + 1
|
|
856
855
|
break
|
|
857
856
|
|
|
@@ -946,7 +945,7 @@ class SemanticVersionManager:
|
|
|
946
945
|
versions = []
|
|
947
946
|
|
|
948
947
|
try:
|
|
949
|
-
with open(changelog_path
|
|
948
|
+
with open(changelog_path) as f:
|
|
950
949
|
content = f.read()
|
|
951
950
|
|
|
952
951
|
# Find version entries
|
|
@@ -15,15 +15,14 @@ from multiple sources with intelligent fallback logic:
|
|
|
15
15
|
The system includes caching for performance and validation for data integrity.
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
+
import contextlib
|
|
18
19
|
import json
|
|
19
20
|
import logging
|
|
20
21
|
import re
|
|
21
22
|
import subprocess
|
|
22
23
|
from datetime import datetime, timedelta
|
|
23
24
|
from functools import lru_cache
|
|
24
|
-
from typing import Dict, List, Optional, Tuple
|
|
25
|
-
|
|
26
|
-
from claude_mpm.services.version_control.semantic_versioning import SemanticVersion
|
|
25
|
+
from typing import Dict, List, Optional, Tuple
|
|
27
26
|
|
|
28
27
|
|
|
29
28
|
class VersionSource:
|
|
@@ -73,9 +72,9 @@ class VersionMetadata:
|
|
|
73
72
|
return {
|
|
74
73
|
"version": self.version,
|
|
75
74
|
"source": self.source,
|
|
76
|
-
"release_date":
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
"release_date": (
|
|
76
|
+
self.release_date.isoformat() if self.release_date else None
|
|
77
|
+
),
|
|
79
78
|
"commit_hash": self.commit_hash,
|
|
80
79
|
"author": self.author,
|
|
81
80
|
"message": self.message,
|
|
@@ -213,13 +212,13 @@ class EnhancedVersionParser:
|
|
|
213
212
|
"""Get version(s) from a specific source."""
|
|
214
213
|
if source == VersionSource.GIT_TAGS:
|
|
215
214
|
return self._get_version_from_git(latest_only)
|
|
216
|
-
|
|
215
|
+
if source == VersionSource.VERSION_FILE:
|
|
217
216
|
return self._get_version_from_file()
|
|
218
|
-
|
|
217
|
+
if source == VersionSource.PACKAGE_JSON:
|
|
219
218
|
return self._get_version_from_package_json()
|
|
220
|
-
|
|
219
|
+
if source == VersionSource.PYPROJECT_TOML:
|
|
221
220
|
return self._get_version_from_pyproject()
|
|
222
|
-
|
|
221
|
+
if source == VersionSource.CHANGELOG:
|
|
223
222
|
versions = self._get_versions_from_changelog()
|
|
224
223
|
return versions[0] if versions else None
|
|
225
224
|
return None
|
|
@@ -228,9 +227,9 @@ class EnhancedVersionParser:
|
|
|
228
227
|
"""Get all versions from a specific source."""
|
|
229
228
|
if source == VersionSource.GIT_TAGS:
|
|
230
229
|
return self._get_all_versions_from_git()
|
|
231
|
-
|
|
230
|
+
if source == VersionSource.CHANGELOG:
|
|
232
231
|
return self._get_versions_from_changelog()
|
|
233
|
-
|
|
232
|
+
if source in [
|
|
234
233
|
VersionSource.VERSION_FILE,
|
|
235
234
|
VersionSource.PACKAGE_JSON,
|
|
236
235
|
VersionSource.PYPROJECT_TOML,
|
|
@@ -318,10 +317,8 @@ class EnhancedVersionParser:
|
|
|
318
317
|
# Parse date if provided
|
|
319
318
|
release_date = None
|
|
320
319
|
if date_str:
|
|
321
|
-
|
|
320
|
+
with contextlib.suppress(Exception):
|
|
322
321
|
release_date = datetime.fromisoformat(date_str.replace(" ", "T"))
|
|
323
|
-
except:
|
|
324
|
-
pass
|
|
325
322
|
|
|
326
323
|
# Get commit hash for this tag
|
|
327
324
|
commit_hash = None
|
|
@@ -422,10 +419,8 @@ class EnhancedVersionParser:
|
|
|
422
419
|
# Parse release date
|
|
423
420
|
release_date = None
|
|
424
421
|
if date_str:
|
|
425
|
-
|
|
422
|
+
with contextlib.suppress(Exception):
|
|
426
423
|
release_date = datetime.strptime(date_str, "%Y-%m-%d")
|
|
427
|
-
except:
|
|
428
|
-
pass
|
|
429
424
|
|
|
430
425
|
# Extract changes for this version
|
|
431
426
|
changes = self._extract_changelog_changes(
|
|
@@ -25,11 +25,9 @@ class VersionService(BaseService, VersionServiceInterface):
|
|
|
25
25
|
|
|
26
26
|
async def _initialize(self) -> None:
|
|
27
27
|
"""Initialize the service. No special initialization needed."""
|
|
28
|
-
pass
|
|
29
28
|
|
|
30
29
|
async def _cleanup(self) -> None:
|
|
31
30
|
"""Cleanup service resources. No cleanup needed."""
|
|
32
|
-
pass
|
|
33
31
|
|
|
34
32
|
def get_version(self) -> str:
|
|
35
33
|
"""
|
|
@@ -134,12 +132,16 @@ class VersionService(BaseService, VersionServiceInterface):
|
|
|
134
132
|
if build_file.exists():
|
|
135
133
|
build_content = build_file.read_text().strip()
|
|
136
134
|
build_number = int(build_content)
|
|
137
|
-
self.logger.debug(
|
|
135
|
+
self.logger.debug(
|
|
136
|
+
f"Build number obtained from {build_file}: {build_number}"
|
|
137
|
+
)
|
|
138
138
|
return build_number
|
|
139
|
-
except (
|
|
139
|
+
except (OSError, ValueError) as e:
|
|
140
140
|
self.logger.debug(f"Could not read BUILD_NUMBER from {build_file}: {e}")
|
|
141
141
|
except Exception as e:
|
|
142
|
-
self.logger.debug(
|
|
142
|
+
self.logger.debug(
|
|
143
|
+
f"Unexpected error reading BUILD_NUMBER from {build_file}: {e}"
|
|
144
|
+
)
|
|
143
145
|
|
|
144
146
|
return None
|
|
145
147
|
|
|
@@ -162,8 +164,7 @@ class VersionService(BaseService, VersionServiceInterface):
|
|
|
162
164
|
if build_number is not None:
|
|
163
165
|
# UI/logging format with 'v' prefix and dash separator
|
|
164
166
|
return f"v{version}-build.{build_number}"
|
|
165
|
-
|
|
166
|
-
return f"v{version}"
|
|
167
|
+
return f"v{version}"
|
|
167
168
|
|
|
168
169
|
def get_base_version(self) -> str:
|
|
169
170
|
"""Get base version without build number.
|
|
@@ -222,8 +223,7 @@ class VersionService(BaseService, VersionServiceInterface):
|
|
|
222
223
|
|
|
223
224
|
if build_number is not None:
|
|
224
225
|
return f"{base_version}+build.{build_number}"
|
|
225
|
-
|
|
226
|
-
return base_version
|
|
226
|
+
return base_version
|
|
227
227
|
|
|
228
228
|
# Implementation of abstract methods from VersionServiceInterface
|
|
229
229
|
|
|
@@ -256,8 +256,7 @@ class VersionService(BaseService, VersionServiceInterface):
|
|
|
256
256
|
"""
|
|
257
257
|
if include_build:
|
|
258
258
|
return self.get_version() # Already includes build number
|
|
259
|
-
|
|
260
|
-
return self.get_base_version()
|
|
259
|
+
return self.get_base_version()
|
|
261
260
|
|
|
262
261
|
def check_for_updates(self) -> Dict[str, Any]:
|
|
263
262
|
"""Check for available updates.
|
claude_mpm/storage/__init__.py
CHANGED
|
@@ -20,12 +20,10 @@ import logging
|
|
|
20
20
|
import os
|
|
21
21
|
import pickle
|
|
22
22
|
import platform
|
|
23
|
-
import shutil
|
|
24
23
|
import tempfile
|
|
25
24
|
import time
|
|
26
|
-
from contextlib import contextmanager
|
|
27
|
-
from
|
|
28
|
-
from typing import Any, BinaryIO, Dict, Optional, TextIO, Union
|
|
25
|
+
from contextlib import contextmanager, suppress
|
|
26
|
+
from typing import Any, Dict, Optional, Tuple, Union
|
|
29
27
|
|
|
30
28
|
|
|
31
29
|
class StateStorage:
|
|
@@ -76,17 +74,16 @@ class StateStorage:
|
|
|
76
74
|
return self._atomic_write(
|
|
77
75
|
file_path, data, serializer="json", compress=compress
|
|
78
76
|
)
|
|
77
|
+
# Direct write (not atomic)
|
|
78
|
+
if compress:
|
|
79
|
+
with gzip.open(file_path, "wt", encoding="utf-8") as f:
|
|
80
|
+
json.dump(data, f, indent=2, default=str)
|
|
79
81
|
else:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
with gzip.open(file_path, "wt", encoding="utf-8") as f:
|
|
83
|
-
json.dump(data, f, indent=2, default=str)
|
|
84
|
-
else:
|
|
85
|
-
with open(file_path, "w") as f:
|
|
86
|
-
json.dump(data, f, indent=2, default=str)
|
|
82
|
+
with open(file_path, "w") as f:
|
|
83
|
+
json.dump(data, f, indent=2, default=str)
|
|
87
84
|
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
self.write_count += 1
|
|
86
|
+
return True
|
|
90
87
|
|
|
91
88
|
except Exception as e:
|
|
92
89
|
self.logger.error(f"Failed to write JSON to {file_path}: {e}")
|
|
@@ -121,7 +118,7 @@ class StateStorage:
|
|
|
121
118
|
with gzip.open(file_path, "rt", encoding="utf-8") as f:
|
|
122
119
|
data = json.load(f)
|
|
123
120
|
else:
|
|
124
|
-
with open(file_path
|
|
121
|
+
with open(file_path) as f:
|
|
125
122
|
data = json.load(f)
|
|
126
123
|
|
|
127
124
|
self.read_count += 1
|
|
@@ -157,17 +154,16 @@ class StateStorage:
|
|
|
157
154
|
return self._atomic_write(
|
|
158
155
|
file_path, data, serializer="pickle", compress=compress
|
|
159
156
|
)
|
|
157
|
+
# Direct write (not atomic)
|
|
158
|
+
if compress:
|
|
159
|
+
with gzip.open(file_path, "wb") as f:
|
|
160
|
+
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
|
|
160
161
|
else:
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
with gzip.open(file_path, "wb") as f:
|
|
164
|
-
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
|
|
165
|
-
else:
|
|
166
|
-
with open(file_path, "wb") as f:
|
|
167
|
-
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
|
|
162
|
+
with open(file_path, "wb") as f:
|
|
163
|
+
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
|
|
168
164
|
|
|
169
|
-
|
|
170
|
-
|
|
165
|
+
self.write_count += 1
|
|
166
|
+
return True
|
|
171
167
|
|
|
172
168
|
except Exception as e:
|
|
173
169
|
self.logger.error(f"Failed to write pickle to {file_path}: {e}")
|
|
@@ -307,7 +303,7 @@ class StateStorage:
|
|
|
307
303
|
try:
|
|
308
304
|
fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
|
|
309
305
|
break
|
|
310
|
-
except
|
|
306
|
+
except OSError:
|
|
311
307
|
if attempt == max_attempts - 1:
|
|
312
308
|
raise
|
|
313
309
|
time.sleep(0.1)
|
|
@@ -316,10 +312,8 @@ class StateStorage:
|
|
|
316
312
|
|
|
317
313
|
finally:
|
|
318
314
|
if f:
|
|
319
|
-
|
|
315
|
+
with suppress(Exception):
|
|
320
316
|
fcntl.flock(f.fileno(), fcntl.LOCK_UN)
|
|
321
|
-
except:
|
|
322
|
-
pass
|
|
323
317
|
f.close()
|
|
324
318
|
|
|
325
319
|
def _add_checksum(self, file_path: Union[str, Path]) -> None:
|
|
@@ -364,7 +358,7 @@ class StateStorage:
|
|
|
364
358
|
return True # No checksum to verify
|
|
365
359
|
|
|
366
360
|
# Read expected checksum
|
|
367
|
-
with open(checksum_path
|
|
361
|
+
with open(checksum_path) as f:
|
|
368
362
|
expected = f.read().strip()
|
|
369
363
|
|
|
370
364
|
# Calculate actual checksum
|
claude_mpm/utils/__init__.py
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
# Delay imports to avoid circular dependencies
|
|
4
4
|
__all__ = [
|
|
5
|
+
"ConfigurationManager",
|
|
6
|
+
"find_file_upwards",
|
|
7
|
+
"get_framework_root",
|
|
5
8
|
"get_logger",
|
|
6
|
-
"setup_logging",
|
|
7
|
-
"safe_import",
|
|
8
|
-
"safe_import_multiple",
|
|
9
9
|
"get_path_manager()",
|
|
10
|
-
"get_framework_root",
|
|
11
10
|
"get_project_root",
|
|
12
|
-
"find_file_upwards",
|
|
13
|
-
"ConfigurationManager",
|
|
14
11
|
"load_config",
|
|
12
|
+
"safe_import",
|
|
13
|
+
"safe_import_multiple",
|
|
15
14
|
"save_config",
|
|
15
|
+
"setup_logging",
|
|
16
16
|
]
|