claude-mpm 3.9.11__py3-none-any.whl → 4.0.3__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/__init__.py +2 -2
- claude_mpm/__main__.py +3 -2
- claude_mpm/agents/__init__.py +85 -79
- claude_mpm/agents/agent_loader.py +464 -1003
- claude_mpm/agents/agent_loader_integration.py +45 -45
- claude_mpm/agents/agents_metadata.py +29 -30
- claude_mpm/agents/async_agent_loader.py +156 -138
- claude_mpm/agents/base_agent.json +1 -1
- claude_mpm/agents/base_agent_loader.py +179 -151
- claude_mpm/agents/frontmatter_validator.py +229 -130
- claude_mpm/agents/schema/agent_schema.json +1 -1
- claude_mpm/agents/system_agent_config.py +213 -147
- claude_mpm/agents/templates/__init__.py +13 -13
- claude_mpm/agents/templates/code_analyzer.json +2 -2
- claude_mpm/agents/templates/data_engineer.json +1 -1
- claude_mpm/agents/templates/documentation.json +23 -11
- claude_mpm/agents/templates/engineer.json +22 -6
- claude_mpm/agents/templates/memory_manager.json +1 -1
- claude_mpm/agents/templates/ops.json +2 -2
- claude_mpm/agents/templates/project_organizer.json +1 -1
- claude_mpm/agents/templates/qa.json +1 -1
- claude_mpm/agents/templates/refactoring_engineer.json +222 -0
- claude_mpm/agents/templates/research.json +20 -14
- claude_mpm/agents/templates/security.json +1 -1
- claude_mpm/agents/templates/ticketing.json +1 -1
- claude_mpm/agents/templates/version_control.json +1 -1
- claude_mpm/agents/templates/web_qa.json +3 -1
- claude_mpm/agents/templates/web_ui.json +2 -2
- claude_mpm/cli/__init__.py +79 -51
- claude_mpm/cli/__main__.py +3 -2
- claude_mpm/cli/commands/__init__.py +20 -20
- claude_mpm/cli/commands/agents.py +279 -247
- claude_mpm/cli/commands/aggregate.py +138 -157
- claude_mpm/cli/commands/cleanup.py +147 -147
- claude_mpm/cli/commands/config.py +93 -76
- claude_mpm/cli/commands/info.py +17 -16
- claude_mpm/cli/commands/mcp.py +140 -905
- claude_mpm/cli/commands/mcp_command_router.py +139 -0
- claude_mpm/cli/commands/mcp_config_commands.py +20 -0
- claude_mpm/cli/commands/mcp_install_commands.py +20 -0
- claude_mpm/cli/commands/mcp_server_commands.py +175 -0
- claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
- claude_mpm/cli/commands/memory.py +239 -203
- claude_mpm/cli/commands/monitor.py +203 -81
- claude_mpm/cli/commands/run.py +380 -429
- claude_mpm/cli/commands/run_config_checker.py +160 -0
- claude_mpm/cli/commands/socketio_monitor.py +235 -0
- claude_mpm/cli/commands/tickets.py +305 -197
- claude_mpm/cli/parser.py +24 -1156
- claude_mpm/cli/parsers/__init__.py +29 -0
- claude_mpm/cli/parsers/agents_parser.py +136 -0
- claude_mpm/cli/parsers/base_parser.py +331 -0
- claude_mpm/cli/parsers/config_parser.py +85 -0
- claude_mpm/cli/parsers/mcp_parser.py +152 -0
- claude_mpm/cli/parsers/memory_parser.py +138 -0
- claude_mpm/cli/parsers/monitor_parser.py +104 -0
- claude_mpm/cli/parsers/run_parser.py +147 -0
- claude_mpm/cli/parsers/tickets_parser.py +203 -0
- claude_mpm/cli/ticket_cli.py +7 -3
- claude_mpm/cli/utils.py +55 -37
- claude_mpm/cli_module/__init__.py +6 -6
- claude_mpm/cli_module/args.py +188 -140
- claude_mpm/cli_module/commands.py +79 -70
- claude_mpm/cli_module/migration_example.py +38 -60
- claude_mpm/config/__init__.py +32 -25
- claude_mpm/config/agent_config.py +151 -119
- claude_mpm/config/experimental_features.py +71 -73
- claude_mpm/config/paths.py +94 -208
- claude_mpm/config/socketio_config.py +84 -73
- claude_mpm/constants.py +35 -18
- claude_mpm/core/__init__.py +9 -6
- claude_mpm/core/agent_name_normalizer.py +68 -71
- claude_mpm/core/agent_registry.py +372 -521
- claude_mpm/core/agent_session_manager.py +74 -63
- claude_mpm/core/base_service.py +116 -87
- claude_mpm/core/cache.py +119 -153
- claude_mpm/core/claude_runner.py +425 -1120
- claude_mpm/core/config.py +263 -168
- claude_mpm/core/config_aliases.py +69 -61
- claude_mpm/core/config_constants.py +292 -0
- claude_mpm/core/constants.py +57 -99
- claude_mpm/core/container.py +211 -178
- claude_mpm/core/exceptions.py +233 -89
- claude_mpm/core/factories.py +92 -54
- claude_mpm/core/framework_loader.py +378 -220
- claude_mpm/core/hook_manager.py +198 -83
- claude_mpm/core/hook_performance_config.py +136 -0
- claude_mpm/core/injectable_service.py +61 -55
- claude_mpm/core/interactive_session.py +165 -155
- claude_mpm/core/interfaces.py +221 -195
- claude_mpm/core/lazy.py +96 -96
- claude_mpm/core/logger.py +133 -107
- claude_mpm/core/logging_config.py +185 -157
- claude_mpm/core/minimal_framework_loader.py +20 -15
- claude_mpm/core/mixins.py +30 -29
- claude_mpm/core/oneshot_session.py +215 -181
- claude_mpm/core/optimized_agent_loader.py +134 -138
- claude_mpm/core/optimized_startup.py +159 -157
- claude_mpm/core/pm_hook_interceptor.py +85 -72
- claude_mpm/core/service_registry.py +103 -101
- claude_mpm/core/session_manager.py +97 -87
- claude_mpm/core/socketio_pool.py +212 -158
- claude_mpm/core/tool_access_control.py +58 -51
- claude_mpm/core/types.py +46 -24
- claude_mpm/core/typing_utils.py +166 -82
- claude_mpm/core/unified_agent_registry.py +721 -0
- claude_mpm/core/unified_config.py +550 -0
- claude_mpm/core/unified_paths.py +549 -0
- claude_mpm/dashboard/index.html +1 -1
- claude_mpm/dashboard/open_dashboard.py +51 -17
- claude_mpm/dashboard/static/css/dashboard.css +27 -8
- claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
- claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
- claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
- claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
- claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
- claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
- claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
- claude_mpm/dashboard/static/dist/dashboard.js +2 -0
- claude_mpm/dashboard/static/dist/socket-client.js +2 -0
- claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
- claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
- claude_mpm/dashboard/static/js/components/event-viewer.js +74 -70
- claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +106 -92
- claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
- claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
- claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
- claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
- claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
- claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
- claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
- claude_mpm/dashboard/static/js/dashboard.js +178 -453
- claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
- claude_mpm/dashboard/static/js/socket-client.js +120 -54
- claude_mpm/dashboard/templates/index.html +40 -50
- claude_mpm/experimental/cli_enhancements.py +60 -58
- claude_mpm/generators/__init__.py +1 -1
- claude_mpm/generators/agent_profile_generator.py +75 -65
- claude_mpm/hooks/__init__.py +1 -1
- claude_mpm/hooks/base_hook.py +33 -28
- claude_mpm/hooks/claude_hooks/__init__.py +1 -1
- claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
- claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
- claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
- claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
- claude_mpm/hooks/memory_integration_hook.py +140 -100
- claude_mpm/hooks/tool_call_interceptor.py +89 -76
- claude_mpm/hooks/validation_hooks.py +57 -49
- claude_mpm/init.py +145 -121
- claude_mpm/models/__init__.py +9 -9
- claude_mpm/models/agent_definition.py +33 -23
- claude_mpm/models/agent_session.py +228 -200
- claude_mpm/scripts/__init__.py +1 -1
- claude_mpm/scripts/socketio_daemon.py +192 -75
- claude_mpm/scripts/socketio_server_manager.py +328 -0
- claude_mpm/scripts/start_activity_logging.py +25 -22
- claude_mpm/services/__init__.py +68 -43
- claude_mpm/services/agent_capabilities_service.py +271 -0
- claude_mpm/services/agents/__init__.py +23 -32
- claude_mpm/services/agents/deployment/__init__.py +3 -3
- claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
- claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
- claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
- claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
- claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
- claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
- claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
- claude_mpm/services/agents/deployment/agent_validator.py +352 -0
- claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
- claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
- claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
- claude_mpm/services/agents/deployment/config/__init__.py +13 -0
- claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
- claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
- claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
- claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
- claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
- claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
- claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
- claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
- claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
- claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
- claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
- claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
- claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
- claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
- claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
- claude_mpm/services/agents/deployment/results/__init__.py +13 -0
- claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
- claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
- claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
- claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
- claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
- claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
- claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
- claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
- claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
- claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
- claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
- claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
- claude_mpm/services/agents/loading/__init__.py +2 -2
- claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
- claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
- claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
- claude_mpm/services/agents/management/__init__.py +2 -2
- claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
- claude_mpm/services/agents/management/agent_management_service.py +209 -156
- claude_mpm/services/agents/memory/__init__.py +9 -6
- claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
- claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
- claude_mpm/services/agents/memory/analyzer.py +430 -0
- claude_mpm/services/agents/memory/content_manager.py +376 -0
- claude_mpm/services/agents/memory/template_generator.py +468 -0
- claude_mpm/services/agents/registry/__init__.py +7 -10
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
- claude_mpm/services/agents/registry/modification_tracker.py +351 -285
- claude_mpm/services/async_session_logger.py +187 -153
- claude_mpm/services/claude_session_logger.py +87 -72
- claude_mpm/services/command_handler_service.py +217 -0
- claude_mpm/services/communication/__init__.py +3 -2
- claude_mpm/services/core/__init__.py +50 -97
- claude_mpm/services/core/base.py +60 -53
- claude_mpm/services/core/interfaces/__init__.py +188 -0
- claude_mpm/services/core/interfaces/agent.py +351 -0
- claude_mpm/services/core/interfaces/communication.py +343 -0
- claude_mpm/services/core/interfaces/infrastructure.py +413 -0
- claude_mpm/services/core/interfaces/service.py +434 -0
- claude_mpm/services/core/interfaces.py +19 -944
- claude_mpm/services/event_aggregator.py +208 -170
- claude_mpm/services/exceptions.py +387 -308
- claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
- claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
- claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
- claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
- claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
- claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
- claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
- claude_mpm/services/hook_service.py +106 -114
- claude_mpm/services/infrastructure/__init__.py +7 -5
- claude_mpm/services/infrastructure/context_preservation.py +233 -199
- claude_mpm/services/infrastructure/daemon_manager.py +279 -0
- claude_mpm/services/infrastructure/logging.py +83 -76
- claude_mpm/services/infrastructure/monitoring.py +547 -404
- claude_mpm/services/mcp_gateway/__init__.py +30 -13
- claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
- claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
- claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
- claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
- claude_mpm/services/mcp_gateway/core/__init__.py +13 -20
- claude_mpm/services/mcp_gateway/core/base.py +80 -67
- claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
- claude_mpm/services/mcp_gateway/core/interfaces.py +87 -84
- claude_mpm/services/mcp_gateway/main.py +287 -137
- claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
- claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
- claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
- claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +109 -119
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
- claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
- claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
- claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
- claude_mpm/services/memory/__init__.py +2 -2
- claude_mpm/services/memory/builder.py +451 -362
- claude_mpm/services/memory/cache/__init__.py +2 -2
- claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
- claude_mpm/services/memory/cache/simple_cache.py +107 -93
- claude_mpm/services/memory/indexed_memory.py +195 -193
- claude_mpm/services/memory/optimizer.py +267 -234
- claude_mpm/services/memory/router.py +571 -263
- claude_mpm/services/memory_hook_service.py +237 -0
- claude_mpm/services/port_manager.py +223 -0
- claude_mpm/services/project/__init__.py +3 -3
- claude_mpm/services/project/analyzer.py +451 -305
- claude_mpm/services/project/registry.py +262 -240
- claude_mpm/services/recovery_manager.py +287 -231
- claude_mpm/services/response_tracker.py +87 -67
- claude_mpm/services/runner_configuration_service.py +587 -0
- claude_mpm/services/session_management_service.py +304 -0
- claude_mpm/services/socketio/__init__.py +4 -4
- claude_mpm/services/socketio/client_proxy.py +174 -0
- claude_mpm/services/socketio/handlers/__init__.py +3 -3
- claude_mpm/services/socketio/handlers/base.py +44 -30
- claude_mpm/services/socketio/handlers/connection.py +145 -65
- claude_mpm/services/socketio/handlers/file.py +123 -108
- claude_mpm/services/socketio/handlers/git.py +607 -373
- claude_mpm/services/socketio/handlers/hook.py +170 -0
- claude_mpm/services/socketio/handlers/memory.py +4 -4
- claude_mpm/services/socketio/handlers/project.py +4 -4
- claude_mpm/services/socketio/handlers/registry.py +53 -38
- claude_mpm/services/socketio/server/__init__.py +18 -0
- claude_mpm/services/socketio/server/broadcaster.py +252 -0
- claude_mpm/services/socketio/server/core.py +399 -0
- claude_mpm/services/socketio/server/main.py +323 -0
- claude_mpm/services/socketio_client_manager.py +160 -133
- claude_mpm/services/socketio_server.py +36 -1885
- claude_mpm/services/subprocess_launcher_service.py +316 -0
- claude_mpm/services/system_instructions_service.py +258 -0
- claude_mpm/services/ticket_manager.py +19 -533
- claude_mpm/services/utility_service.py +285 -0
- claude_mpm/services/version_control/__init__.py +18 -21
- claude_mpm/services/version_control/branch_strategy.py +20 -10
- claude_mpm/services/version_control/conflict_resolution.py +37 -13
- claude_mpm/services/version_control/git_operations.py +52 -21
- claude_mpm/services/version_control/semantic_versioning.py +92 -53
- claude_mpm/services/version_control/version_parser.py +145 -125
- claude_mpm/services/version_service.py +270 -0
- claude_mpm/storage/__init__.py +2 -2
- claude_mpm/storage/state_storage.py +177 -181
- claude_mpm/ticket_wrapper.py +2 -2
- claude_mpm/utils/__init__.py +2 -2
- claude_mpm/utils/agent_dependency_loader.py +453 -243
- claude_mpm/utils/config_manager.py +157 -118
- claude_mpm/utils/console.py +1 -1
- claude_mpm/utils/dependency_cache.py +102 -107
- claude_mpm/utils/dependency_manager.py +52 -47
- claude_mpm/utils/dependency_strategies.py +131 -96
- claude_mpm/utils/environment_context.py +110 -102
- claude_mpm/utils/error_handler.py +75 -55
- claude_mpm/utils/file_utils.py +80 -67
- claude_mpm/utils/framework_detection.py +12 -11
- claude_mpm/utils/import_migration_example.py +12 -60
- claude_mpm/utils/imports.py +48 -45
- claude_mpm/utils/path_operations.py +100 -93
- claude_mpm/utils/robust_installer.py +172 -164
- claude_mpm/utils/session_logging.py +30 -23
- claude_mpm/utils/subprocess_utils.py +99 -61
- claude_mpm/validation/__init__.py +1 -1
- claude_mpm/validation/agent_validator.py +151 -111
- claude_mpm/validation/frontmatter_validator.py +92 -71
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/METADATA +27 -1
- claude_mpm-4.0.3.dist-info/RECORD +402 -0
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/entry_points.txt +1 -0
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/licenses/LICENSE +1 -1
- claude_mpm/cli/commands/run_guarded.py +0 -511
- claude_mpm/config/memory_guardian_config.py +0 -325
- claude_mpm/config/memory_guardian_yaml.py +0 -335
- claude_mpm/core/config_paths.py +0 -150
- claude_mpm/core/memory_aware_runner.py +0 -353
- claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
- claude_mpm/deployment_paths.py +0 -261
- claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
- claude_mpm/models/state_models.py +0 -433
- claude_mpm/services/agent/__init__.py +0 -24
- claude_mpm/services/agent/deployment.py +0 -2548
- claude_mpm/services/agent/management.py +0 -598
- claude_mpm/services/agent/registry.py +0 -813
- claude_mpm/services/agents/registry/agent_registry.py +0 -813
- claude_mpm/services/communication/socketio.py +0 -1935
- claude_mpm/services/communication/websocket.py +0 -479
- claude_mpm/services/framework_claude_md_generator.py +0 -624
- claude_mpm/services/health_monitor.py +0 -893
- claude_mpm/services/infrastructure/graceful_degradation.py +0 -616
- claude_mpm/services/infrastructure/health_monitor.py +0 -775
- claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
- claude_mpm/services/infrastructure/memory_guardian.py +0 -944
- claude_mpm/services/infrastructure/restart_protection.py +0 -642
- claude_mpm/services/infrastructure/state_manager.py +0 -774
- claude_mpm/services/mcp_gateway/manager.py +0 -334
- claude_mpm/services/optimized_hook_service.py +0 -542
- claude_mpm/services/project_analyzer.py +0 -864
- claude_mpm/services/project_registry.py +0 -608
- claude_mpm/services/standalone_socketio_server.py +0 -1300
- claude_mpm/services/ticket_manager_di.py +0 -318
- claude_mpm/services/ticketing_service_original.py +0 -510
- claude_mpm/utils/paths.py +0 -395
- claude_mpm/utils/platform_memory.py +0 -524
- claude_mpm-3.9.11.dist-info/RECORD +0 -306
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/WHEEL +0 -0
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/top_level.txt +0 -0
    
        claude_mpm/core/lazy.py
    CHANGED
    
    | @@ -15,18 +15,19 @@ import asyncio | |
| 15 15 | 
             
            import functools
         | 
| 16 16 | 
             
            import threading
         | 
| 17 17 | 
             
            import time
         | 
| 18 | 
            -
            from typing import Any, Callable, Dict, Optional, Type, TypeVar, Generic
         | 
| 19 | 
            -
            from datetime import datetime
         | 
| 20 18 | 
             
            from dataclasses import dataclass, field
         | 
| 19 | 
            +
            from datetime import datetime
         | 
| 20 | 
            +
            from typing import Any, Callable, Dict, Generic, Optional, Type, TypeVar
         | 
| 21 21 |  | 
| 22 22 | 
             
            from ..core.logger import get_logger
         | 
| 23 23 |  | 
| 24 | 
            -
            T = TypeVar( | 
| 24 | 
            +
            T = TypeVar("T")
         | 
| 25 25 |  | 
| 26 26 |  | 
| 27 27 | 
             
            @dataclass
         | 
| 28 28 | 
             
            class LazyMetrics:
         | 
| 29 29 | 
             
                """Metrics for lazy loading performance."""
         | 
| 30 | 
            +
             | 
| 30 31 | 
             
                created_at: datetime = field(default_factory=datetime.now)
         | 
| 31 32 | 
             
                first_access: Optional[datetime] = None
         | 
| 32 33 | 
             
                initialization_time: float = 0.0
         | 
| @@ -37,13 +38,13 @@ class LazyMetrics: | |
| 37 38 |  | 
| 38 39 | 
             
            class LazyService(Generic[T]):
         | 
| 39 40 | 
             
                """Lazy loading wrapper for expensive services.
         | 
| 40 | 
            -
             | 
| 41 | 
            +
             | 
| 41 42 | 
             
                WHY this design:
         | 
| 42 43 | 
             
                - Services are only initialized when first accessed
         | 
| 43 44 | 
             
                - Thread-safe initialization ensures single instance
         | 
| 44 45 | 
             
                - Transparent proxy pattern preserves service interface
         | 
| 45 46 | 
             
                - Metrics tracking for performance monitoring
         | 
| 46 | 
            -
             | 
| 47 | 
            +
             | 
| 47 48 | 
             
                Example:
         | 
| 48 49 | 
             
                    # Wrap expensive service
         | 
| 49 50 | 
             
                    lazy_analyzer = LazyService(
         | 
| @@ -51,31 +52,31 @@ class LazyService(Generic[T]): | |
| 51 52 | 
             
                        init_args=(),
         | 
| 52 53 | 
             
                        init_kwargs={'config': config}
         | 
| 53 54 | 
             
                    )
         | 
| 54 | 
            -
             | 
| 55 | 
            +
             | 
| 55 56 | 
             
                    # Service is not initialized yet
         | 
| 56 57 | 
             
                    assert not lazy_analyzer.is_initialized
         | 
| 57 | 
            -
             | 
| 58 | 
            +
             | 
| 58 59 | 
             
                    # First access triggers initialization
         | 
| 59 60 | 
             
                    result = lazy_analyzer.analyze()  # Initializes here
         | 
| 60 | 
            -
             | 
| 61 | 
            +
             | 
| 61 62 | 
             
                    # Subsequent accesses use cached instance
         | 
| 62 63 | 
             
                    result2 = lazy_analyzer.analyze()  # No initialization
         | 
| 63 64 | 
             
                """
         | 
| 64 | 
            -
             | 
| 65 | 
            +
             | 
| 65 66 | 
             
                def __init__(
         | 
| 66 67 | 
             
                    self,
         | 
| 67 68 | 
             
                    service_class: Type[T],
         | 
| 68 69 | 
             
                    init_args: tuple = (),
         | 
| 69 70 | 
             
                    init_kwargs: dict = None,
         | 
| 70 71 | 
             
                    name: Optional[str] = None,
         | 
| 71 | 
            -
                    eager: bool = False
         | 
| 72 | 
            +
                    eager: bool = False,
         | 
| 72 73 | 
             
                ):
         | 
| 73 74 | 
             
                    """Initialize lazy service wrapper.
         | 
| 74 | 
            -
             | 
| 75 | 
            +
             | 
| 75 76 | 
             
                    Args:
         | 
| 76 77 | 
             
                        service_class: The class to lazily instantiate
         | 
| 77 78 | 
             
                        init_args: Positional arguments for initialization
         | 
| 78 | 
            -
                        init_kwargs: Keyword arguments for initialization | 
| 79 | 
            +
                        init_kwargs: Keyword arguments for initialization
         | 
| 79 80 | 
             
                        name: Optional name for logging
         | 
| 80 81 | 
             
                        eager: If True, initialize immediately (for testing)
         | 
| 81 82 | 
             
                    """
         | 
| @@ -84,92 +85,93 @@ class LazyService(Generic[T]): | |
| 84 85 | 
             
                    self._init_kwargs = init_kwargs or {}
         | 
| 85 86 | 
             
                    self._name = name or service_class.__name__
         | 
| 86 87 | 
             
                    self._eager = eager
         | 
| 87 | 
            -
             | 
| 88 | 
            +
             | 
| 88 89 | 
             
                    self._instance: Optional[T] = None
         | 
| 89 90 | 
             
                    self._lock = threading.RLock()
         | 
| 90 91 | 
             
                    self._metrics = LazyMetrics()
         | 
| 91 92 | 
             
                    self._logger = get_logger(f"lazy.{self._name}")
         | 
| 92 | 
            -
             | 
| 93 | 
            +
             | 
| 93 94 | 
             
                    # Initialize immediately if eager mode
         | 
| 94 95 | 
             
                    if eager:
         | 
| 95 96 | 
             
                        self._ensure_initialized()
         | 
| 96 | 
            -
             | 
| 97 | 
            +
             | 
| 97 98 | 
             
                @property
         | 
| 98 99 | 
             
                def is_initialized(self) -> bool:
         | 
| 99 100 | 
             
                    """Check if service has been initialized."""
         | 
| 100 101 | 
             
                    return self._instance is not None
         | 
| 101 | 
            -
             | 
| 102 | 
            +
             | 
| 102 103 | 
             
                @property
         | 
| 103 104 | 
             
                def metrics(self) -> LazyMetrics:
         | 
| 104 105 | 
             
                    """Get lazy loading metrics."""
         | 
| 105 106 | 
             
                    return self._metrics
         | 
| 106 | 
            -
             | 
| 107 | 
            +
             | 
| 107 108 | 
             
                def _ensure_initialized(self) -> T:
         | 
| 108 109 | 
             
                    """Ensure service is initialized, creating if necessary.
         | 
| 109 | 
            -
             | 
| 110 | 
            +
             | 
| 110 111 | 
             
                    Thread-safe initialization with metrics tracking.
         | 
| 111 112 | 
             
                    """
         | 
| 112 113 | 
             
                    if self._instance is not None:
         | 
| 113 114 | 
             
                        return self._instance
         | 
| 114 | 
            -
             | 
| 115 | 
            +
             | 
| 115 116 | 
             
                    with self._lock:
         | 
| 116 117 | 
             
                        # Double-check pattern for thread safety
         | 
| 117 118 | 
             
                        if self._instance is not None:
         | 
| 118 119 | 
             
                            return self._instance
         | 
| 119 | 
            -
             | 
| 120 | 
            +
             | 
| 120 121 | 
             
                        # Track initialization
         | 
| 121 122 | 
             
                        start_time = time.time()
         | 
| 122 123 | 
             
                        if self._metrics.first_access is None:
         | 
| 123 124 | 
             
                            self._metrics.first_access = datetime.now()
         | 
| 124 | 
            -
             | 
| 125 | 
            +
             | 
| 125 126 | 
             
                        try:
         | 
| 126 127 | 
             
                            self._logger.debug(f"Initializing lazy service: {self._name}")
         | 
| 127 | 
            -
             | 
| 128 | 
            +
             | 
| 128 129 | 
             
                            # Create the actual service instance
         | 
| 129 130 | 
             
                            self._instance = self._service_class(
         | 
| 130 | 
            -
                                *self._init_args,
         | 
| 131 | 
            -
                                **self._init_kwargs
         | 
| 131 | 
            +
                                *self._init_args, **self._init_kwargs
         | 
| 132 132 | 
             
                            )
         | 
| 133 | 
            -
             | 
| 133 | 
            +
             | 
| 134 134 | 
             
                            # Update metrics
         | 
| 135 135 | 
             
                            self._metrics.initialization_time = time.time() - start_time
         | 
| 136 136 | 
             
                            self._metrics.is_initialized = True
         | 
| 137 | 
            -
             | 
| 137 | 
            +
             | 
| 138 138 | 
             
                            self._logger.info(
         | 
| 139 139 | 
             
                                f"Lazy service {self._name} initialized in "
         | 
| 140 140 | 
             
                                f"{self._metrics.initialization_time:.2f}s"
         | 
| 141 141 | 
             
                            )
         | 
| 142 | 
            -
             | 
| 142 | 
            +
             | 
| 143 143 | 
             
                            return self._instance
         | 
| 144 | 
            -
             | 
| 144 | 
            +
             | 
| 145 145 | 
             
                        except Exception as e:
         | 
| 146 146 | 
             
                            self._metrics.initialization_error = e
         | 
| 147 147 | 
             
                            self._logger.error(f"Failed to initialize {self._name}: {e}")
         | 
| 148 148 | 
             
                            raise
         | 
| 149 | 
            -
             | 
| 149 | 
            +
             | 
| 150 150 | 
             
                def __getattr__(self, name: str) -> Any:
         | 
| 151 151 | 
             
                    """Proxy attribute access to the underlying service.
         | 
| 152 | 
            -
             | 
| 152 | 
            +
             | 
| 153 153 | 
             
                    This is called when an attribute is not found on LazyService itself.
         | 
| 154 154 | 
             
                    It ensures initialization and forwards the request.
         | 
| 155 155 | 
             
                    """
         | 
| 156 156 | 
             
                    # Avoid recursion for internal attributes
         | 
| 157 | 
            -
                    if name.startswith( | 
| 158 | 
            -
                        raise AttributeError( | 
| 159 | 
            -
             | 
| 157 | 
            +
                    if name.startswith("_"):
         | 
| 158 | 
            +
                        raise AttributeError(
         | 
| 159 | 
            +
                            f"'{type(self).__name__}' object has no attribute '{name}'"
         | 
| 160 | 
            +
                        )
         | 
| 161 | 
            +
             | 
| 160 162 | 
             
                    # Initialize if needed
         | 
| 161 163 | 
             
                    instance = self._ensure_initialized()
         | 
| 162 164 | 
             
                    self._metrics.access_count += 1
         | 
| 163 | 
            -
             | 
| 165 | 
            +
             | 
| 164 166 | 
             
                    # Forward attribute access
         | 
| 165 167 | 
             
                    return getattr(instance, name)
         | 
| 166 | 
            -
             | 
| 168 | 
            +
             | 
| 167 169 | 
             
                def __call__(self, *args, **kwargs) -> Any:
         | 
| 168 170 | 
             
                    """Make LazyService callable if underlying service is."""
         | 
| 169 171 | 
             
                    instance = self._ensure_initialized()
         | 
| 170 172 | 
             
                    self._metrics.access_count += 1
         | 
| 171 173 | 
             
                    return instance(*args, **kwargs)
         | 
| 172 | 
            -
             | 
| 174 | 
            +
             | 
| 173 175 | 
             
                def __repr__(self) -> str:
         | 
| 174 176 | 
             
                    """String representation of lazy service."""
         | 
| 175 177 | 
             
                    status = "initialized" if self.is_initialized else "pending"
         | 
| @@ -178,69 +180,69 @@ class LazyService(Generic[T]): | |
| 178 180 |  | 
| 179 181 | 
             
            class LazyServiceRegistry:
         | 
| 180 182 | 
             
                """Registry for managing lazy services.
         | 
| 181 | 
            -
             | 
| 183 | 
            +
             | 
| 182 184 | 
             
                WHY registry pattern:
         | 
| 183 185 | 
             
                - Central management of all lazy services
         | 
| 184 186 | 
             
                - Bulk initialization for testing
         | 
| 185 187 | 
             
                - Performance metrics aggregation
         | 
| 186 188 | 
             
                - Service dependency resolution
         | 
| 187 189 | 
             
                """
         | 
| 188 | 
            -
             | 
| 190 | 
            +
             | 
| 189 191 | 
             
                def __init__(self):
         | 
| 190 192 | 
             
                    self._services: Dict[str, LazyService] = {}
         | 
| 191 193 | 
             
                    self._logger = get_logger("lazy_registry")
         | 
| 192 194 | 
             
                    self._lock = threading.Lock()
         | 
| 193 | 
            -
             | 
| 195 | 
            +
             | 
| 194 196 | 
             
                def register(
         | 
| 195 197 | 
             
                    self,
         | 
| 196 198 | 
             
                    name: str,
         | 
| 197 199 | 
             
                    service_class: Type,
         | 
| 198 200 | 
             
                    init_args: tuple = (),
         | 
| 199 201 | 
             
                    init_kwargs: dict = None,
         | 
| 200 | 
            -
                    eager: bool = False
         | 
| 202 | 
            +
                    eager: bool = False,
         | 
| 201 203 | 
             
                ) -> LazyService:
         | 
| 202 204 | 
             
                    """Register a lazy service.
         | 
| 203 | 
            -
             | 
| 205 | 
            +
             | 
| 204 206 | 
             
                    Args:
         | 
| 205 207 | 
             
                        name: Unique name for the service
         | 
| 206 208 | 
             
                        service_class: The service class to wrap
         | 
| 207 209 | 
             
                        init_args: Initialization arguments
         | 
| 208 210 | 
             
                        init_kwargs: Initialization keyword arguments
         | 
| 209 211 | 
             
                        eager: Whether to initialize immediately
         | 
| 210 | 
            -
             | 
| 212 | 
            +
             | 
| 211 213 | 
             
                    Returns:
         | 
| 212 214 | 
             
                        The registered LazyService instance
         | 
| 213 215 | 
             
                    """
         | 
| 214 216 | 
             
                    with self._lock:
         | 
| 215 217 | 
             
                        if name in self._services:
         | 
| 216 218 | 
             
                            self._logger.warning(f"Overwriting existing service: {name}")
         | 
| 217 | 
            -
             | 
| 219 | 
            +
             | 
| 218 220 | 
             
                        service = LazyService(
         | 
| 219 221 | 
             
                            service_class=service_class,
         | 
| 220 222 | 
             
                            init_args=init_args,
         | 
| 221 223 | 
             
                            init_kwargs=init_kwargs,
         | 
| 222 224 | 
             
                            name=name,
         | 
| 223 | 
            -
                            eager=eager
         | 
| 225 | 
            +
                            eager=eager,
         | 
| 224 226 | 
             
                        )
         | 
| 225 | 
            -
             | 
| 227 | 
            +
             | 
| 226 228 | 
             
                        self._services[name] = service
         | 
| 227 229 | 
             
                        self._logger.debug(f"Registered lazy service: {name}")
         | 
| 228 230 | 
             
                        return service
         | 
| 229 | 
            -
             | 
| 231 | 
            +
             | 
| 230 232 | 
             
                def get(self, name: str) -> Optional[LazyService]:
         | 
| 231 233 | 
             
                    """Get a registered service by name."""
         | 
| 232 234 | 
             
                    return self._services.get(name)
         | 
| 233 | 
            -
             | 
| 235 | 
            +
             | 
| 234 236 | 
             
                def initialize_all(self) -> Dict[str, float]:
         | 
| 235 237 | 
             
                    """Initialize all registered services.
         | 
| 236 | 
            -
             | 
| 238 | 
            +
             | 
| 237 239 | 
             
                    Useful for testing or preloading.
         | 
| 238 | 
            -
             | 
| 240 | 
            +
             | 
| 239 241 | 
             
                    Returns:
         | 
| 240 242 | 
             
                        Dictionary mapping service names to initialization times
         | 
| 241 243 | 
             
                    """
         | 
| 242 244 | 
             
                    init_times = {}
         | 
| 243 | 
            -
             | 
| 245 | 
            +
             | 
| 244 246 | 
             
                    for name, service in self._services.items():
         | 
| 245 247 | 
             
                        if not service.is_initialized:
         | 
| 246 248 | 
             
                            try:
         | 
| @@ -249,13 +251,13 @@ class LazyServiceRegistry: | |
| 249 251 | 
             
                            except Exception as e:
         | 
| 250 252 | 
             
                                self._logger.error(f"Failed to initialize {name}: {e}")
         | 
| 251 253 | 
             
                                init_times[name] = -1.0
         | 
| 252 | 
            -
             | 
| 254 | 
            +
             | 
| 253 255 | 
             
                    return init_times
         | 
| 254 | 
            -
             | 
| 256 | 
            +
             | 
| 255 257 | 
             
                def get_metrics(self) -> Dict[str, Dict[str, Any]]:
         | 
| 256 258 | 
             
                    """Get metrics for all registered services."""
         | 
| 257 259 | 
             
                    metrics = {}
         | 
| 258 | 
            -
             | 
| 260 | 
            +
             | 
| 259 261 | 
             
                    for name, service in self._services.items():
         | 
| 260 262 | 
             
                        m = service.metrics
         | 
| 261 263 | 
             
                        metrics[name] = {
         | 
| @@ -263,11 +265,11 @@ class LazyServiceRegistry: | |
| 263 265 | 
             
                            "first_access": m.first_access.isoformat() if m.first_access else None,
         | 
| 264 266 | 
             
                            "initialization_time": m.initialization_time,
         | 
| 265 267 | 
             
                            "access_count": m.access_count,
         | 
| 266 | 
            -
                            "has_error": m.initialization_error is not None
         | 
| 268 | 
            +
                            "has_error": m.initialization_error is not None,
         | 
| 267 269 | 
             
                        }
         | 
| 268 | 
            -
             | 
| 270 | 
            +
             | 
| 269 271 | 
             
                    return metrics
         | 
| 270 | 
            -
             | 
| 272 | 
            +
             | 
| 271 273 | 
             
                def reset(self):
         | 
| 272 274 | 
             
                    """Clear all registered services."""
         | 
| 273 275 | 
             
                    with self._lock:
         | 
| @@ -283,37 +285,37 @@ def lazy_load( | |
| 283 285 | 
             
                service_class: Type,
         | 
| 284 286 | 
             
                name: Optional[str] = None,
         | 
| 285 287 | 
             
                init_args: tuple = (),
         | 
| 286 | 
            -
                init_kwargs: dict = None
         | 
| 288 | 
            +
                init_kwargs: dict = None,
         | 
| 287 289 | 
             
            ) -> LazyService:
         | 
| 288 290 | 
             
                """Convenience function to create and register a lazy service.
         | 
| 289 | 
            -
             | 
| 291 | 
            +
             | 
| 290 292 | 
             
                Args:
         | 
| 291 293 | 
             
                    service_class: The service class to wrap
         | 
| 292 294 | 
             
                    name: Optional name (defaults to class name)
         | 
| 293 295 | 
             
                    init_args: Initialization arguments
         | 
| 294 296 | 
             
                    init_kwargs: Initialization keyword arguments
         | 
| 295 | 
            -
             | 
| 297 | 
            +
             | 
| 296 298 | 
             
                Returns:
         | 
| 297 299 | 
             
                    Registered LazyService instance
         | 
| 298 | 
            -
             | 
| 300 | 
            +
             | 
| 299 301 | 
             
                Example:
         | 
| 300 302 | 
             
                    # Create lazy service
         | 
| 301 303 | 
             
                    analyzer = lazy_load(
         | 
| 302 304 | 
             
                        ProjectAnalyzer,
         | 
| 303 305 | 
             
                        init_kwargs={'config': config}
         | 
| 304 306 | 
             
                    )
         | 
| 305 | 
            -
             | 
| 307 | 
            +
             | 
| 306 308 | 
             
                    # Use like normal service
         | 
| 307 309 | 
             
                    result = analyzer.analyze_project()
         | 
| 308 310 | 
             
                """
         | 
| 309 311 | 
             
                if name is None:
         | 
| 310 312 | 
             
                    name = service_class.__name__
         | 
| 311 | 
            -
             | 
| 313 | 
            +
             | 
| 312 314 | 
             
                return _registry.register(
         | 
| 313 315 | 
             
                    name=name,
         | 
| 314 316 | 
             
                    service_class=service_class,
         | 
| 315 317 | 
             
                    init_args=init_args,
         | 
| 316 | 
            -
                    init_kwargs=init_kwargs
         | 
| 318 | 
            +
                    init_kwargs=init_kwargs,
         | 
| 317 319 | 
             
                )
         | 
| 318 320 |  | 
| 319 321 |  | 
| @@ -334,13 +336,13 @@ def initialize_all_services() -> Dict[str, float]: | |
| 334 336 |  | 
| 335 337 | 
             
            class lazy_property:
         | 
| 336 338 | 
             
                """Decorator for lazy property initialization.
         | 
| 337 | 
            -
             | 
| 339 | 
            +
             | 
| 338 340 | 
             
                WHY decorator pattern:
         | 
| 339 341 | 
             
                - Pythonic approach for lazy attributes
         | 
| 340 342 | 
             
                - Caches expensive computations
         | 
| 341 343 | 
             
                - Thread-safe initialization
         | 
| 342 344 | 
             
                - Transparent to callers
         | 
| 343 | 
            -
             | 
| 345 | 
            +
             | 
| 344 346 | 
             
                Example:
         | 
| 345 347 | 
             
                    class MyService:
         | 
| 346 348 | 
             
                        @lazy_property
         | 
| @@ -348,28 +350,28 @@ class lazy_property: | |
| 348 350 | 
             
                            # This only runs once
         | 
| 349 351 | 
             
                            return self._compute_expensive_data()
         | 
| 350 352 | 
             
                """
         | 
| 351 | 
            -
             | 
| 353 | 
            +
             | 
| 352 354 | 
             
                def __init__(self, func: Callable) -> None:
         | 
| 353 355 | 
             
                    self.func = func
         | 
| 354 356 | 
             
                    self.lock = threading.RLock()
         | 
| 355 357 | 
             
                    functools.update_wrapper(self, func)
         | 
| 356 | 
            -
             | 
| 358 | 
            +
             | 
| 357 359 | 
             
                def __get__(self, obj: Any, objtype: Type = None) -> Any:
         | 
| 358 360 | 
             
                    if obj is None:
         | 
| 359 361 | 
             
                        return self
         | 
| 360 | 
            -
             | 
| 362 | 
            +
             | 
| 361 363 | 
             
                    # Check if already cached
         | 
| 362 364 | 
             
                    val = obj.__dict__.get(self.func.__name__)
         | 
| 363 365 | 
             
                    if val is not None:
         | 
| 364 366 | 
             
                        return val
         | 
| 365 | 
            -
             | 
| 367 | 
            +
             | 
| 366 368 | 
             
                    # Thread-safe initialization
         | 
| 367 369 | 
             
                    with self.lock:
         | 
| 368 370 | 
             
                        # Double-check pattern
         | 
| 369 371 | 
             
                        val = obj.__dict__.get(self.func.__name__)
         | 
| 370 372 | 
             
                        if val is not None:
         | 
| 371 373 | 
             
                            return val
         | 
| 372 | 
            -
             | 
| 374 | 
            +
             | 
| 373 375 | 
             
                        # Compute and cache
         | 
| 374 376 | 
             
                        val = self.func(obj)
         | 
| 375 377 | 
             
                        obj.__dict__[self.func.__name__] = val
         | 
| @@ -378,84 +380,82 @@ class lazy_property: | |
| 378 380 |  | 
| 379 381 | 
             
            class AsyncLazyService(Generic[T]):
         | 
| 380 382 | 
             
                """Async version of LazyService for async services.
         | 
| 381 | 
            -
             | 
| 383 | 
            +
             | 
| 382 384 | 
             
                Supports services that require async initialization.
         | 
| 383 385 | 
             
                """
         | 
| 384 | 
            -
             | 
| 386 | 
            +
             | 
| 385 387 | 
             
                def __init__(
         | 
| 386 388 | 
             
                    self,
         | 
| 387 389 | 
             
                    service_class: Type[T],
         | 
| 388 390 | 
             
                    init_args: tuple = (),
         | 
| 389 391 | 
             
                    init_kwargs: dict = None,
         | 
| 390 | 
            -
                    name: Optional[str] = None
         | 
| 392 | 
            +
                    name: Optional[str] = None,
         | 
| 391 393 | 
             
                ):
         | 
| 392 394 | 
             
                    self._service_class = service_class
         | 
| 393 395 | 
             
                    self._init_args = init_args
         | 
| 394 396 | 
             
                    self._init_kwargs = init_kwargs or {}
         | 
| 395 397 | 
             
                    self._name = name or service_class.__name__
         | 
| 396 | 
            -
             | 
| 398 | 
            +
             | 
| 397 399 | 
             
                    self._instance: Optional[T] = None
         | 
| 398 400 | 
             
                    self._lock = asyncio.Lock()
         | 
| 399 401 | 
             
                    self._metrics = LazyMetrics()
         | 
| 400 402 | 
             
                    self._logger = get_logger(f"async_lazy.{self._name}")
         | 
| 401 | 
            -
             | 
| 403 | 
            +
             | 
| 402 404 | 
             
                @property
         | 
| 403 405 | 
             
                def is_initialized(self) -> bool:
         | 
| 404 406 | 
             
                    """Check if service has been initialized."""
         | 
| 405 407 | 
             
                    return self._instance is not None
         | 
| 406 | 
            -
             | 
| 408 | 
            +
             | 
| 407 409 | 
             
                async def _ensure_initialized(self) -> T:
         | 
| 408 410 | 
             
                    """Ensure service is initialized asynchronously."""
         | 
| 409 411 | 
             
                    if self._instance is not None:
         | 
| 410 412 | 
             
                        return self._instance
         | 
| 411 | 
            -
             | 
| 413 | 
            +
             | 
| 412 414 | 
             
                    async with self._lock:
         | 
| 413 415 | 
             
                        if self._instance is not None:
         | 
| 414 416 | 
             
                            return self._instance
         | 
| 415 | 
            -
             | 
| 417 | 
            +
             | 
| 416 418 | 
             
                        start_time = time.time()
         | 
| 417 419 | 
             
                        if self._metrics.first_access is None:
         | 
| 418 420 | 
             
                            self._metrics.first_access = datetime.now()
         | 
| 419 | 
            -
             | 
| 421 | 
            +
             | 
| 420 422 | 
             
                        try:
         | 
| 421 423 | 
             
                            self._logger.debug(f"Async initializing: {self._name}")
         | 
| 422 | 
            -
             | 
| 424 | 
            +
             | 
| 423 425 | 
             
                            # Handle both async and sync initialization
         | 
| 424 426 | 
             
                            if asyncio.iscoroutinefunction(self._service_class):
         | 
| 425 427 | 
             
                                self._instance = await self._service_class(
         | 
| 426 | 
            -
                                    *self._init_args,
         | 
| 427 | 
            -
                                    **self._init_kwargs
         | 
| 428 | 
            +
                                    *self._init_args, **self._init_kwargs
         | 
| 428 429 | 
             
                                )
         | 
| 429 430 | 
             
                            else:
         | 
| 430 431 | 
             
                                # Run sync initialization in executor
         | 
| 431 432 | 
             
                                loop = asyncio.get_event_loop()
         | 
| 432 433 | 
             
                                self._instance = await loop.run_in_executor(
         | 
| 433 | 
            -
                                    None,
         | 
| 434 | 
            -
                                    self._service_class,
         | 
| 435 | 
            -
                                    *self._init_args,
         | 
| 436 | 
            -
                                    **self._init_kwargs
         | 
| 434 | 
            +
                                    None, self._service_class, *self._init_args, **self._init_kwargs
         | 
| 437 435 | 
             
                                )
         | 
| 438 | 
            -
             | 
| 436 | 
            +
             | 
| 439 437 | 
             
                            self._metrics.initialization_time = time.time() - start_time
         | 
| 440 438 | 
             
                            self._metrics.is_initialized = True
         | 
| 441 | 
            -
             | 
| 439 | 
            +
             | 
| 442 440 | 
             
                            self._logger.info(
         | 
| 443 441 | 
             
                                f"Async service {self._name} initialized in "
         | 
| 444 442 | 
             
                                f"{self._metrics.initialization_time:.2f}s"
         | 
| 445 443 | 
             
                            )
         | 
| 446 | 
            -
             | 
| 444 | 
            +
             | 
| 447 445 | 
             
                            return self._instance
         | 
| 448 | 
            -
             | 
| 446 | 
            +
             | 
| 449 447 | 
             
                        except Exception as e:
         | 
| 450 448 | 
             
                            self._metrics.initialization_error = e
         | 
| 451 449 | 
             
                            self._logger.error(f"Failed to initialize {self._name}: {e}")
         | 
| 452 450 | 
             
                            raise
         | 
| 453 | 
            -
             | 
| 451 | 
            +
             | 
| 454 452 | 
             
                def __getattr__(self, name: str) -> Any:
         | 
| 455 453 | 
             
                    """Proxy attribute access to the underlying service."""
         | 
| 456 | 
            -
                    if name.startswith( | 
| 457 | 
            -
                        raise AttributeError( | 
| 458 | 
            -
             | 
| 454 | 
            +
                    if name.startswith("_"):
         | 
| 455 | 
            +
                        raise AttributeError(
         | 
| 456 | 
            +
                            f"'{type(self).__name__}' object has no attribute '{name}'"
         | 
| 457 | 
            +
                        )
         | 
| 458 | 
            +
             | 
| 459 459 | 
             
                    async def async_wrapper(*args, **kwargs):
         | 
| 460 460 | 
             
                        instance = await self._ensure_initialized()
         | 
| 461 461 | 
             
                        self._metrics.access_count += 1
         | 
| @@ -463,5 +463,5 @@ class AsyncLazyService(Generic[T]): | |
| 463 463 | 
             
                        if asyncio.iscoroutinefunction(attr):
         | 
| 464 464 | 
             
                            return await attr(*args, **kwargs)
         | 
| 465 465 | 
             
                        return attr(*args, **kwargs)
         | 
| 466 | 
            -
             | 
| 467 | 
            -
                    return async_wrapper
         | 
| 466 | 
            +
             | 
| 467 | 
            +
                    return async_wrapper
         |