claude-mpm 3.9.9__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 +155 -0
- 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 +90 -49
- claude_mpm/cli/__main__.py +3 -2
- claude_mpm/cli/commands/__init__.py +21 -18
- 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 +143 -762
- 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 -1150
- 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 +217 -0
- claude_mpm/config/paths.py +94 -208
- claude_mpm/config/socketio_config.py +84 -73
- claude_mpm/constants.py +36 -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 +571 -0
- 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 +40 -23
- 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 +14 -21
- 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 +97 -93
- claude_mpm/services/mcp_gateway/main.py +307 -127
- claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/registry/service_registry.py +100 -101
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
- claude_mpm/services/mcp_gateway/server/__init__.py +4 -4
- claude_mpm/services/mcp_gateway/server/{mcp_server.py → mcp_gateway.py} +149 -153
- 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 +110 -121
- 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 +20 -534
- 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 +9 -0
- claude_mpm/storage/state_storage.py +552 -0
- 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.9.dist-info → claude_mpm-4.0.3.dist-info}/METADATA +51 -2
- claude_mpm-4.0.3.dist-info/RECORD +402 -0
- {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/entry_points.txt +1 -0
- {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/licenses/LICENSE +1 -1
- claude_mpm/config/memory_guardian_config.py +0 -325
- claude_mpm/core/config_paths.py +0 -150
- 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/memory_guardian.py +0 -770
- claude_mpm/services/mcp_gateway/server/mcp_server_simple.py +0 -444
- 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.9.dist-info/RECORD +0 -293
- {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/WHEEL +0 -0
- {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/top_level.txt +0 -0
| @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            from pathlib import Path
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            #!/usr/bin/env python3
         | 
| 2 4 | 
             
            """
         | 
| 3 5 | 
             
            Agent Lifecycle Manager - ISS-0118 Integration Service
         | 
| @@ -25,38 +27,37 @@ Created for ISS-0118: Agent Registry and Hierarchical Discovery System | |
| 25 27 | 
             
            """
         | 
| 26 28 |  | 
| 27 29 | 
             
            import asyncio
         | 
| 28 | 
            -
            import logging
         | 
| 29 30 | 
             
            import time
         | 
| 30 31 | 
             
            from dataclasses import dataclass, field
         | 
| 31 32 | 
             
            from datetime import datetime, timedelta
         | 
| 32 33 | 
             
            from enum import Enum
         | 
| 33 | 
            -
            from  | 
| 34 | 
            -
            from typing import Dict, List, Optional, Set, Any, Tuple, Union
         | 
| 34 | 
            +
            from typing import Any, Dict, List, Optional, Set, Tuple, Union
         | 
| 35 35 |  | 
| 36 | 
            -
            from claude_mpm. | 
| 37 | 
            -
            from claude_mpm. | 
| 38 | 
            -
            from claude_mpm. | 
| 39 | 
            -
             | 
| 40 | 
            -
                AgentModification, 
         | 
| 41 | 
            -
                ModificationType, 
         | 
| 42 | 
            -
                ModificationTier
         | 
| 43 | 
            -
            )
         | 
| 36 | 
            +
            from claude_mpm.core.base_service import BaseService
         | 
| 37 | 
            +
            from claude_mpm.core.unified_paths import get_path_manager
         | 
| 38 | 
            +
            from claude_mpm.models.agent_definition import AgentDefinition, AgentType
         | 
| 39 | 
            +
            from claude_mpm.services.agents.management import AgentManager
         | 
| 44 40 | 
             
            from claude_mpm.services.agents.memory import (
         | 
| 45 41 | 
             
                AgentPersistenceService,
         | 
| 46 | 
            -
                 | 
| 42 | 
            +
                PersistenceOperation,
         | 
| 47 43 | 
             
                PersistenceRecord,
         | 
| 48 | 
            -
                 | 
| 44 | 
            +
                PersistenceStrategy,
         | 
| 49 45 | 
             
            )
         | 
| 50 | 
            -
            from claude_mpm.services.agents. | 
| 51 | 
            -
            from claude_mpm. | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 46 | 
            +
            from claude_mpm.services.agents.registry import AgentMetadata, AgentRegistry
         | 
| 47 | 
            +
            from claude_mpm.services.agents.registry.modification_tracker import (
         | 
| 48 | 
            +
                AgentModification,
         | 
| 49 | 
            +
                AgentModificationTracker,
         | 
| 50 | 
            +
                ModificationTier,
         | 
| 51 | 
            +
                ModificationType,
         | 
| 52 | 
            +
            )
         | 
| 53 | 
            +
            from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCache
         | 
| 55 54 | 
             
            from claude_mpm.utils.config_manager import ConfigurationManager
         | 
| 55 | 
            +
            from claude_mpm.utils.path_operations import path_ops
         | 
| 56 56 |  | 
| 57 57 |  | 
| 58 58 | 
             
            class LifecycleOperation(Enum):
         | 
| 59 59 | 
             
                """Agent lifecycle operations."""
         | 
| 60 | 
            +
             | 
| 60 61 | 
             
                CREATE = "create"
         | 
| 61 62 | 
             
                UPDATE = "update"
         | 
| 62 63 | 
             
                DELETE = "delete"
         | 
| @@ -68,6 +69,7 @@ class LifecycleOperation(Enum): | |
| 68 69 |  | 
| 69 70 | 
             
            class LifecycleState(Enum):
         | 
| 70 71 | 
             
                """Agent lifecycle states."""
         | 
| 72 | 
            +
             | 
| 71 73 | 
             
                ACTIVE = "active"
         | 
| 72 74 | 
             
                MODIFIED = "modified"
         | 
| 73 75 | 
             
                DELETED = "deleted"
         | 
| @@ -79,7 +81,7 @@ class LifecycleState(Enum): | |
| 79 81 | 
             
            @dataclass
         | 
| 80 82 | 
             
            class AgentLifecycleRecord:
         | 
| 81 83 | 
             
                """Complete lifecycle record for an agent."""
         | 
| 82 | 
            -
             | 
| 84 | 
            +
             | 
| 83 85 | 
             
                agent_name: str
         | 
| 84 86 | 
             
                current_state: LifecycleState
         | 
| 85 87 | 
             
                tier: ModificationTier
         | 
| @@ -93,12 +95,12 @@ class AgentLifecycleRecord: | |
| 93 95 | 
             
                validation_status: str = "valid"
         | 
| 94 96 | 
             
                validation_errors: List[str] = field(default_factory=list)
         | 
| 95 97 | 
             
                metadata: Dict[str, Any] = field(default_factory=dict)
         | 
| 96 | 
            -
             | 
| 98 | 
            +
             | 
| 97 99 | 
             
                @property
         | 
| 98 100 | 
             
                def age_days(self) -> float:
         | 
| 99 101 | 
             
                    """Get age in days."""
         | 
| 100 102 | 
             
                    return (time.time() - self.created_at) / (24 * 3600)
         | 
| 101 | 
            -
             | 
| 103 | 
            +
             | 
| 102 104 | 
             
                @property
         | 
| 103 105 | 
             
                def last_modified_datetime(self) -> datetime:
         | 
| 104 106 | 
             
                    """Get last modified as datetime."""
         | 
| @@ -108,7 +110,7 @@ class AgentLifecycleRecord: | |
| 108 110 | 
             
            @dataclass
         | 
| 109 111 | 
             
            class LifecycleOperationResult:
         | 
| 110 112 | 
             
                """Result of a lifecycle operation."""
         | 
| 111 | 
            -
             | 
| 113 | 
            +
             | 
| 112 114 | 
             
                operation: LifecycleOperation
         | 
| 113 115 | 
             
                agent_name: str
         | 
| 114 116 | 
             
                success: bool
         | 
| @@ -124,7 +126,7 @@ class LifecycleOperationResult: | |
| 124 126 | 
             
            class AgentLifecycleManager(BaseService):
         | 
| 125 127 | 
             
                """
         | 
| 126 128 | 
             
                Agent Lifecycle Manager - Unified agent management across hierarchy tiers.
         | 
| 127 | 
            -
             | 
| 129 | 
            +
             | 
| 128 130 | 
             
                Features:
         | 
| 129 131 | 
             
                - Complete agent lifecycle management (CRUD operations)
         | 
| 130 132 | 
             
                - Integrated modification tracking and persistence
         | 
| @@ -133,132 +135,117 @@ class AgentLifecycleManager(BaseService): | |
| 133 135 | 
             
                - Real-time conflict detection and resolution
         | 
| 134 136 | 
             
                - Performance monitoring and optimization
         | 
| 135 137 | 
             
                """
         | 
| 136 | 
            -
             | 
| 138 | 
            +
             | 
| 137 139 | 
             
                def __init__(self, config: Optional[Dict[str, Any]] = None):
         | 
| 138 140 | 
             
                    """Initialize the agent lifecycle manager."""
         | 
| 139 141 | 
             
                    super().__init__("agent_lifecycle_manager", config)
         | 
| 140 | 
            -
             | 
| 142 | 
            +
             | 
| 141 143 | 
             
                    # Configuration
         | 
| 142 144 | 
             
                    self.enable_auto_backup = self.get_config("enable_auto_backup", True)
         | 
| 143 145 | 
             
                    self.enable_auto_validation = self.get_config("enable_auto_validation", True)
         | 
| 144 | 
            -
                    self.enable_cache_invalidation = self.get_config( | 
| 146 | 
            +
                    self.enable_cache_invalidation = self.get_config(
         | 
| 147 | 
            +
                        "enable_cache_invalidation", True
         | 
| 148 | 
            +
                    )
         | 
| 145 149 | 
             
                    self.enable_registry_sync = self.get_config("enable_registry_sync", True)
         | 
| 146 150 | 
             
                    self.default_persistence_strategy = PersistenceStrategy(
         | 
| 147 | 
            -
                        self.get_config( | 
| 151 | 
            +
                        self.get_config(
         | 
| 152 | 
            +
                            "default_persistence_strategy", PersistenceStrategy.USER_OVERRIDE.value
         | 
| 153 | 
            +
                        )
         | 
| 148 154 | 
             
                    )
         | 
| 149 | 
            -
             | 
| 155 | 
            +
             | 
| 150 156 | 
             
                    # Core services
         | 
| 151 157 | 
             
                    self.shared_cache: Optional[SharedPromptCache] = None
         | 
| 152 158 | 
             
                    self.agent_registry: Optional[AgentRegistry] = None
         | 
| 153 159 | 
             
                    self.modification_tracker: Optional[AgentModificationTracker] = None
         | 
| 154 160 | 
             
                    self.persistence_service: Optional[AgentPersistenceService] = None
         | 
| 155 161 | 
             
                    self.agent_manager: Optional[AgentManager] = None
         | 
| 156 | 
            -
             | 
| 162 | 
            +
             | 
| 157 163 | 
             
                    # Lifecycle tracking
         | 
| 158 164 | 
             
                    self.agent_records: Dict[str, AgentLifecycleRecord] = {}
         | 
| 159 165 | 
             
                    self.operation_history: List[LifecycleOperationResult] = []
         | 
| 160 166 | 
             
                    self.active_operations: Dict[str, LifecycleOperation] = {}
         | 
| 161 | 
            -
             | 
| 167 | 
            +
             | 
| 162 168 | 
             
                    # Performance metrics
         | 
| 163 169 | 
             
                    self.performance_metrics = {
         | 
| 164 | 
            -
                         | 
| 165 | 
            -
                         | 
| 166 | 
            -
                         | 
| 167 | 
            -
                         | 
| 168 | 
            -
                         | 
| 170 | 
            +
                        "total_operations": 0,
         | 
| 171 | 
            +
                        "successful_operations": 0,
         | 
| 172 | 
            +
                        "failed_operations": 0,
         | 
| 173 | 
            +
                        "average_duration_ms": 0.0,
         | 
| 174 | 
            +
                        "cache_hit_rate": 0.0,
         | 
| 169 175 | 
             
                    }
         | 
| 170 | 
            -
             | 
| 176 | 
            +
             | 
| 171 177 | 
             
                    # Operation lock for thread safety
         | 
| 172 178 | 
             
                    self._operation_lock = asyncio.Lock()
         | 
| 173 | 
            -
             | 
| 179 | 
            +
             | 
| 174 180 | 
             
                    # Configuration manager
         | 
| 175 181 | 
             
                    self.config_mgr = ConfigurationManager(cache_enabled=True)
         | 
| 176 | 
            -
             | 
| 182 | 
            +
             | 
| 177 183 | 
             
                    self.logger.info("AgentLifecycleManager initialized")
         | 
| 178 | 
            -
             | 
| 184 | 
            +
             | 
| 179 185 | 
             
                async def _initialize(self) -> None:
         | 
| 180 186 | 
             
                    """Initialize the lifecycle manager."""
         | 
| 181 187 | 
             
                    self.logger.info("Initializing AgentLifecycleManager...")
         | 
| 182 | 
            -
             | 
| 188 | 
            +
             | 
| 183 189 | 
             
                    # Initialize core services
         | 
| 184 190 | 
             
                    await self._initialize_core_services()
         | 
| 185 | 
            -
             | 
| 191 | 
            +
             | 
| 186 192 | 
             
                    # Load existing agent records
         | 
| 187 193 | 
             
                    await self._load_agent_records()
         | 
| 188 | 
            -
             | 
| 194 | 
            +
             | 
| 189 195 | 
             
                    # Start service integrations
         | 
| 190 196 | 
             
                    await self._setup_service_integrations()
         | 
| 191 | 
            -
             | 
| 197 | 
            +
             | 
| 192 198 | 
             
                    # Perform initial registry sync
         | 
| 193 199 | 
             
                    if self.enable_registry_sync:
         | 
| 194 200 | 
             
                        await self._sync_with_registry()
         | 
| 195 | 
            -
             | 
| 201 | 
            +
             | 
| 196 202 | 
             
                    self.logger.info("AgentLifecycleManager initialized successfully")
         | 
| 197 | 
            -
             | 
| 203 | 
            +
             | 
| 198 204 | 
             
                async def _cleanup(self) -> None:
         | 
| 199 205 | 
             
                    """Cleanup lifecycle manager resources."""
         | 
| 200 206 | 
             
                    self.logger.info("Cleaning up AgentLifecycleManager...")
         | 
| 201 | 
            -
             | 
| 207 | 
            +
             | 
| 202 208 | 
             
                    # Save agent records
         | 
| 203 209 | 
             
                    await self._save_agent_records()
         | 
| 204 | 
            -
             | 
| 210 | 
            +
             | 
| 205 211 | 
             
                    # Stop core services if we own them
         | 
| 206 212 | 
             
                    await self._cleanup_core_services()
         | 
| 207 | 
            -
             | 
| 213 | 
            +
             | 
| 208 214 | 
             
                    self.logger.info("AgentLifecycleManager cleaned up")
         | 
| 209 | 
            -
             | 
| 215 | 
            +
             | 
| 210 216 | 
             
                async def _health_check(self) -> Dict[str, bool]:
         | 
| 211 217 | 
             
                    """Perform lifecycle manager health checks."""
         | 
| 212 | 
            -
                     | 
| 213 | 
            -
             | 
| 214 | 
            -
                     | 
| 215 | 
            -
             | 
| 216 | 
            -
             | 
| 217 | 
            -
                        checks["registry_service"] = self.agent_registry is not None
         | 
| 218 | 
            -
                        checks["tracker_service"] = self.modification_tracker is not None
         | 
| 219 | 
            -
                        checks["persistence_service"] = self.persistence_service is not None
         | 
| 220 | 
            -
                        
         | 
| 221 | 
            -
                        # Check operation capabilities
         | 
| 222 | 
            -
                        checks["can_create_agents"] = await self._test_create_capability()
         | 
| 223 | 
            -
                        checks["can_modify_agents"] = await self._test_modify_capability()
         | 
| 224 | 
            -
                        checks["can_delete_agents"] = await self._test_delete_capability()
         | 
| 225 | 
            -
                        
         | 
| 226 | 
            -
                        # Check data integrity
         | 
| 227 | 
            -
                        checks["agent_records_valid"] = len(self.agent_records) >= 0
         | 
| 228 | 
            -
                        checks["operation_history_valid"] = len(self.operation_history) >= 0
         | 
| 229 | 
            -
                        
         | 
| 230 | 
            -
                    except Exception as e:
         | 
| 231 | 
            -
                        self.logger.error(f"Lifecycle manager health check failed: {e}")
         | 
| 232 | 
            -
                        checks["health_check_error"] = False
         | 
| 233 | 
            -
                    
         | 
| 234 | 
            -
                    return checks
         | 
| 235 | 
            -
                
         | 
| 218 | 
            +
                    from .lifecycle_health_checker import LifecycleHealthChecker
         | 
| 219 | 
            +
             | 
| 220 | 
            +
                    checker = LifecycleHealthChecker(self)
         | 
| 221 | 
            +
                    return await checker.perform_health_check()
         | 
| 222 | 
            +
             | 
| 236 223 | 
             
                async def _initialize_core_services(self) -> None:
         | 
| 237 224 | 
             
                    """Initialize core service dependencies."""
         | 
| 238 225 | 
             
                    try:
         | 
| 239 226 | 
             
                        # Initialize SharedPromptCache
         | 
| 240 227 | 
             
                        self.shared_cache = SharedPromptCache.get_instance()
         | 
| 241 | 
            -
             | 
| 228 | 
            +
             | 
| 242 229 | 
             
                        # Initialize AgentRegistry
         | 
| 243 230 | 
             
                        self.agent_registry = AgentRegistry(cache_service=self.shared_cache)
         | 
| 244 | 
            -
             | 
| 231 | 
            +
             | 
| 245 232 | 
             
                        # Initialize AgentModificationTracker
         | 
| 246 233 | 
             
                        self.modification_tracker = AgentModificationTracker()
         | 
| 247 234 | 
             
                        await self.modification_tracker.start()
         | 
| 248 | 
            -
             | 
| 235 | 
            +
             | 
| 249 236 | 
             
                        # Initialize AgentPersistenceService
         | 
| 250 237 | 
             
                        self.persistence_service = AgentPersistenceService()
         | 
| 251 238 | 
             
                        await self.persistence_service.start()
         | 
| 252 | 
            -
             | 
| 239 | 
            +
             | 
| 253 240 | 
             
                        # Initialize AgentManager
         | 
| 254 241 | 
             
                        self.agent_manager = AgentManager()
         | 
| 255 | 
            -
             | 
| 242 | 
            +
             | 
| 256 243 | 
             
                        self.logger.info("Core services initialized successfully")
         | 
| 257 | 
            -
             | 
| 244 | 
            +
             | 
| 258 245 | 
             
                    except Exception as e:
         | 
| 259 246 | 
             
                        self.logger.error(f"Failed to initialize core services: {e}")
         | 
| 260 247 | 
             
                        raise
         | 
| 261 | 
            -
             | 
| 248 | 
            +
             | 
| 262 249 | 
             
                async def _setup_service_integrations(self) -> None:
         | 
| 263 250 | 
             
                    """Set up integrations between services."""
         | 
| 264 251 | 
             
                    try:
         | 
| @@ -267,79 +254,83 @@ class AgentLifecycleManager(BaseService): | |
| 267 254 | 
             
                            self.modification_tracker.register_modification_callback(
         | 
| 268 255 | 
             
                                self._handle_modification_event
         | 
| 269 256 | 
             
                            )
         | 
| 270 | 
            -
             | 
| 257 | 
            +
             | 
| 271 258 | 
             
                        self.logger.debug("Service integrations set up successfully")
         | 
| 272 | 
            -
             | 
| 259 | 
            +
             | 
| 273 260 | 
             
                    except Exception as e:
         | 
| 274 261 | 
             
                        self.logger.warning(f"Failed to setup some service integrations: {e}")
         | 
| 275 | 
            -
             | 
| 262 | 
            +
             | 
| 276 263 | 
             
                async def _load_agent_records(self) -> None:
         | 
| 277 264 | 
             
                    """Load existing agent lifecycle records."""
         | 
| 278 265 | 
             
                    try:
         | 
| 279 | 
            -
                        records_file =  | 
| 266 | 
            +
                        records_file = (
         | 
| 267 | 
            +
                            get_path_manager().get_tracking_dir() / "lifecycle_records.json"
         | 
| 268 | 
            +
                        )
         | 
| 280 269 | 
             
                        if path_ops.validate_exists(records_file):
         | 
| 281 270 | 
             
                            data = self.config_mgr.load_json(records_file)
         | 
| 282 | 
            -
             | 
| 271 | 
            +
             | 
| 283 272 | 
             
                            for agent_name, record_data in data.items():
         | 
| 284 273 | 
             
                                record = AgentLifecycleRecord(**record_data)
         | 
| 285 274 | 
             
                                # Convert string enum back to enum
         | 
| 286 | 
            -
                                record.current_state = LifecycleState(record_data[ | 
| 287 | 
            -
                                record.tier = ModificationTier(record_data[ | 
| 275 | 
            +
                                record.current_state = LifecycleState(record_data["current_state"])
         | 
| 276 | 
            +
                                record.tier = ModificationTier(record_data["tier"])
         | 
| 288 277 | 
             
                                self.agent_records[agent_name] = record
         | 
| 289 | 
            -
             | 
| 278 | 
            +
             | 
| 290 279 | 
             
                            self.logger.info(f"Loaded {len(self.agent_records)} agent records")
         | 
| 291 | 
            -
             | 
| 280 | 
            +
             | 
| 292 281 | 
             
                    except Exception as e:
         | 
| 293 282 | 
             
                        self.logger.warning(f"Failed to load agent records: {e}")
         | 
| 294 | 
            -
             | 
| 283 | 
            +
             | 
| 295 284 | 
             
                async def _save_agent_records(self) -> None:
         | 
| 296 285 | 
             
                    """Save agent lifecycle records to disk."""
         | 
| 297 286 | 
             
                    try:
         | 
| 298 | 
            -
                        records_file =  | 
| 287 | 
            +
                        records_file = (
         | 
| 288 | 
            +
                            get_path_manager().get_tracking_dir() / "lifecycle_records.json"
         | 
| 289 | 
            +
                        )
         | 
| 299 290 | 
             
                        path_ops.ensure_dir(records_file.parent)
         | 
| 300 | 
            -
             | 
| 291 | 
            +
             | 
| 301 292 | 
             
                        data = {}
         | 
| 302 293 | 
             
                        for agent_name, record in self.agent_records.items():
         | 
| 303 294 | 
             
                            record_dict = record.__dict__.copy()
         | 
| 304 295 | 
             
                            # Convert enums to strings for JSON serialization
         | 
| 305 | 
            -
                            record_dict[ | 
| 306 | 
            -
                            record_dict[ | 
| 296 | 
            +
                            record_dict["current_state"] = record.current_state.value
         | 
| 297 | 
            +
                            record_dict["tier"] = record.tier.value
         | 
| 307 298 | 
             
                            data[agent_name] = record_dict
         | 
| 308 | 
            -
             | 
| 299 | 
            +
             | 
| 309 300 | 
             
                        # Use save_json with custom encoder for datetime serialization
         | 
| 310 301 | 
             
                        import json
         | 
| 311 | 
            -
             | 
| 302 | 
            +
             | 
| 312 303 | 
             
                        # First convert to JSON string with custom encoder, then save
         | 
| 313 304 | 
             
                        json_str = json.dumps(data, indent=2, default=str)
         | 
| 314 305 | 
             
                        records_file.parent.mkdir(parents=True, exist_ok=True)
         | 
| 315 | 
            -
                        with open(records_file,  | 
| 306 | 
            +
                        with open(records_file, "w", encoding="utf-8") as f:
         | 
| 316 307 | 
             
                            f.write(json_str)
         | 
| 317 | 
            -
             | 
| 308 | 
            +
             | 
| 318 309 | 
             
                        self.logger.debug(f"Saved {len(self.agent_records)} agent records")
         | 
| 319 | 
            -
             | 
| 310 | 
            +
             | 
| 320 311 | 
             
                    except Exception as e:
         | 
| 321 312 | 
             
                        self.logger.error(f"Failed to save agent records: {e}")
         | 
| 322 | 
            -
             | 
| 313 | 
            +
             | 
| 323 314 | 
             
                async def _sync_with_registry(self) -> None:
         | 
| 324 315 | 
             
                    """Synchronize with agent registry."""
         | 
| 325 316 | 
             
                    try:
         | 
| 326 317 | 
             
                        if not self.agent_registry:
         | 
| 327 318 | 
             
                            return
         | 
| 328 | 
            -
             | 
| 319 | 
            +
             | 
| 329 320 | 
             
                        # Discover all agents via registry (sync methods)
         | 
| 330 321 | 
             
                        self.agent_registry.discover_agents()
         | 
| 331 322 | 
             
                        all_agents = self.agent_registry.list_agents()
         | 
| 332 | 
            -
             | 
| 323 | 
            +
             | 
| 333 324 | 
             
                        # Update lifecycle records with registry data
         | 
| 334 325 | 
             
                        for agent_metadata in all_agents:
         | 
| 335 326 | 
             
                            if agent_metadata.name not in self.agent_records:
         | 
| 336 327 | 
             
                                # Create new lifecycle record
         | 
| 337 328 | 
             
                                tier_map = {
         | 
| 338 | 
            -
                                     | 
| 339 | 
            -
                                     | 
| 340 | 
            -
                                     | 
| 329 | 
            +
                                    "project": ModificationTier.PROJECT,
         | 
| 330 | 
            +
                                    "user": ModificationTier.USER,
         | 
| 331 | 
            +
                                    "system": ModificationTier.SYSTEM,
         | 
| 341 332 | 
             
                                }
         | 
| 342 | 
            -
             | 
| 333 | 
            +
             | 
| 343 334 | 
             
                                record = AgentLifecycleRecord(
         | 
| 344 335 | 
             
                                    agent_name=agent_metadata.name,
         | 
| 345 336 | 
             
                                    current_state=LifecycleState.ACTIVE,
         | 
| @@ -349,44 +340,46 @@ class AgentLifecycleManager(BaseService): | |
| 349 340 | 
             
                                    last_modified=agent_metadata.last_modified or time.time(),
         | 
| 350 341 | 
             
                                    version="1.0.0",
         | 
| 351 342 | 
             
                                    metadata={
         | 
| 352 | 
            -
                                         | 
| 353 | 
            -
                                         | 
| 354 | 
            -
                                         | 
| 355 | 
            -
                                         | 
| 356 | 
            -
                                    }
         | 
| 343 | 
            +
                                        "type": agent_metadata.type,
         | 
| 344 | 
            +
                                        "description": agent_metadata.description,
         | 
| 345 | 
            +
                                        "capabilities": agent_metadata.capabilities,
         | 
| 346 | 
            +
                                        "validated": agent_metadata.validated,
         | 
| 347 | 
            +
                                    },
         | 
| 357 348 | 
             
                                )
         | 
| 358 | 
            -
             | 
| 349 | 
            +
             | 
| 359 350 | 
             
                                self.agent_records[agent_metadata.name] = record
         | 
| 360 | 
            -
             | 
| 351 | 
            +
             | 
| 361 352 | 
             
                        self.logger.info(f"Synchronized with registry: {len(all_agents)} agents")
         | 
| 362 | 
            -
             | 
| 353 | 
            +
             | 
| 363 354 | 
             
                    except Exception as e:
         | 
| 364 355 | 
             
                        self.logger.error(f"Failed to sync with registry: {e}")
         | 
| 365 | 
            -
             | 
| 366 | 
            -
                async def create_agent( | 
| 367 | 
            -
             | 
| 368 | 
            -
             | 
| 369 | 
            -
             | 
| 370 | 
            -
             | 
| 371 | 
            -
             | 
| 356 | 
            +
             | 
| 357 | 
            +
                async def create_agent(
         | 
| 358 | 
            +
                    self,
         | 
| 359 | 
            +
                    agent_name: str,
         | 
| 360 | 
            +
                    agent_content: str,
         | 
| 361 | 
            +
                    tier: ModificationTier = ModificationTier.USER,
         | 
| 362 | 
            +
                    agent_type: str = "custom",
         | 
| 363 | 
            +
                    **kwargs,
         | 
| 364 | 
            +
                ) -> LifecycleOperationResult:
         | 
| 372 365 | 
             
                    """
         | 
| 373 366 | 
             
                    Create a new agent with complete lifecycle tracking.
         | 
| 374 | 
            -
             | 
| 367 | 
            +
             | 
| 375 368 | 
             
                    Args:
         | 
| 376 369 | 
             
                        agent_name: Name of the agent to create
         | 
| 377 370 | 
             
                        agent_content: Content of the agent file
         | 
| 378 371 | 
             
                        tier: Target tier for creation
         | 
| 379 372 | 
             
                        agent_type: Type of agent (for classification)
         | 
| 380 373 | 
             
                        **kwargs: Additional metadata
         | 
| 381 | 
            -
             | 
| 374 | 
            +
             | 
| 382 375 | 
             
                    Returns:
         | 
| 383 376 | 
             
                        LifecycleOperationResult with operation details
         | 
| 384 377 | 
             
                    """
         | 
| 385 378 | 
             
                    start_time = time.time()
         | 
| 386 | 
            -
             | 
| 379 | 
            +
             | 
| 387 380 | 
             
                    async with self._operation_lock:
         | 
| 388 381 | 
             
                        self.active_operations[agent_name] = LifecycleOperation.CREATE
         | 
| 389 | 
            -
             | 
| 382 | 
            +
             | 
| 390 383 | 
             
                        try:
         | 
| 391 384 | 
             
                            # Check if agent already exists
         | 
| 392 385 | 
             
                            if agent_name in self.agent_records:
         | 
| @@ -395,27 +388,33 @@ class AgentLifecycleManager(BaseService): | |
| 395 388 | 
             
                                    agent_name=agent_name,
         | 
| 396 389 | 
             
                                    success=False,
         | 
| 397 390 | 
             
                                    duration_ms=(time.time() - start_time) * 1000,
         | 
| 398 | 
            -
                                    error_message="Agent already exists"
         | 
| 391 | 
            +
                                    error_message="Agent already exists",
         | 
| 399 392 | 
             
                                )
         | 
| 400 | 
            -
             | 
| 393 | 
            +
             | 
| 401 394 | 
             
                            # Create agent definition
         | 
| 402 395 | 
             
                            agent_def = await self._create_agent_definition(
         | 
| 403 396 | 
             
                                agent_name, agent_content, tier, agent_type, **kwargs
         | 
| 404 397 | 
             
                            )
         | 
| 405 | 
            -
             | 
| 398 | 
            +
             | 
| 406 399 | 
             
                            # Determine location based on tier
         | 
| 407 | 
            -
                            location =  | 
| 408 | 
            -
             | 
| 400 | 
            +
                            location = (
         | 
| 401 | 
            +
                                "project" if tier == ModificationTier.PROJECT else "framework"
         | 
| 402 | 
            +
                            )
         | 
| 403 | 
            +
             | 
| 409 404 | 
             
                            # Create agent using AgentManager (sync call in executor)
         | 
| 410 405 | 
             
                            try:
         | 
| 411 406 | 
             
                                if self.agent_manager:
         | 
| 412 407 | 
             
                                    file_path = await self._run_sync_in_executor(
         | 
| 413 408 | 
             
                                        self.agent_manager.create_agent,
         | 
| 414 | 
            -
                                        agent_name, | 
| 409 | 
            +
                                        agent_name,
         | 
| 410 | 
            +
                                        agent_def,
         | 
| 411 | 
            +
                                        location,
         | 
| 415 412 | 
             
                                    )
         | 
| 416 413 | 
             
                                else:
         | 
| 417 414 | 
             
                                    # Fallback to direct file creation if AgentManager not available
         | 
| 418 | 
            -
                                    file_path = await self._determine_agent_file_path( | 
| 415 | 
            +
                                    file_path = await self._determine_agent_file_path(
         | 
| 416 | 
            +
                                        agent_name, tier
         | 
| 417 | 
            +
                                    )
         | 
| 419 418 | 
             
                                    path_ops.ensure_dir(file_path.parent)
         | 
| 420 419 | 
             
                                    path_ops.safe_write(file_path, agent_content)
         | 
| 421 420 | 
             
                            except Exception as e:
         | 
| @@ -424,7 +423,7 @@ class AgentLifecycleManager(BaseService): | |
| 424 423 | 
             
                                file_path = await self._determine_agent_file_path(agent_name, tier)
         | 
| 425 424 | 
             
                                path_ops.ensure_dir(file_path.parent)
         | 
| 426 425 | 
             
                                path_ops.safe_write(file_path, agent_content)
         | 
| 427 | 
            -
             | 
| 426 | 
            +
             | 
| 428 427 | 
             
                            # Track modification
         | 
| 429 428 | 
             
                            modification = await self.modification_tracker.track_modification(
         | 
| 430 429 | 
             
                                agent_name=agent_name,
         | 
| @@ -432,9 +431,9 @@ class AgentLifecycleManager(BaseService): | |
| 432 431 | 
             
                                file_path=str(file_path),
         | 
| 433 432 | 
             
                                tier=tier,
         | 
| 434 433 | 
             
                                agent_type=agent_type,
         | 
| 435 | 
            -
                                **kwargs
         | 
| 434 | 
            +
                                **kwargs,
         | 
| 436 435 | 
             
                            )
         | 
| 437 | 
            -
             | 
| 436 | 
            +
             | 
| 438 437 | 
             
                            # Note: We don't use persistence_service for the actual write anymore
         | 
| 439 438 | 
             
                            # since AgentManager handles that. We create a synthetic record for compatibility.
         | 
| 440 439 | 
             
                            persistence_record = PersistenceRecord(
         | 
| @@ -446,9 +445,9 @@ class AgentLifecycleManager(BaseService): | |
| 446 445 | 
             
                                strategy=self.default_persistence_strategy,
         | 
| 447 446 | 
             
                                success=True,
         | 
| 448 447 | 
             
                                timestamp=time.time(),
         | 
| 449 | 
            -
                                file_path=str(file_path)
         | 
| 448 | 
            +
                                file_path=str(file_path),
         | 
| 450 449 | 
             
                            )
         | 
| 451 | 
            -
             | 
| 450 | 
            +
             | 
| 452 451 | 
             
                            # Create lifecycle record
         | 
| 453 452 | 
             
                            lifecycle_record = AgentLifecycleRecord(
         | 
| 454 453 | 
             
                                agent_name=agent_name,
         | 
| @@ -460,18 +459,15 @@ class AgentLifecycleManager(BaseService): | |
| 460 459 | 
             
                                version="1.0.0",
         | 
| 461 460 | 
             
                                modifications=[modification.modification_id],
         | 
| 462 461 | 
             
                                persistence_operations=[persistence_record.operation_id],
         | 
| 463 | 
            -
                                metadata={
         | 
| 464 | 
            -
                                    'agent_type': agent_type,
         | 
| 465 | 
            -
                                    **kwargs
         | 
| 466 | 
            -
                                }
         | 
| 462 | 
            +
                                metadata={"agent_type": agent_type, **kwargs},
         | 
| 467 463 | 
             
                            )
         | 
| 468 | 
            -
             | 
| 464 | 
            +
             | 
| 469 465 | 
             
                            self.agent_records[agent_name] = lifecycle_record
         | 
| 470 | 
            -
             | 
| 466 | 
            +
             | 
| 471 467 | 
             
                            # Invalidate cache and update registry
         | 
| 472 468 | 
             
                            cache_invalidated = await self._invalidate_agent_cache(agent_name)
         | 
| 473 469 | 
             
                            registry_updated = await self._update_registry(agent_name)
         | 
| 474 | 
            -
             | 
| 470 | 
            +
             | 
| 475 471 | 
             
                            # Create result
         | 
| 476 472 | 
             
                            result = LifecycleOperationResult(
         | 
| 477 473 | 
             
                                operation=LifecycleOperation.CREATE,
         | 
| @@ -482,59 +478,60 @@ class AgentLifecycleManager(BaseService): | |
| 482 478 | 
             
                                persistence_id=persistence_record.operation_id,
         | 
| 483 479 | 
             
                                cache_invalidated=cache_invalidated,
         | 
| 484 480 | 
             
                                registry_updated=registry_updated,
         | 
| 485 | 
            -
                                metadata={ | 
| 481 | 
            +
                                metadata={"file_path": str(file_path)},
         | 
| 486 482 | 
             
                            )
         | 
| 487 | 
            -
             | 
| 483 | 
            +
             | 
| 488 484 | 
             
                            if not persistence_record.success:
         | 
| 489 485 | 
             
                                result.error_message = persistence_record.error_message
         | 
| 490 486 | 
             
                                lifecycle_record.current_state = LifecycleState.CONFLICTED
         | 
| 491 | 
            -
             | 
| 487 | 
            +
             | 
| 492 488 | 
             
                            # Update performance metrics
         | 
| 493 489 | 
             
                            await self._update_performance_metrics(result)
         | 
| 494 | 
            -
             | 
| 490 | 
            +
             | 
| 495 491 | 
             
                            self.operation_history.append(result)
         | 
| 496 | 
            -
                            self.logger.info( | 
| 497 | 
            -
             | 
| 492 | 
            +
                            self.logger.info(
         | 
| 493 | 
            +
                                f"Created agent '{agent_name}' in {result.duration_ms:.1f}ms"
         | 
| 494 | 
            +
                            )
         | 
| 495 | 
            +
             | 
| 498 496 | 
             
                            return result
         | 
| 499 | 
            -
             | 
| 497 | 
            +
             | 
| 500 498 | 
             
                        except Exception as e:
         | 
| 501 499 | 
             
                            result = LifecycleOperationResult(
         | 
| 502 500 | 
             
                                operation=LifecycleOperation.CREATE,
         | 
| 503 501 | 
             
                                agent_name=agent_name,
         | 
| 504 502 | 
             
                                success=False,
         | 
| 505 503 | 
             
                                duration_ms=(time.time() - start_time) * 1000,
         | 
| 506 | 
            -
                                error_message=str(e)
         | 
| 504 | 
            +
                                error_message=str(e),
         | 
| 507 505 | 
             
                            )
         | 
| 508 | 
            -
             | 
| 506 | 
            +
             | 
| 509 507 | 
             
                            self.operation_history.append(result)
         | 
| 510 508 | 
             
                            await self._update_performance_metrics(result)
         | 
| 511 | 
            -
             | 
| 509 | 
            +
             | 
| 512 510 | 
             
                            self.logger.error(f"Failed to create agent '{agent_name}': {e}")
         | 
| 513 511 | 
             
                            return result
         | 
| 514 | 
            -
             | 
| 512 | 
            +
             | 
| 515 513 | 
             
                        finally:
         | 
| 516 514 | 
             
                            self.active_operations.pop(agent_name, None)
         | 
| 517 | 
            -
             | 
| 518 | 
            -
                async def update_agent( | 
| 519 | 
            -
             | 
| 520 | 
            -
             | 
| 521 | 
            -
                                      **kwargs) -> LifecycleOperationResult:
         | 
| 515 | 
            +
             | 
| 516 | 
            +
                async def update_agent(
         | 
| 517 | 
            +
                    self, agent_name: str, agent_content: str, **kwargs
         | 
| 518 | 
            +
                ) -> LifecycleOperationResult:
         | 
| 522 519 | 
             
                    """
         | 
| 523 520 | 
             
                    Update an existing agent with lifecycle tracking.
         | 
| 524 | 
            -
             | 
| 521 | 
            +
             | 
| 525 522 | 
             
                    Args:
         | 
| 526 523 | 
             
                        agent_name: Name of the agent to update
         | 
| 527 524 | 
             
                        agent_content: New content for the agent
         | 
| 528 525 | 
             
                        **kwargs: Additional metadata
         | 
| 529 | 
            -
             | 
| 526 | 
            +
             | 
| 530 527 | 
             
                    Returns:
         | 
| 531 528 | 
             
                        LifecycleOperationResult with operation details
         | 
| 532 529 | 
             
                    """
         | 
| 533 530 | 
             
                    start_time = time.time()
         | 
| 534 | 
            -
             | 
| 531 | 
            +
             | 
| 535 532 | 
             
                    async with self._operation_lock:
         | 
| 536 533 | 
             
                        self.active_operations[agent_name] = LifecycleOperation.UPDATE
         | 
| 537 | 
            -
             | 
| 534 | 
            +
             | 
| 538 535 | 
             
                        try:
         | 
| 539 536 | 
             
                            # Check if agent exists
         | 
| 540 537 | 
             
                            if agent_name not in self.agent_records:
         | 
| @@ -543,11 +540,11 @@ class AgentLifecycleManager(BaseService): | |
| 543 540 | 
             
                                    agent_name=agent_name,
         | 
| 544 541 | 
             
                                    success=False,
         | 
| 545 542 | 
             
                                    duration_ms=(time.time() - start_time) * 1000,
         | 
| 546 | 
            -
                                    error_message="Agent not found"
         | 
| 543 | 
            +
                                    error_message="Agent not found",
         | 
| 547 544 | 
             
                                )
         | 
| 548 | 
            -
             | 
| 545 | 
            +
             | 
| 549 546 | 
             
                            record = self.agent_records[agent_name]
         | 
| 550 | 
            -
             | 
| 547 | 
            +
             | 
| 551 548 | 
             
                            # Update agent using AgentManager
         | 
| 552 549 | 
             
                            try:
         | 
| 553 550 | 
             
                                if self.agent_manager:
         | 
| @@ -555,25 +552,31 @@ class AgentLifecycleManager(BaseService): | |
| 555 552 | 
             
                                    current_def = await self._run_sync_in_executor(
         | 
| 556 553 | 
             
                                        self.agent_manager.read_agent, agent_name
         | 
| 557 554 | 
             
                                    )
         | 
| 558 | 
            -
             | 
| 555 | 
            +
             | 
| 559 556 | 
             
                                    if current_def:
         | 
| 560 557 | 
             
                                        # Update raw content
         | 
| 561 558 | 
             
                                        current_def.raw_content = agent_content
         | 
| 562 | 
            -
             | 
| 559 | 
            +
             | 
| 563 560 | 
             
                                        # Apply any metadata updates from kwargs
         | 
| 564 | 
            -
                                        if  | 
| 565 | 
            -
                                            current_def.metadata.model_preference = kwargs[ | 
| 566 | 
            -
             | 
| 567 | 
            -
                                             | 
| 568 | 
            -
                                        if  | 
| 569 | 
            -
                                            current_def.metadata. | 
| 570 | 
            -
                                        
         | 
| 561 | 
            +
                                        if "model_preference" in kwargs:
         | 
| 562 | 
            +
                                            current_def.metadata.model_preference = kwargs[
         | 
| 563 | 
            +
                                                "model_preference"
         | 
| 564 | 
            +
                                            ]
         | 
| 565 | 
            +
                                        if "tags" in kwargs:
         | 
| 566 | 
            +
                                            current_def.metadata.tags = kwargs["tags"]
         | 
| 567 | 
            +
                                        if "specializations" in kwargs:
         | 
| 568 | 
            +
                                            current_def.metadata.specializations = kwargs[
         | 
| 569 | 
            +
                                                "specializations"
         | 
| 570 | 
            +
                                            ]
         | 
| 571 | 
            +
             | 
| 571 572 | 
             
                                        # Update via AgentManager
         | 
| 572 573 | 
             
                                        updated_def = await self._run_sync_in_executor(
         | 
| 573 574 | 
             
                                            self.agent_manager.update_agent,
         | 
| 574 | 
            -
                                            agent_name, | 
| 575 | 
            +
                                            agent_name,
         | 
| 576 | 
            +
                                            {"raw_content": agent_content},
         | 
| 577 | 
            +
                                            True,
         | 
| 575 578 | 
             
                                        )
         | 
| 576 | 
            -
             | 
| 579 | 
            +
             | 
| 577 580 | 
             
                                        if not updated_def:
         | 
| 578 581 | 
             
                                            raise Exception("AgentManager update failed")
         | 
| 579 582 | 
             
                                    else:
         | 
| @@ -589,16 +592,16 @@ class AgentLifecycleManager(BaseService): | |
| 589 592 | 
             
                                file_path = Path(record.file_path)
         | 
| 590 593 | 
             
                                if path_ops.validate_exists(file_path):
         | 
| 591 594 | 
             
                                    path_ops.safe_write(file_path, agent_content)
         | 
| 592 | 
            -
             | 
| 595 | 
            +
             | 
| 593 596 | 
             
                            # Track modification
         | 
| 594 597 | 
             
                            modification = await self.modification_tracker.track_modification(
         | 
| 595 598 | 
             
                                agent_name=agent_name,
         | 
| 596 599 | 
             
                                modification_type=ModificationType.MODIFY,
         | 
| 597 600 | 
             
                                file_path=record.file_path,
         | 
| 598 601 | 
             
                                tier=record.tier,
         | 
| 599 | 
            -
                                **kwargs
         | 
| 602 | 
            +
                                **kwargs,
         | 
| 600 603 | 
             
                            )
         | 
| 601 | 
            -
             | 
| 604 | 
            +
             | 
| 602 605 | 
             
                            # Create synthetic persistence record for compatibility
         | 
| 603 606 | 
             
                            persistence_record = PersistenceRecord(
         | 
| 604 607 | 
             
                                operation_id=f"update_{agent_name}_{time.time()}",
         | 
| @@ -609,24 +612,24 @@ class AgentLifecycleManager(BaseService): | |
| 609 612 | 
             
                                strategy=self.default_persistence_strategy,
         | 
| 610 613 | 
             
                                success=True,
         | 
| 611 614 | 
             
                                timestamp=time.time(),
         | 
| 612 | 
            -
                                file_path=record.file_path
         | 
| 615 | 
            +
                                file_path=record.file_path,
         | 
| 613 616 | 
             
                            )
         | 
| 614 | 
            -
             | 
| 617 | 
            +
             | 
| 615 618 | 
             
                            # Update lifecycle record
         | 
| 616 619 | 
             
                            record.current_state = LifecycleState.MODIFIED
         | 
| 617 620 | 
             
                            record.last_modified = time.time()
         | 
| 618 621 | 
             
                            record.modifications.append(modification.modification_id)
         | 
| 619 622 | 
             
                            record.persistence_operations.append(persistence_record.operation_id)
         | 
| 620 | 
            -
             | 
| 623 | 
            +
             | 
| 621 624 | 
             
                            # Increment version
         | 
| 622 | 
            -
                            current_version = record.version.split( | 
| 625 | 
            +
                            current_version = record.version.split(".")
         | 
| 623 626 | 
             
                            current_version[-1] = str(int(current_version[-1]) + 1)
         | 
| 624 | 
            -
                            record.version =  | 
| 625 | 
            -
             | 
| 627 | 
            +
                            record.version = ".".join(current_version)
         | 
| 628 | 
            +
             | 
| 626 629 | 
             
                            # Invalidate cache and update registry
         | 
| 627 630 | 
             
                            cache_invalidated = await self._invalidate_agent_cache(agent_name)
         | 
| 628 631 | 
             
                            registry_updated = await self._update_registry(agent_name)
         | 
| 629 | 
            -
             | 
| 632 | 
            +
             | 
| 630 633 | 
             
                            # Create result
         | 
| 631 634 | 
             
                            result = LifecycleOperationResult(
         | 
| 632 635 | 
             
                                operation=LifecycleOperation.UPDATE,
         | 
| @@ -637,55 +640,57 @@ class AgentLifecycleManager(BaseService): | |
| 637 640 | 
             
                                persistence_id=persistence_record.operation_id,
         | 
| 638 641 | 
             
                                cache_invalidated=cache_invalidated,
         | 
| 639 642 | 
             
                                registry_updated=registry_updated,
         | 
| 640 | 
            -
                                metadata={ | 
| 643 | 
            +
                                metadata={"new_version": record.version},
         | 
| 641 644 | 
             
                            )
         | 
| 642 | 
            -
             | 
| 645 | 
            +
             | 
| 643 646 | 
             
                            if not persistence_record.success:
         | 
| 644 647 | 
             
                                result.error_message = persistence_record.error_message
         | 
| 645 648 | 
             
                                record.current_state = LifecycleState.CONFLICTED
         | 
| 646 | 
            -
             | 
| 649 | 
            +
             | 
| 647 650 | 
             
                            # Update performance metrics
         | 
| 648 651 | 
             
                            await self._update_performance_metrics(result)
         | 
| 649 | 
            -
             | 
| 652 | 
            +
             | 
| 650 653 | 
             
                            self.operation_history.append(result)
         | 
| 651 | 
            -
                            self.logger.info( | 
| 652 | 
            -
             | 
| 654 | 
            +
                            self.logger.info(
         | 
| 655 | 
            +
                                f"Updated agent '{agent_name}' to version {record.version} in {result.duration_ms:.1f}ms"
         | 
| 656 | 
            +
                            )
         | 
| 657 | 
            +
             | 
| 653 658 | 
             
                            return result
         | 
| 654 | 
            -
             | 
| 659 | 
            +
             | 
| 655 660 | 
             
                        except Exception as e:
         | 
| 656 661 | 
             
                            result = LifecycleOperationResult(
         | 
| 657 662 | 
             
                                operation=LifecycleOperation.UPDATE,
         | 
| 658 663 | 
             
                                agent_name=agent_name,
         | 
| 659 664 | 
             
                                success=False,
         | 
| 660 665 | 
             
                                duration_ms=(time.time() - start_time) * 1000,
         | 
| 661 | 
            -
                                error_message=str(e)
         | 
| 666 | 
            +
                                error_message=str(e),
         | 
| 662 667 | 
             
                            )
         | 
| 663 | 
            -
             | 
| 668 | 
            +
             | 
| 664 669 | 
             
                            self.operation_history.append(result)
         | 
| 665 670 | 
             
                            await self._update_performance_metrics(result)
         | 
| 666 | 
            -
             | 
| 671 | 
            +
             | 
| 667 672 | 
             
                            self.logger.error(f"Failed to update agent '{agent_name}': {e}")
         | 
| 668 673 | 
             
                            return result
         | 
| 669 | 
            -
             | 
| 674 | 
            +
             | 
| 670 675 | 
             
                        finally:
         | 
| 671 676 | 
             
                            self.active_operations.pop(agent_name, None)
         | 
| 672 | 
            -
             | 
| 677 | 
            +
             | 
| 673 678 | 
             
                async def delete_agent(self, agent_name: str, **kwargs) -> LifecycleOperationResult:
         | 
| 674 679 | 
             
                    """
         | 
| 675 680 | 
             
                    Delete an agent with lifecycle tracking.
         | 
| 676 | 
            -
             | 
| 681 | 
            +
             | 
| 677 682 | 
             
                    Args:
         | 
| 678 683 | 
             
                        agent_name: Name of the agent to delete
         | 
| 679 684 | 
             
                        **kwargs: Additional metadata
         | 
| 680 | 
            -
             | 
| 685 | 
            +
             | 
| 681 686 | 
             
                    Returns:
         | 
| 682 687 | 
             
                        LifecycleOperationResult with operation details
         | 
| 683 688 | 
             
                    """
         | 
| 684 689 | 
             
                    start_time = time.time()
         | 
| 685 | 
            -
             | 
| 690 | 
            +
             | 
| 686 691 | 
             
                    async with self._operation_lock:
         | 
| 687 692 | 
             
                        self.active_operations[agent_name] = LifecycleOperation.DELETE
         | 
| 688 | 
            -
             | 
| 693 | 
            +
             | 
| 689 694 | 
             
                        try:
         | 
| 690 695 | 
             
                            # Check if agent exists
         | 
| 691 696 | 
             
                            if agent_name not in self.agent_records:
         | 
| @@ -694,16 +699,16 @@ class AgentLifecycleManager(BaseService): | |
| 694 699 | 
             
                                    agent_name=agent_name,
         | 
| 695 700 | 
             
                                    success=False,
         | 
| 696 701 | 
             
                                    duration_ms=(time.time() - start_time) * 1000,
         | 
| 697 | 
            -
                                    error_message="Agent not found"
         | 
| 702 | 
            +
                                    error_message="Agent not found",
         | 
| 698 703 | 
             
                                )
         | 
| 699 | 
            -
             | 
| 704 | 
            +
             | 
| 700 705 | 
             
                            record = self.agent_records[agent_name]
         | 
| 701 | 
            -
             | 
| 706 | 
            +
             | 
| 702 707 | 
             
                            # Create backup before deletion
         | 
| 703 708 | 
             
                            backup_path = None
         | 
| 704 709 | 
             
                            if self.enable_auto_backup:
         | 
| 705 710 | 
             
                                backup_path = await self._create_deletion_backup(agent_name, record)
         | 
| 706 | 
            -
             | 
| 711 | 
            +
             | 
| 707 712 | 
             
                            # Track modification
         | 
| 708 713 | 
             
                            modification = await self.modification_tracker.track_modification(
         | 
| 709 714 | 
             
                                agent_name=agent_name,
         | 
| @@ -711,9 +716,9 @@ class AgentLifecycleManager(BaseService): | |
| 711 716 | 
             
                                file_path=record.file_path,
         | 
| 712 717 | 
             
                                tier=record.tier,
         | 
| 713 718 | 
             
                                backup_path=backup_path,
         | 
| 714 | 
            -
                                **kwargs
         | 
| 719 | 
            +
                                **kwargs,
         | 
| 715 720 | 
             
                            )
         | 
| 716 | 
            -
             | 
| 721 | 
            +
             | 
| 717 722 | 
             
                            # Delete agent using AgentManager
         | 
| 718 723 | 
             
                            deletion_success = False
         | 
| 719 724 | 
             
                            try:
         | 
| @@ -736,18 +741,18 @@ class AgentLifecycleManager(BaseService): | |
| 736 741 | 
             
                                if path_ops.validate_exists(file_path):
         | 
| 737 742 | 
             
                                    path_ops.safe_delete(file_path)
         | 
| 738 743 | 
             
                                    deletion_success = True
         | 
| 739 | 
            -
             | 
| 744 | 
            +
             | 
| 740 745 | 
             
                            # Update lifecycle record
         | 
| 741 746 | 
             
                            record.current_state = LifecycleState.DELETED
         | 
| 742 747 | 
             
                            record.last_modified = time.time()
         | 
| 743 748 | 
             
                            record.modifications.append(modification.modification_id)
         | 
| 744 749 | 
             
                            if backup_path:
         | 
| 745 750 | 
             
                                record.backup_paths.append(backup_path)
         | 
| 746 | 
            -
             | 
| 751 | 
            +
             | 
| 747 752 | 
             
                            # Invalidate cache and update registry
         | 
| 748 753 | 
             
                            cache_invalidated = await self._invalidate_agent_cache(agent_name)
         | 
| 749 754 | 
             
                            registry_updated = await self._update_registry(agent_name)
         | 
| 750 | 
            -
             | 
| 755 | 
            +
             | 
| 751 756 | 
             
                            # Create result
         | 
| 752 757 | 
             
                            result = LifecycleOperationResult(
         | 
| 753 758 | 
             
                                operation=LifecycleOperation.DELETE,
         | 
| @@ -757,414 +762,259 @@ class AgentLifecycleManager(BaseService): | |
| 757 762 | 
             
                                modification_id=modification.modification_id,
         | 
| 758 763 | 
             
                                cache_invalidated=cache_invalidated,
         | 
| 759 764 | 
             
                                registry_updated=registry_updated,
         | 
| 760 | 
            -
                                metadata={ | 
| 765 | 
            +
                                metadata={"backup_path": backup_path},
         | 
| 761 766 | 
             
                            )
         | 
| 762 | 
            -
             | 
| 767 | 
            +
             | 
| 763 768 | 
             
                            # Update performance metrics
         | 
| 764 769 | 
             
                            await self._update_performance_metrics(result)
         | 
| 765 | 
            -
             | 
| 770 | 
            +
             | 
| 766 771 | 
             
                            self.operation_history.append(result)
         | 
| 767 | 
            -
                            self.logger.info( | 
| 768 | 
            -
             | 
| 772 | 
            +
                            self.logger.info(
         | 
| 773 | 
            +
                                f"Deleted agent '{agent_name}' in {result.duration_ms:.1f}ms"
         | 
| 774 | 
            +
                            )
         | 
| 775 | 
            +
             | 
| 769 776 | 
             
                            return result
         | 
| 770 | 
            -
             | 
| 777 | 
            +
             | 
| 771 778 | 
             
                        except Exception as e:
         | 
| 772 779 | 
             
                            result = LifecycleOperationResult(
         | 
| 773 780 | 
             
                                operation=LifecycleOperation.DELETE,
         | 
| 774 781 | 
             
                                agent_name=agent_name,
         | 
| 775 782 | 
             
                                success=False,
         | 
| 776 783 | 
             
                                duration_ms=(time.time() - start_time) * 1000,
         | 
| 777 | 
            -
                                error_message=str(e)
         | 
| 784 | 
            +
                                error_message=str(e),
         | 
| 778 785 | 
             
                            )
         | 
| 779 | 
            -
             | 
| 786 | 
            +
             | 
| 780 787 | 
             
                            self.operation_history.append(result)
         | 
| 781 788 | 
             
                            await self._update_performance_metrics(result)
         | 
| 782 | 
            -
             | 
| 789 | 
            +
             | 
| 783 790 | 
             
                            self.logger.error(f"Failed to delete agent '{agent_name}': {e}")
         | 
| 784 791 | 
             
                            return result
         | 
| 785 | 
            -
             | 
| 792 | 
            +
             | 
| 786 793 | 
             
                        finally:
         | 
| 787 794 | 
             
                            self.active_operations.pop(agent_name, None)
         | 
| 788 | 
            -
             | 
| 789 | 
            -
                async def _determine_agent_file_path( | 
| 795 | 
            +
             | 
| 796 | 
            +
                async def _determine_agent_file_path(
         | 
| 797 | 
            +
                    self, agent_name: str, tier: ModificationTier
         | 
| 798 | 
            +
                ) -> Path:
         | 
| 790 799 | 
             
                    """Determine appropriate file path for agent."""
         | 
| 791 800 | 
             
                    if tier == ModificationTier.USER:
         | 
| 792 | 
            -
                        base_path =  | 
| 801 | 
            +
                        base_path = get_path_manager().get_user_agents_dir()
         | 
| 793 802 | 
             
                    elif tier == ModificationTier.PROJECT:
         | 
| 794 | 
            -
                        base_path =  | 
| 803 | 
            +
                        base_path = get_path_manager().get_project_agents_dir()
         | 
| 795 804 | 
             
                    else:  # SYSTEM
         | 
| 796 | 
            -
                        base_path = Path.cwd() /  | 
| 797 | 
            -
             | 
| 805 | 
            +
                        base_path = Path.cwd() / "claude_pm" / "agents"
         | 
| 806 | 
            +
             | 
| 798 807 | 
             
                    path_ops.ensure_dir(base_path)
         | 
| 799 808 | 
             
                    return base_path / f"{agent_name}_agent.py"
         | 
| 800 | 
            -
             | 
| 801 | 
            -
                async def _create_deletion_backup( | 
| 809 | 
            +
             | 
| 810 | 
            +
                async def _create_deletion_backup(
         | 
| 811 | 
            +
                    self, agent_name: str, record: AgentLifecycleRecord
         | 
| 812 | 
            +
                ) -> Optional[str]:
         | 
| 802 813 | 
             
                    """Create backup before agent deletion."""
         | 
| 803 814 | 
             
                    try:
         | 
| 804 815 | 
             
                        source_path = Path(record.file_path)
         | 
| 805 816 | 
             
                        if not path_ops.validate_exists(source_path):
         | 
| 806 817 | 
             
                            return None
         | 
| 807 | 
            -
             | 
| 808 | 
            -
                        backup_dir =  | 
| 818 | 
            +
             | 
| 819 | 
            +
                        backup_dir = get_path_manager().get_tracking_dir() / "backups"
         | 
| 809 820 | 
             
                        path_ops.ensure_dir(backup_dir)
         | 
| 810 | 
            -
             | 
| 811 | 
            -
                        timestamp = datetime.now().strftime( | 
| 821 | 
            +
             | 
| 822 | 
            +
                        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
         | 
| 812 823 | 
             
                        backup_filename = f"{agent_name}_deleted_{timestamp}{source_path.suffix}"
         | 
| 813 824 | 
             
                        backup_path = backup_dir / backup_filename
         | 
| 814 | 
            -
             | 
| 825 | 
            +
             | 
| 815 826 | 
             
                        path_ops.safe_copy(source_path, backup_path)
         | 
| 816 827 | 
             
                        return str(backup_path)
         | 
| 817 | 
            -
             | 
| 828 | 
            +
             | 
| 818 829 | 
             
                    except Exception as e:
         | 
| 819 | 
            -
                        self.logger.warning( | 
| 830 | 
            +
                        self.logger.warning(
         | 
| 831 | 
            +
                            f"Failed to create deletion backup for {agent_name}: {e}"
         | 
| 832 | 
            +
                        )
         | 
| 820 833 | 
             
                        return None
         | 
| 821 | 
            -
             | 
| 834 | 
            +
             | 
| 822 835 | 
             
                async def _invalidate_agent_cache(self, agent_name: str) -> bool:
         | 
| 823 836 | 
             
                    """Invalidate cache entries for agent."""
         | 
| 824 837 | 
             
                    if not self.enable_cache_invalidation or not self.shared_cache:
         | 
| 825 838 | 
             
                        return False
         | 
| 826 | 
            -
             | 
| 839 | 
            +
             | 
| 827 840 | 
             
                    try:
         | 
| 828 841 | 
             
                        patterns = [
         | 
| 829 842 | 
             
                            f"agent_profile:{agent_name}:*",
         | 
| 830 843 | 
             
                            f"task_prompt:{agent_name}:*",
         | 
| 831 844 | 
             
                            f"agent_registry_discovery",
         | 
| 832 | 
            -
                            f"agent_profile_enhanced:{agent_name}:*"
         | 
| 845 | 
            +
                            f"agent_profile_enhanced:{agent_name}:*",
         | 
| 833 846 | 
             
                        ]
         | 
| 834 | 
            -
             | 
| 847 | 
            +
             | 
| 835 848 | 
             
                        for pattern in patterns:
         | 
| 836 849 | 
             
                            await asyncio.get_event_loop().run_in_executor(
         | 
| 837 | 
            -
                                None, 
         | 
| 838 | 
            -
                                lambda p=pattern: self.shared_cache.invalidate(p)
         | 
| 850 | 
            +
                                None, lambda p=pattern: self.shared_cache.invalidate(p)
         | 
| 839 851 | 
             
                            )
         | 
| 840 | 
            -
             | 
| 852 | 
            +
             | 
| 841 853 | 
             
                        return True
         | 
| 842 | 
            -
             | 
| 854 | 
            +
             | 
| 843 855 | 
             
                    except Exception as e:
         | 
| 844 856 | 
             
                        self.logger.warning(f"Failed to invalidate cache for {agent_name}: {e}")
         | 
| 845 857 | 
             
                        return False
         | 
| 846 | 
            -
             | 
| 858 | 
            +
             | 
| 847 859 | 
             
                async def _update_registry(self, agent_name: str) -> bool:
         | 
| 848 860 | 
             
                    """Update agent registry after modification."""
         | 
| 849 861 | 
             
                    if not self.enable_registry_sync or not self.agent_registry:
         | 
| 850 862 | 
             
                        return False
         | 
| 851 | 
            -
             | 
| 863 | 
            +
             | 
| 852 864 | 
             
                    try:
         | 
| 853 865 | 
             
                        # Refresh registry (discover_agents is synchronous)
         | 
| 854 866 | 
             
                        self.agent_registry.discover_agents()
         | 
| 855 867 | 
             
                        return True
         | 
| 856 | 
            -
             | 
| 868 | 
            +
             | 
| 857 869 | 
             
                    except Exception as e:
         | 
| 858 870 | 
             
                        self.logger.warning(f"Failed to update registry for {agent_name}: {e}")
         | 
| 859 871 | 
             
                        return False
         | 
| 860 | 
            -
             | 
| 861 | 
            -
                async def _update_performance_metrics( | 
| 862 | 
            -
                     | 
| 863 | 
            -
             | 
| 864 | 
            -
                     | 
| 865 | 
            -
                     | 
| 866 | 
            -
             | 
| 867 | 
            -
                     | 
| 868 | 
            -
             | 
| 869 | 
            -
             | 
| 870 | 
            -
                       - Cache invalidation events
         | 
| 871 | 
            -
                       - Operation type and agent tier
         | 
| 872 | 
            -
                    
         | 
| 873 | 
            -
                    2. TRANSFORM: Calculate derived metrics
         | 
| 874 | 
            -
                       - Success rates and failure percentages
         | 
| 875 | 
            -
                       - Rolling averages for performance
         | 
| 876 | 
            -
                       - Operation distribution by type
         | 
| 877 | 
            -
                       - Performance by agent tier
         | 
| 878 | 
            -
                    
         | 
| 879 | 
            -
                    3. LOAD: Store in metrics structure
         | 
| 880 | 
            -
                       - In-memory storage for real-time access
         | 
| 881 | 
            -
                       - Could be extended to push to:
         | 
| 882 | 
            -
                         * Time-series databases (Prometheus, InfluxDB)
         | 
| 883 | 
            -
                         * AI observability platforms (Datadog, New Relic)
         | 
| 884 | 
            -
                         * Custom analytics pipelines
         | 
| 885 | 
            -
                    
         | 
| 886 | 
            -
                    OPTIMIZATION OPPORTUNITIES:
         | 
| 887 | 
            -
                    - Add percentile calculations (p50, p95, p99)
         | 
| 888 | 
            -
                    - Track operation queuing times
         | 
| 889 | 
            -
                    - Monitor resource usage per operation
         | 
| 890 | 
            -
                    - Implement sliding window metrics
         | 
| 891 | 
            -
                    """
         | 
| 892 | 
            -
                    self.performance_metrics['total_operations'] += 1
         | 
| 893 | 
            -
                    
         | 
| 894 | 
            -
                    if result.success:
         | 
| 895 | 
            -
                        self.performance_metrics['successful_operations'] += 1
         | 
| 896 | 
            -
                    else:
         | 
| 897 | 
            -
                        self.performance_metrics['failed_operations'] += 1
         | 
| 898 | 
            -
                    
         | 
| 899 | 
            -
                    # Update average duration using incremental calculation
         | 
| 900 | 
            -
                    # This avoids storing all durations in memory
         | 
| 901 | 
            -
                    total_ops = self.performance_metrics['total_operations']
         | 
| 902 | 
            -
                    current_avg = self.performance_metrics['average_duration_ms']
         | 
| 903 | 
            -
                    new_avg = ((current_avg * (total_ops - 1)) + result.duration_ms) / total_ops
         | 
| 904 | 
            -
                    self.performance_metrics['average_duration_ms'] = new_avg
         | 
| 905 | 
            -
                    
         | 
| 906 | 
            -
                    # METRICS: Track operation type distribution
         | 
| 907 | 
            -
                    # This helps identify which operations are most common
         | 
| 908 | 
            -
                    op_type = result.operation.value
         | 
| 909 | 
            -
                    if 'operation_distribution' not in self.performance_metrics:
         | 
| 910 | 
            -
                        self.performance_metrics['operation_distribution'] = {}
         | 
| 911 | 
            -
                    self.performance_metrics['operation_distribution'][op_type] = \
         | 
| 912 | 
            -
                        self.performance_metrics['operation_distribution'].get(op_type, 0) + 1
         | 
| 913 | 
            -
                    
         | 
| 914 | 
            -
                    # METRICS: Track performance by agent tier
         | 
| 915 | 
            -
                    # Useful for identifying tier-specific performance issues
         | 
| 916 | 
            -
                    if hasattr(result, 'tier') and result.tier:
         | 
| 917 | 
            -
                        if 'tier_performance' not in self.performance_metrics:
         | 
| 918 | 
            -
                            self.performance_metrics['tier_performance'] = {}
         | 
| 919 | 
            -
                        tier_name = result.tier.value if hasattr(result.tier, 'value') else str(result.tier)
         | 
| 920 | 
            -
                        if tier_name not in self.performance_metrics['tier_performance']:
         | 
| 921 | 
            -
                            self.performance_metrics['tier_performance'][tier_name] = {
         | 
| 922 | 
            -
                                'count': 0,
         | 
| 923 | 
            -
                                'total_duration_ms': 0,
         | 
| 924 | 
            -
                                'average_duration_ms': 0
         | 
| 925 | 
            -
                            }
         | 
| 926 | 
            -
                        tier_metrics = self.performance_metrics['tier_performance'][tier_name]
         | 
| 927 | 
            -
                        tier_metrics['count'] += 1
         | 
| 928 | 
            -
                        tier_metrics['total_duration_ms'] += result.duration_ms
         | 
| 929 | 
            -
                        tier_metrics['average_duration_ms'] = \
         | 
| 930 | 
            -
                            tier_metrics['total_duration_ms'] / tier_metrics['count']
         | 
| 931 | 
            -
                    
         | 
| 932 | 
            -
                    # Update cache hit rate if cache was involved
         | 
| 933 | 
            -
                    if result.cache_invalidated:
         | 
| 934 | 
            -
                        # Track cache invalidation frequency
         | 
| 935 | 
            -
                        if 'cache_invalidations' not in self.performance_metrics:
         | 
| 936 | 
            -
                            self.performance_metrics['cache_invalidations'] = 0
         | 
| 937 | 
            -
                        self.performance_metrics['cache_invalidations'] += 1
         | 
| 938 | 
            -
                
         | 
| 872 | 
            +
             | 
| 873 | 
            +
                async def _update_performance_metrics(
         | 
| 874 | 
            +
                    self, result: LifecycleOperationResult
         | 
| 875 | 
            +
                ) -> None:
         | 
| 876 | 
            +
                    """Update performance metrics with operation result."""
         | 
| 877 | 
            +
                    from .lifecycle_performance_tracker import LifecyclePerformanceTracker
         | 
| 878 | 
            +
             | 
| 879 | 
            +
                    tracker = LifecyclePerformanceTracker(self.performance_metrics)
         | 
| 880 | 
            +
                    tracker.update_metrics(result)
         | 
| 881 | 
            +
             | 
| 939 882 | 
             
                async def _handle_modification_event(self, modification: AgentModification) -> None:
         | 
| 940 883 | 
             
                    """Handle modification events from tracker."""
         | 
| 941 884 | 
             
                    try:
         | 
| 942 885 | 
             
                        agent_name = modification.agent_name
         | 
| 943 | 
            -
             | 
| 886 | 
            +
             | 
| 944 887 | 
             
                        # Update lifecycle record if exists
         | 
| 945 888 | 
             
                        if agent_name in self.agent_records:
         | 
| 946 889 | 
             
                            record = self.agent_records[agent_name]
         | 
| 947 890 | 
             
                            record.last_modified = modification.timestamp
         | 
| 948 891 | 
             
                            record.modifications.append(modification.modification_id)
         | 
| 949 | 
            -
             | 
| 892 | 
            +
             | 
| 950 893 | 
             
                            # Update state based on modification type
         | 
| 951 894 | 
             
                            if modification.modification_type == ModificationType.DELETE:
         | 
| 952 895 | 
             
                                record.current_state = LifecycleState.DELETED
         | 
| 953 | 
            -
                            elif modification.modification_type in [ | 
| 896 | 
            +
                            elif modification.modification_type in [
         | 
| 897 | 
            +
                                ModificationType.CREATE,
         | 
| 898 | 
            +
                                ModificationType.MODIFY,
         | 
| 899 | 
            +
                            ]:
         | 
| 954 900 | 
             
                                record.current_state = LifecycleState.MODIFIED
         | 
| 955 | 
            -
             | 
| 956 | 
            -
                            self.logger.debug( | 
| 957 | 
            -
             | 
| 901 | 
            +
             | 
| 902 | 
            +
                            self.logger.debug(
         | 
| 903 | 
            +
                                f"Updated lifecycle record for {agent_name} due to {modification.modification_type.value}"
         | 
| 904 | 
            +
                            )
         | 
| 905 | 
            +
             | 
| 958 906 | 
             
                    except Exception as e:
         | 
| 959 907 | 
             
                        self.logger.error(f"Error handling modification event: {e}")
         | 
| 960 | 
            -
             | 
| 961 | 
            -
                 | 
| 962 | 
            -
             | 
| 963 | 
            -
                    try:
         | 
| 964 | 
            -
                        # This would test if we can create agents in the configured tiers
         | 
| 965 | 
            -
                        return (self.modification_tracker is not None and 
         | 
| 966 | 
            -
                               self.persistence_service is not None)
         | 
| 967 | 
            -
                    except Exception:
         | 
| 968 | 
            -
                        return False
         | 
| 969 | 
            -
                
         | 
| 970 | 
            -
                async def _test_modify_capability(self) -> bool:
         | 
| 971 | 
            -
                    """Test agent modification capability."""
         | 
| 972 | 
            -
                    try:
         | 
| 973 | 
            -
                        # This would test if we can modify existing agents
         | 
| 974 | 
            -
                        return (self.modification_tracker is not None and 
         | 
| 975 | 
            -
                               self.persistence_service is not None)
         | 
| 976 | 
            -
                    except Exception:
         | 
| 977 | 
            -
                        return False
         | 
| 978 | 
            -
                
         | 
| 979 | 
            -
                async def _test_delete_capability(self) -> bool:
         | 
| 980 | 
            -
                    """Test agent deletion capability."""
         | 
| 981 | 
            -
                    try:
         | 
| 982 | 
            -
                        # This would test if we can delete agents
         | 
| 983 | 
            -
                        return self.modification_tracker is not None
         | 
| 984 | 
            -
                    except Exception:
         | 
| 985 | 
            -
                        return False
         | 
| 986 | 
            -
                
         | 
| 908 | 
            +
             | 
| 909 | 
            +
                # Test capability methods moved to LifecycleHealthChecker
         | 
| 910 | 
            +
             | 
| 987 911 | 
             
                async def _cleanup_core_services(self) -> None:
         | 
| 988 912 | 
             
                    """Cleanup core services if we manage their lifecycle."""
         | 
| 989 913 | 
             
                    try:
         | 
| 990 914 | 
             
                        if self.modification_tracker:
         | 
| 991 915 | 
             
                            await self.modification_tracker.stop()
         | 
| 992 | 
            -
             | 
| 916 | 
            +
             | 
| 993 917 | 
             
                        if self.persistence_service:
         | 
| 994 918 | 
             
                            await self.persistence_service.stop()
         | 
| 995 | 
            -
             | 
| 919 | 
            +
             | 
| 996 920 | 
             
                    except Exception as e:
         | 
| 997 921 | 
             
                        self.logger.error(f"Error cleaning up core services: {e}")
         | 
| 998 | 
            -
             | 
| 922 | 
            +
             | 
| 999 923 | 
             
                # Public API Methods
         | 
| 1000 | 
            -
             | 
| 924 | 
            +
             | 
| 1001 925 | 
             
                async def get_agent_status(self, agent_name: str) -> Optional[AgentLifecycleRecord]:
         | 
| 1002 926 | 
             
                    """Get current status of an agent."""
         | 
| 1003 927 | 
             
                    return self.agent_records.get(agent_name)
         | 
| 1004 | 
            -
             | 
| 1005 | 
            -
                async def list_agents( | 
| 928 | 
            +
             | 
| 929 | 
            +
                async def list_agents(
         | 
| 930 | 
            +
                    self, state_filter: Optional[LifecycleState] = None
         | 
| 931 | 
            +
                ) -> List[AgentLifecycleRecord]:
         | 
| 1006 932 | 
             
                    """List agents with optional state filtering."""
         | 
| 1007 933 | 
             
                    agents = list(self.agent_records.values())
         | 
| 1008 | 
            -
             | 
| 934 | 
            +
             | 
| 1009 935 | 
             
                    if state_filter:
         | 
| 1010 936 | 
             
                        agents = [agent for agent in agents if agent.current_state == state_filter]
         | 
| 1011 | 
            -
             | 
| 937 | 
            +
             | 
| 1012 938 | 
             
                    return sorted(agents, key=lambda x: x.last_modified, reverse=True)
         | 
| 1013 | 
            -
             | 
| 1014 | 
            -
                async def get_operation_history( | 
| 939 | 
            +
             | 
| 940 | 
            +
                async def get_operation_history(
         | 
| 941 | 
            +
                    self, agent_name: Optional[str] = None, limit: int = 100
         | 
| 942 | 
            +
                ) -> List[LifecycleOperationResult]:
         | 
| 1015 943 | 
             
                    """Get operation history with optional filtering."""
         | 
| 1016 944 | 
             
                    history = self.operation_history
         | 
| 1017 | 
            -
             | 
| 945 | 
            +
             | 
| 1018 946 | 
             
                    if agent_name:
         | 
| 1019 947 | 
             
                        history = [op for op in history if op.agent_name == agent_name]
         | 
| 1020 | 
            -
             | 
| 948 | 
            +
             | 
| 1021 949 | 
             
                    return sorted(history, key=lambda x: x.duration_ms, reverse=True)[:limit]
         | 
| 1022 | 
            -
             | 
| 950 | 
            +
             | 
| 1023 951 | 
             
                async def get_lifecycle_stats(self) -> Dict[str, Any]:
         | 
| 1024 952 | 
             
                    """Get comprehensive lifecycle statistics."""
         | 
| 1025 953 | 
             
                    stats = {
         | 
| 1026 | 
            -
                         | 
| 1027 | 
            -
                         | 
| 1028 | 
            -
                         | 
| 954 | 
            +
                        "total_agents": len(self.agent_records),
         | 
| 955 | 
            +
                        "active_operations": len(self.active_operations),
         | 
| 956 | 
            +
                        "performance_metrics": self.performance_metrics.copy(),
         | 
| 1029 957 | 
             
                    }
         | 
| 1030 | 
            -
             | 
| 958 | 
            +
             | 
| 1031 959 | 
             
                    # State distribution
         | 
| 1032 960 | 
             
                    state_counts = {}
         | 
| 1033 961 | 
             
                    for record in self.agent_records.values():
         | 
| 1034 | 
            -
                        state_counts[record.current_state.value] =  | 
| 1035 | 
            -
             | 
| 1036 | 
            -
             | 
| 1037 | 
            -
             | 
| 962 | 
            +
                        state_counts[record.current_state.value] = (
         | 
| 963 | 
            +
                            state_counts.get(record.current_state.value, 0) + 1
         | 
| 964 | 
            +
                        )
         | 
| 965 | 
            +
             | 
| 966 | 
            +
                    stats["agents_by_state"] = state_counts
         | 
| 967 | 
            +
             | 
| 1038 968 | 
             
                    # Tier distribution
         | 
| 1039 969 | 
             
                    tier_counts = {}
         | 
| 1040 970 | 
             
                    for record in self.agent_records.values():
         | 
| 1041 971 | 
             
                        tier_counts[record.tier.value] = tier_counts.get(record.tier.value, 0) + 1
         | 
| 1042 | 
            -
             | 
| 1043 | 
            -
                    stats[ | 
| 1044 | 
            -
             | 
| 972 | 
            +
             | 
| 973 | 
            +
                    stats["agents_by_tier"] = tier_counts
         | 
| 974 | 
            +
             | 
| 1045 975 | 
             
                    # Recent activity
         | 
| 1046 976 | 
             
                    recent_ops = [
         | 
| 1047 | 
            -
                        op | 
| 977 | 
            +
                        op
         | 
| 978 | 
            +
                        for op in self.operation_history
         | 
| 1048 979 | 
             
                        if (time.time() - (op.duration_ms / 1000)) < 3600  # Last hour
         | 
| 1049 980 | 
             
                    ]
         | 
| 1050 | 
            -
                    stats[ | 
| 1051 | 
            -
             | 
| 981 | 
            +
                    stats["recent_operations"] = len(recent_ops)
         | 
| 982 | 
            +
             | 
| 1052 983 | 
             
                    return stats
         | 
| 1053 | 
            -
             | 
| 1054 | 
            -
                async def _create_agent_definition( | 
| 1055 | 
            -
             | 
| 1056 | 
            -
                     | 
| 1057 | 
            -
                     | 
| 1058 | 
            -
                    
         | 
| 1059 | 
            -
                     | 
| 1060 | 
            -
                     | 
| 1061 | 
            -
             | 
| 1062 | 
            -
                     | 
| 1063 | 
            -
                     | 
| 1064 | 
            -
             | 
| 1065 | 
            -
                     | 
| 1066 | 
            -
                     | 
| 1067 | 
            -
             | 
| 1068 | 
            -
                    type_map = {
         | 
| 1069 | 
            -
                        ModificationTier.USER: AgentType.CUSTOM,
         | 
| 1070 | 
            -
                        ModificationTier.PROJECT: AgentType.PROJECT,
         | 
| 1071 | 
            -
                        ModificationTier.SYSTEM: AgentType.SYSTEM
         | 
| 1072 | 
            -
                    }
         | 
| 1073 | 
            -
                    
         | 
| 1074 | 
            -
                    # Create metadata
         | 
| 1075 | 
            -
                    from claude_mpm.models.agent_definition import AgentMetadata, AgentPermissions
         | 
| 1076 | 
            -
                    metadata = AgentMetadata(
         | 
| 1077 | 
            -
                        type=type_map.get(tier, AgentType.CUSTOM),
         | 
| 1078 | 
            -
                        model_preference=kwargs.get('model_preference', 'claude-3-sonnet'),
         | 
| 1079 | 
            -
                        version="1.0.0",
         | 
| 1080 | 
            -
                        author=kwargs.get('author', 'claude-mpm'),
         | 
| 1081 | 
            -
                        tags=kwargs.get('tags', []),
         | 
| 1082 | 
            -
                        specializations=kwargs.get('specializations', [])
         | 
| 1083 | 
            -
                    )
         | 
| 1084 | 
            -
                    
         | 
| 1085 | 
            -
                    # Create minimal definition
         | 
| 1086 | 
            -
                    definition = AgentDefinition(
         | 
| 1087 | 
            -
                        name=agent_name,
         | 
| 1088 | 
            -
                        title=agent_name.replace('-', ' ').title(),
         | 
| 1089 | 
            -
                        file_path="",  # Will be set by AgentManager
         | 
| 1090 | 
            -
                        metadata=metadata,
         | 
| 1091 | 
            -
                        primary_role=kwargs.get('primary_role', f"{agent_name} agent"),
         | 
| 1092 | 
            -
                        when_to_use={"select": [], "do_not_select": []},
         | 
| 1093 | 
            -
                        capabilities=[],
         | 
| 1094 | 
            -
                        authority=AgentPermissions(),
         | 
| 1095 | 
            -
                        workflows=[],
         | 
| 1096 | 
            -
                        escalation_triggers=[],
         | 
| 1097 | 
            -
                        kpis=[],
         | 
| 1098 | 
            -
                        dependencies=[],
         | 
| 1099 | 
            -
                        tools_commands="",
         | 
| 1100 | 
            -
                        raw_content=agent_content
         | 
| 984 | 
            +
             | 
| 985 | 
            +
                async def _create_agent_definition(
         | 
| 986 | 
            +
                    self,
         | 
| 987 | 
            +
                    agent_name: str,
         | 
| 988 | 
            +
                    agent_content: str,
         | 
| 989 | 
            +
                    tier: ModificationTier,
         | 
| 990 | 
            +
                    agent_type: str,
         | 
| 991 | 
            +
                    **kwargs,
         | 
| 992 | 
            +
                ) -> AgentDefinition:
         | 
| 993 | 
            +
                    """Create an AgentDefinition from lifecycle parameters."""
         | 
| 994 | 
            +
                    from .agent_definition_factory import AgentDefinitionFactory
         | 
| 995 | 
            +
             | 
| 996 | 
            +
                    factory = AgentDefinitionFactory()
         | 
| 997 | 
            +
                    return factory.create_agent_definition(
         | 
| 998 | 
            +
                        agent_name, agent_content, tier, agent_type, **kwargs
         | 
| 1101 999 | 
             
                    )
         | 
| 1102 | 
            -
             | 
| 1103 | 
            -
                    return definition
         | 
| 1104 | 
            -
                
         | 
| 1000 | 
            +
             | 
| 1105 1001 | 
             
                async def _run_sync_in_executor(self, func, *args, **kwargs):
         | 
| 1106 1002 | 
             
                    """
         | 
| 1107 1003 | 
             
                    Run a synchronous function in an executor to avoid blocking.
         | 
| 1108 | 
            -
             | 
| 1004 | 
            +
             | 
| 1109 1005 | 
             
                    WHY: AgentManager has synchronous methods but AgentLifecycleManager is async.
         | 
| 1110 1006 | 
             
                    This allows us to call sync methods without blocking the event loop.
         | 
| 1111 | 
            -
             | 
| 1007 | 
            +
             | 
| 1112 1008 | 
             
                    PERFORMANCE: Uses the default executor which manages a thread pool efficiently.
         | 
| 1113 1009 | 
             
                    """
         | 
| 1114 1010 | 
             
                    loop = asyncio.get_event_loop()
         | 
| 1115 1011 | 
             
                    return await loop.run_in_executor(None, func, *args, **kwargs)
         | 
| 1116 | 
            -
             | 
| 1117 | 
            -
                async def restore_agent( | 
| 1012 | 
            +
             | 
| 1013 | 
            +
                async def restore_agent(
         | 
| 1014 | 
            +
                    self, agent_name: str, backup_path: Optional[str] = None
         | 
| 1015 | 
            +
                ) -> LifecycleOperationResult:
         | 
| 1118 1016 | 
             
                    """Restore agent from backup."""
         | 
| 1119 | 
            -
                     | 
| 1120 | 
            -
             | 
| 1121 | 
            -
                     | 
| 1122 | 
            -
             | 
| 1123 | 
            -
                        if not record:
         | 
| 1124 | 
            -
                            return LifecycleOperationResult(
         | 
| 1125 | 
            -
                                operation=LifecycleOperation.RESTORE,
         | 
| 1126 | 
            -
                                agent_name=agent_name,
         | 
| 1127 | 
            -
                                success=False,
         | 
| 1128 | 
            -
                                duration_ms=(time.time() - start_time) * 1000,
         | 
| 1129 | 
            -
                                error_message="Agent record not found"
         | 
| 1130 | 
            -
                            )
         | 
| 1131 | 
            -
                        
         | 
| 1132 | 
            -
                        # Use latest backup if not specified
         | 
| 1133 | 
            -
                        if not backup_path and record.backup_paths:
         | 
| 1134 | 
            -
                            backup_path = record.backup_paths[-1]
         | 
| 1135 | 
            -
                        
         | 
| 1136 | 
            -
                        if not backup_path or not path_ops.validate_exists(backup_path):
         | 
| 1137 | 
            -
                            return LifecycleOperationResult(
         | 
| 1138 | 
            -
                                operation=LifecycleOperation.RESTORE,
         | 
| 1139 | 
            -
                                agent_name=agent_name,
         | 
| 1140 | 
            -
                                success=False,
         | 
| 1141 | 
            -
                                duration_ms=(time.time() - start_time) * 1000,
         | 
| 1142 | 
            -
                                error_message="No valid backup found"
         | 
| 1143 | 
            -
                            )
         | 
| 1144 | 
            -
                        
         | 
| 1145 | 
            -
                        # Read backup content
         | 
| 1146 | 
            -
                        backup_content = path_ops.safe_read(backup_path)
         | 
| 1147 | 
            -
                        if not backup_content:
         | 
| 1148 | 
            -
                            return LifecycleOperationResult(
         | 
| 1149 | 
            -
                                operation=LifecycleOperation.RESTORE,
         | 
| 1150 | 
            -
                                agent_name=agent_name,
         | 
| 1151 | 
            -
                                success=False,
         | 
| 1152 | 
            -
                                duration_ms=(time.time() - start_time) * 1000,
         | 
| 1153 | 
            -
                                error_message="Failed to read backup content"
         | 
| 1154 | 
            -
                            )
         | 
| 1155 | 
            -
                        
         | 
| 1156 | 
            -
                        # Restore via update operation
         | 
| 1157 | 
            -
                        return await self.update_agent(
         | 
| 1158 | 
            -
                            agent_name=agent_name,
         | 
| 1159 | 
            -
                            agent_content=backup_content,
         | 
| 1160 | 
            -
                            restored_from=backup_path
         | 
| 1161 | 
            -
                        )
         | 
| 1162 | 
            -
                        
         | 
| 1163 | 
            -
                    except Exception as e:
         | 
| 1164 | 
            -
                        return LifecycleOperationResult(
         | 
| 1165 | 
            -
                            operation=LifecycleOperation.RESTORE,
         | 
| 1166 | 
            -
                            agent_name=agent_name,
         | 
| 1167 | 
            -
                            success=False,
         | 
| 1168 | 
            -
                            duration_ms=(time.time() - start_time) * 1000,
         | 
| 1169 | 
            -
                            error_message=str(e)
         | 
| 1170 | 
            -
                        )
         | 
| 1017 | 
            +
                    from .agent_restore_handler import AgentRestoreHandler
         | 
| 1018 | 
            +
             | 
| 1019 | 
            +
                    handler = AgentRestoreHandler(self)
         | 
| 1020 | 
            +
                    return await handler.restore_agent(agent_name, backup_path)
         |