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
| @@ -0,0 +1,217 @@ | |
| 1 | 
            +
            from pathlib import Path
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            """Experimental features configuration for Claude MPM.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            WHY: This module manages experimental and beta features, providing a centralized
         | 
| 6 | 
            +
            way to control feature flags and display appropriate warnings to users.
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            DESIGN DECISION: Use a simple configuration class with static defaults that can
         | 
| 9 | 
            +
            be overridden through environment variables or config files. This allows for
         | 
| 10 | 
            +
            gradual rollout of experimental features while maintaining stability in production.
         | 
| 11 | 
            +
            """
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            import json
         | 
| 14 | 
            +
            import os
         | 
| 15 | 
            +
            from typing import Any, Dict, Optional
         | 
| 16 | 
            +
             | 
| 17 | 
            +
             | 
| 18 | 
            +
            class ExperimentalFeatures:
         | 
| 19 | 
            +
                """Manages experimental feature flags and warnings.
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                WHY: Experimental features need special handling to ensure users understand
         | 
| 22 | 
            +
                they are using beta functionality that may change or have issues.
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                DESIGN DECISION: Use environment variables for quick override during development,
         | 
| 25 | 
            +
                but also support configuration files for persistent settings.
         | 
| 26 | 
            +
                """
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                # Default feature flags
         | 
| 29 | 
            +
                DEFAULTS = {
         | 
| 30 | 
            +
                    "enable_mcp_gateway": False,  # MCP Gateway is experimental
         | 
| 31 | 
            +
                    "enable_advanced_aggregation": False,  # Advanced aggregation features
         | 
| 32 | 
            +
                    "show_experimental_warnings": True,  # Show warnings for experimental features
         | 
| 33 | 
            +
                    "require_experimental_acceptance": True,  # Require explicit acceptance
         | 
| 34 | 
            +
                }
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                # Warning messages for experimental features
         | 
| 37 | 
            +
                WARNINGS = {
         | 
| 38 | 
            +
                    "mcp_gateway": (
         | 
| 39 | 
            +
                        "⚠️  EXPERIMENTAL FEATURE: MCP Gateway is in early access.\n"
         | 
| 40 | 
            +
                        "   Tool integration may be unstable. Not recommended for production use."
         | 
| 41 | 
            +
                    ),
         | 
| 42 | 
            +
                    "advanced_aggregation": (
         | 
| 43 | 
            +
                        "⚠️  EXPERIMENTAL FEATURE: Advanced aggregation is under development.\n"
         | 
| 44 | 
            +
                        "   Results may vary. Please verify outputs manually."
         | 
| 45 | 
            +
                    ),
         | 
| 46 | 
            +
                }
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def __init__(self, config_file: Optional[Path] = None):
         | 
| 49 | 
            +
                    """Initialize experimental features configuration.
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    Args:
         | 
| 52 | 
            +
                        config_file: Optional path to configuration file
         | 
| 53 | 
            +
                    """
         | 
| 54 | 
            +
                    self._features = self.DEFAULTS.copy()
         | 
| 55 | 
            +
                    self._config_file = config_file
         | 
| 56 | 
            +
                    self._load_configuration()
         | 
| 57 | 
            +
                    self._apply_environment_overrides()
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                def _load_configuration(self):
         | 
| 60 | 
            +
                    """Load configuration from file if it exists.
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    WHY: Allow persistent configuration of experimental features without
         | 
| 63 | 
            +
                    requiring environment variables to be set every time.
         | 
| 64 | 
            +
                    """
         | 
| 65 | 
            +
                    if self._config_file and self._config_file.exists():
         | 
| 66 | 
            +
                        try:
         | 
| 67 | 
            +
                            with open(self._config_file, "r") as f:
         | 
| 68 | 
            +
                                config = json.load(f)
         | 
| 69 | 
            +
                                experimental = config.get("experimental_features", {})
         | 
| 70 | 
            +
                                self._features.update(experimental)
         | 
| 71 | 
            +
                        except Exception:
         | 
| 72 | 
            +
                            # Silently ignore configuration errors for experimental features
         | 
| 73 | 
            +
                            pass
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                def _apply_environment_overrides(self):
         | 
| 76 | 
            +
                    """Apply environment variable overrides.
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                    WHY: Environment variables provide a quick way to enable/disable features
         | 
| 79 | 
            +
                    during development and testing without modifying configuration files.
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                    Format: CLAUDE_MPM_EXPERIMENTAL_<FEATURE_NAME>=true/false
         | 
| 82 | 
            +
                    """
         | 
| 83 | 
            +
                    for key in self._features:
         | 
| 84 | 
            +
                        env_key = f"CLAUDE_MPM_EXPERIMENTAL_{key.upper()}"
         | 
| 85 | 
            +
                        if env_key in os.environ:
         | 
| 86 | 
            +
                            value = os.environ[env_key].lower()
         | 
| 87 | 
            +
                            self._features[key] = value in ("true", "1", "yes", "on")
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                def is_enabled(self, feature: str) -> bool:
         | 
| 90 | 
            +
                    """Check if a feature is enabled.
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                    Args:
         | 
| 93 | 
            +
                        feature: Feature name (without 'enable_' prefix)
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                    Returns:
         | 
| 96 | 
            +
                        True if the feature is enabled
         | 
| 97 | 
            +
                    """
         | 
| 98 | 
            +
                    key = f"enable_{feature}" if not feature.startswith("enable_") else feature
         | 
| 99 | 
            +
                    return self._features.get(key, False)
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                def get_warning(self, feature: str) -> Optional[str]:
         | 
| 102 | 
            +
                    """Get warning message for a feature.
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                    Args:
         | 
| 105 | 
            +
                        feature: Feature name
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                    Returns:
         | 
| 108 | 
            +
                        Warning message or None if no warning exists
         | 
| 109 | 
            +
                    """
         | 
| 110 | 
            +
                    return self.WARNINGS.get(feature)
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                def should_show_warning(self, feature: str) -> bool:
         | 
| 113 | 
            +
                    """Check if warning should be shown for a feature.
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                    Args:
         | 
| 116 | 
            +
                        feature: Feature name
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                    Returns:
         | 
| 119 | 
            +
                        True if warning should be displayed
         | 
| 120 | 
            +
                    """
         | 
| 121 | 
            +
                    if not self._features.get("show_experimental_warnings", True):
         | 
| 122 | 
            +
                        return False
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                    # Check if user has already accepted this feature
         | 
| 125 | 
            +
                    accepted_file = Path.home() / ".claude-mpm" / ".experimental_accepted"
         | 
| 126 | 
            +
                    if accepted_file.exists():
         | 
| 127 | 
            +
                        try:
         | 
| 128 | 
            +
                            with open(accepted_file, "r") as f:
         | 
| 129 | 
            +
                                accepted = json.load(f)
         | 
| 130 | 
            +
                                if feature in accepted.get("features", []):
         | 
| 131 | 
            +
                                    return False
         | 
| 132 | 
            +
                        except Exception:
         | 
| 133 | 
            +
                            pass
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                    return True
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                def mark_accepted(self, feature: str):
         | 
| 138 | 
            +
                    """Mark a feature as accepted by the user.
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                    WHY: Once a user accepts the experimental status, we don't need to
         | 
| 141 | 
            +
                    warn them every time they use the feature.
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                    Args:
         | 
| 144 | 
            +
                        feature: Feature name to mark as accepted
         | 
| 145 | 
            +
                    """
         | 
| 146 | 
            +
                    accepted_file = Path.home() / ".claude-mpm" / ".experimental_accepted"
         | 
| 147 | 
            +
                    accepted_file.parent.mkdir(parents=True, exist_ok=True)
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                    try:
         | 
| 150 | 
            +
                        if accepted_file.exists():
         | 
| 151 | 
            +
                            with open(accepted_file, "r") as f:
         | 
| 152 | 
            +
                                data = json.load(f)
         | 
| 153 | 
            +
                        else:
         | 
| 154 | 
            +
                            data = {"features": [], "timestamp": {}}
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                        if feature not in data["features"]:
         | 
| 157 | 
            +
                            data["features"].append(feature)
         | 
| 158 | 
            +
                            data["timestamp"][feature] = os.environ.get(
         | 
| 159 | 
            +
                                "CLAUDE_MPM_TIMESTAMP", str(Path.cwd())
         | 
| 160 | 
            +
                            )
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                        with open(accepted_file, "w") as f:
         | 
| 163 | 
            +
                            json.dump(data, f, indent=2)
         | 
| 164 | 
            +
                    except Exception:
         | 
| 165 | 
            +
                        # Silently ignore errors in acceptance tracking
         | 
| 166 | 
            +
                        pass
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                def requires_acceptance(self) -> bool:
         | 
| 169 | 
            +
                    """Check if experimental features require explicit acceptance.
         | 
| 170 | 
            +
             | 
| 171 | 
            +
                    Returns:
         | 
| 172 | 
            +
                        True if acceptance is required
         | 
| 173 | 
            +
                    """
         | 
| 174 | 
            +
                    return self._features.get("require_experimental_acceptance", True)
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                def get_all_features(self) -> Dict[str, bool]:
         | 
| 177 | 
            +
                    """Get all feature flags and their current values.
         | 
| 178 | 
            +
             | 
| 179 | 
            +
                    Returns:
         | 
| 180 | 
            +
                        Dictionary of feature flags and their values
         | 
| 181 | 
            +
                    """
         | 
| 182 | 
            +
                    return self._features.copy()
         | 
| 183 | 
            +
             | 
| 184 | 
            +
             | 
| 185 | 
            +
            # Global instance for easy access
         | 
| 186 | 
            +
            _experimental_features = None
         | 
| 187 | 
            +
             | 
| 188 | 
            +
             | 
| 189 | 
            +
            def get_experimental_features(
         | 
| 190 | 
            +
                config_file: Optional[Path] = None,
         | 
| 191 | 
            +
            ) -> ExperimentalFeatures:
         | 
| 192 | 
            +
                """Get the global experimental features instance.
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                WHY: Provide a singleton-like access pattern to experimental features
         | 
| 195 | 
            +
                configuration to ensure consistency across the application.
         | 
| 196 | 
            +
             | 
| 197 | 
            +
                Args:
         | 
| 198 | 
            +
                    config_file: Optional configuration file path
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                Returns:
         | 
| 201 | 
            +
                    ExperimentalFeatures instance
         | 
| 202 | 
            +
                """
         | 
| 203 | 
            +
                global _experimental_features
         | 
| 204 | 
            +
                if _experimental_features is None:
         | 
| 205 | 
            +
                    # Check for config file in standard locations
         | 
| 206 | 
            +
                    if config_file is None:
         | 
| 207 | 
            +
                        for path in [
         | 
| 208 | 
            +
                            Path.cwd() / ".claude-mpm" / "experimental.json",
         | 
| 209 | 
            +
                            Path.home() / ".claude-mpm" / "experimental.json",
         | 
| 210 | 
            +
                        ]:
         | 
| 211 | 
            +
                            if path.exists():
         | 
| 212 | 
            +
                                config_file = path
         | 
| 213 | 
            +
                                break
         | 
| 214 | 
            +
             | 
| 215 | 
            +
                    _experimental_features = ExperimentalFeatures(config_file)
         | 
| 216 | 
            +
             | 
| 217 | 
            +
                return _experimental_features
         | 
    
        claude_mpm/config/paths.py
    CHANGED
    
    | @@ -1,317 +1,203 @@ | |
| 1 1 | 
             
            """
         | 
| 2 2 | 
             
            Centralized path management for claude-mpm.
         | 
| 3 3 |  | 
| 4 | 
            +
            This module provides the primary interface for path management operations.
         | 
| 5 | 
            +
            All functionality has been consolidated into the unified path management system.
         | 
| 6 | 
            +
             | 
| 4 7 | 
             
            This module provides a consistent, reliable way to access project paths
         | 
| 5 8 | 
             
            without fragile parent.parent.parent patterns.
         | 
| 6 9 | 
             
            """
         | 
| 7 10 |  | 
| 8 | 
            -
            import  | 
| 11 | 
            +
            import logging
         | 
| 9 12 | 
             
            import sys
         | 
| 10 13 | 
             
            from pathlib import Path
         | 
| 11 14 | 
             
            from typing import Optional, Union
         | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 15 | 
            +
             | 
| 16 | 
            +
            # Import from the unified path management system
         | 
| 17 | 
            +
            from ..core.unified_paths import get_path_manager
         | 
| 14 18 |  | 
| 15 19 | 
             
            logger = logging.getLogger(__name__)
         | 
| 16 20 |  | 
| 17 21 |  | 
| 18 22 | 
             
            class ClaudeMPMPaths:
         | 
| 19 23 | 
             
                """
         | 
| 20 | 
            -
                 | 
| 21 | 
            -
             | 
| 22 | 
            -
                This class provides  | 
| 23 | 
            -
             | 
| 24 | 
            -
                
         | 
| 24 | 
            +
                Primary interface for the unified path management system.
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                This class provides access to all path operations through the UnifiedPathManager.
         | 
| 27 | 
            +
             | 
| 25 28 | 
             
                Usage:
         | 
| 26 29 | 
             
                    from claude_mpm.config.paths import paths
         | 
| 27 | 
            -
             | 
| 30 | 
            +
             | 
| 28 31 | 
             
                    # Access common paths
         | 
| 29 32 | 
             
                    project_root = paths.project_root
         | 
| 30 33 | 
             
                    agents_dir = paths.agents_dir
         | 
| 31 34 | 
             
                    config_file = paths.config_dir / "some_config.yaml"
         | 
| 32 35 | 
             
                """
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                _instance: Optional[ | 
| 35 | 
            -
                 | 
| 36 | 
            -
             | 
| 37 | 
            -
                
         | 
| 38 | 
            -
                def __new__(cls) -> 'ClaudeMPMPaths':
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                _instance: Optional["ClaudeMPMPaths"] = None
         | 
| 38 | 
            +
                _path_manager = None
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def __new__(cls) -> "ClaudeMPMPaths":
         | 
| 39 41 | 
             
                    """Singleton pattern to ensure single instance."""
         | 
| 40 42 | 
             
                    if cls._instance is None:
         | 
| 41 43 | 
             
                        cls._instance = super().__new__(cls)
         | 
| 42 44 | 
             
                    return cls._instance
         | 
| 43 | 
            -
             | 
| 45 | 
            +
             | 
| 44 46 | 
             
                def __init__(self):
         | 
| 45 | 
            -
                    """Initialize paths  | 
| 46 | 
            -
                    if self. | 
| 47 | 
            -
                        self. | 
| 48 | 
            -
             | 
| 49 | 
            -
                
         | 
| 50 | 
            -
                 | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
                    
         | 
| 54 | 
            -
                    Strategy:
         | 
| 55 | 
            -
                    1. Look for definitive project markers (pyproject.toml, setup.py)
         | 
| 56 | 
            -
                    2. Look for combination of markers to ensure we're at the right level
         | 
| 57 | 
            -
                    3. Walk up from current file location
         | 
| 58 | 
            -
                    4. Handle both development and installed environments
         | 
| 59 | 
            -
                    """
         | 
| 60 | 
            -
                    # Start from this file's location
         | 
| 61 | 
            -
                    current = Path(__file__).resolve()
         | 
| 62 | 
            -
                    
         | 
| 63 | 
            -
                    # Check if we're in an installed environment (site-packages)
         | 
| 64 | 
            -
                    # In pip/pipx installs, the package is directly in site-packages
         | 
| 65 | 
            -
                    if 'site-packages' in str(current) or 'dist-packages' in str(current):
         | 
| 66 | 
            -
                        # We're in an installed environment
         | 
| 67 | 
            -
                        # The claude_mpm package directory itself is the "root" for resources
         | 
| 68 | 
            -
                        import claude_mpm
         | 
| 69 | 
            -
                        self._project_root = Path(claude_mpm.__file__).parent
         | 
| 70 | 
            -
                        self._is_installed = True
         | 
| 71 | 
            -
                        logger.debug(f"Installed environment detected, using package dir: {self._project_root}")
         | 
| 72 | 
            -
                        return
         | 
| 73 | 
            -
                    
         | 
| 74 | 
            -
                    # We're in a development environment, look for project markers
         | 
| 75 | 
            -
                    for parent in current.parents:
         | 
| 76 | 
            -
                        # Check for definitive project root indicators
         | 
| 77 | 
            -
                        # Prioritize pyproject.toml and setup.py as they're only at root
         | 
| 78 | 
            -
                        if (parent / 'pyproject.toml').exists() or (parent / 'setup.py').exists():
         | 
| 79 | 
            -
                            self._project_root = parent
         | 
| 80 | 
            -
                            self._is_installed = False
         | 
| 81 | 
            -
                            logger.debug(f"Project root detected at: {parent} (found pyproject.toml or setup.py)")
         | 
| 82 | 
            -
                            return
         | 
| 83 | 
            -
                        
         | 
| 84 | 
            -
                        # Secondary check: .git directory + VERSION file together
         | 
| 85 | 
            -
                        # This combination is more likely to be the real project root
         | 
| 86 | 
            -
                        if (parent / '.git').exists() and (parent / 'VERSION').exists():
         | 
| 87 | 
            -
                            self._project_root = parent
         | 
| 88 | 
            -
                            self._is_installed = False
         | 
| 89 | 
            -
                            logger.debug(f"Project root detected at: {parent} (found .git and VERSION)")
         | 
| 90 | 
            -
                            return
         | 
| 91 | 
            -
                    
         | 
| 92 | 
            -
                    # Fallback: walk up to find claude-mpm directory name
         | 
| 93 | 
            -
                    for parent in current.parents:
         | 
| 94 | 
            -
                        if parent.name == 'claude-mpm':
         | 
| 95 | 
            -
                            self._project_root = parent
         | 
| 96 | 
            -
                            self._is_installed = False
         | 
| 97 | 
            -
                            logger.debug(f"Project root detected at: {parent} (by directory name)")
         | 
| 98 | 
            -
                            return
         | 
| 99 | 
            -
                    
         | 
| 100 | 
            -
                    # Last resort fallback: 3 levels up from this file
         | 
| 101 | 
            -
                    # paths.py is in src/claude_mpm/config/
         | 
| 102 | 
            -
                    self._project_root = current.parent.parent.parent
         | 
| 103 | 
            -
                    self._is_installed = False
         | 
| 104 | 
            -
                    logger.warning(f"Project root fallback to: {self._project_root}")
         | 
| 105 | 
            -
                
         | 
| 47 | 
            +
                    """Initialize paths using the unified path manager."""
         | 
| 48 | 
            +
                    if self._path_manager is None:
         | 
| 49 | 
            +
                        self._path_manager = get_path_manager()
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                # ========================================================================
         | 
| 52 | 
            +
                # Compatibility Properties - Delegate to UnifiedPathManager
         | 
| 53 | 
            +
                # ========================================================================
         | 
| 54 | 
            +
             | 
| 106 55 | 
             
                @property
         | 
| 107 56 | 
             
                def project_root(self) -> Path:
         | 
| 108 57 | 
             
                    """Get the project root directory."""
         | 
| 109 | 
            -
                     | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
| 112 | 
            -
                
         | 
| 58 | 
            +
                    return self._path_manager.project_root
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                @property
         | 
| 61 | 
            +
                def framework_root(self) -> Path:
         | 
| 62 | 
            +
                    """Get the framework root directory."""
         | 
| 63 | 
            +
                    return self._path_manager.framework_root
         | 
| 64 | 
            +
             | 
| 113 65 | 
             
                @property
         | 
| 114 66 | 
             
                def src_dir(self) -> Path:
         | 
| 115 67 | 
             
                    """Get the src directory."""
         | 
| 116 | 
            -
                     | 
| 117 | 
            -
             | 
| 118 | 
            -
                        # Return the package directory itself
         | 
| 119 | 
            -
                        return self.project_root.parent
         | 
| 120 | 
            -
                    return self.project_root / "src"
         | 
| 121 | 
            -
                
         | 
| 68 | 
            +
                    return self._path_manager.framework_root / "src"
         | 
| 69 | 
            +
             | 
| 122 70 | 
             
                @property
         | 
| 123 71 | 
             
                def claude_mpm_dir(self) -> Path:
         | 
| 124 72 | 
             
                    """Get the main claude_mpm package directory."""
         | 
| 125 | 
            -
                     | 
| 126 | 
            -
             | 
| 127 | 
            -
                        return self.project_root
         | 
| 128 | 
            -
                    return self.src_dir / "claude_mpm"
         | 
| 129 | 
            -
                
         | 
| 73 | 
            +
                    return self._path_manager.package_root
         | 
| 74 | 
            +
             | 
| 130 75 | 
             
                @property
         | 
| 131 76 | 
             
                def agents_dir(self) -> Path:
         | 
| 132 77 | 
             
                    """Get the agents directory."""
         | 
| 133 | 
            -
                     | 
| 134 | 
            -
             | 
| 135 | 
            -
                        return self.project_root / "agents"
         | 
| 136 | 
            -
                    return self.claude_mpm_dir / "agents"
         | 
| 137 | 
            -
                
         | 
| 78 | 
            +
                    return self._path_manager.get_agents_dir("framework")
         | 
| 79 | 
            +
             | 
| 138 80 | 
             
                @property
         | 
| 139 81 | 
             
                def services_dir(self) -> Path:
         | 
| 140 82 | 
             
                    """Get the services directory."""
         | 
| 141 | 
            -
                    return self. | 
| 142 | 
            -
             | 
| 83 | 
            +
                    return self._path_manager.package_root / "services"
         | 
| 84 | 
            +
             | 
| 143 85 | 
             
                @property
         | 
| 144 86 | 
             
                def hooks_dir(self) -> Path:
         | 
| 145 87 | 
             
                    """Get the hooks directory."""
         | 
| 146 | 
            -
                    return self. | 
| 147 | 
            -
             | 
| 88 | 
            +
                    return self._path_manager.package_root / "hooks"
         | 
| 89 | 
            +
             | 
| 148 90 | 
             
                @property
         | 
| 149 91 | 
             
                def config_dir(self) -> Path:
         | 
| 150 92 | 
             
                    """Get the config directory."""
         | 
| 151 | 
            -
                    return self. | 
| 152 | 
            -
             | 
| 93 | 
            +
                    return self._path_manager.package_root / "config"
         | 
| 94 | 
            +
             | 
| 153 95 | 
             
                @property
         | 
| 154 96 | 
             
                def cli_dir(self) -> Path:
         | 
| 155 97 | 
             
                    """Get the CLI directory."""
         | 
| 156 | 
            -
                    return self. | 
| 157 | 
            -
             | 
| 98 | 
            +
                    return self._path_manager.package_root / "cli"
         | 
| 99 | 
            +
             | 
| 158 100 | 
             
                @property
         | 
| 159 101 | 
             
                def core_dir(self) -> Path:
         | 
| 160 102 | 
             
                    """Get the core directory."""
         | 
| 161 | 
            -
                    return self. | 
| 162 | 
            -
             | 
| 103 | 
            +
                    return self._path_manager.package_root / "core"
         | 
| 104 | 
            +
             | 
| 163 105 | 
             
                @property
         | 
| 164 106 | 
             
                def schemas_dir(self) -> Path:
         | 
| 165 107 | 
             
                    """Get the schemas directory."""
         | 
| 166 | 
            -
                    return self. | 
| 167 | 
            -
             | 
| 108 | 
            +
                    return self._path_manager.package_root / "schemas"
         | 
| 109 | 
            +
             | 
| 168 110 | 
             
                @property
         | 
| 169 111 | 
             
                def scripts_dir(self) -> Path:
         | 
| 170 112 | 
             
                    """Get the scripts directory."""
         | 
| 171 | 
            -
                     | 
| 172 | 
            -
             | 
| 173 | 
            -
                        # Return a path that won't cause issues but indicates it's not available
         | 
| 174 | 
            -
                        return Path.home() / '.claude-mpm' / 'scripts'
         | 
| 175 | 
            -
                    return self.project_root / "scripts"
         | 
| 176 | 
            -
                
         | 
| 113 | 
            +
                    return self._path_manager.get_scripts_dir()
         | 
| 114 | 
            +
             | 
| 177 115 | 
             
                @property
         | 
| 178 116 | 
             
                def tests_dir(self) -> Path:
         | 
| 179 117 | 
             
                    """Get the tests directory."""
         | 
| 180 | 
            -
                     | 
| 181 | 
            -
             | 
| 182 | 
            -
                        return Path.home() / '.claude-mpm' / 'tests'
         | 
| 183 | 
            -
                    return self.project_root / "tests"
         | 
| 184 | 
            -
                
         | 
| 118 | 
            +
                    return self._path_manager.project_root / "tests"
         | 
| 119 | 
            +
             | 
| 185 120 | 
             
                @property
         | 
| 186 121 | 
             
                def docs_dir(self) -> Path:
         | 
| 187 122 | 
             
                    """Get the documentation directory."""
         | 
| 188 | 
            -
                     | 
| 189 | 
            -
             | 
| 190 | 
            -
                        return Path.home() / '.claude-mpm' / 'docs'
         | 
| 191 | 
            -
                    return self.project_root / "docs"
         | 
| 192 | 
            -
                
         | 
| 123 | 
            +
                    return self._path_manager.project_root / "docs"
         | 
| 124 | 
            +
             | 
| 193 125 | 
             
                @property
         | 
| 194 126 | 
             
                def logs_dir(self) -> Path:
         | 
| 195 127 | 
             
                    """Get the logs directory (creates if doesn't exist)."""
         | 
| 196 | 
            -
                     | 
| 197 | 
            -
             | 
| 198 | 
            -
             | 
| 199 | 
            -
             | 
| 200 | 
            -
                        logs = self.project_root / "logs"
         | 
| 201 | 
            -
                    logs.mkdir(parents=True, exist_ok=True)
         | 
| 202 | 
            -
                    return logs
         | 
| 203 | 
            -
                
         | 
| 128 | 
            +
                    logs_dir = self._path_manager.get_logs_dir("project")
         | 
| 129 | 
            +
                    self._path_manager.ensure_directory(logs_dir)
         | 
| 130 | 
            +
                    return logs_dir
         | 
| 131 | 
            +
             | 
| 204 132 | 
             
                @property
         | 
| 205 133 | 
             
                def temp_dir(self) -> Path:
         | 
| 206 134 | 
             
                    """Get the temporary files directory (creates if doesn't exist)."""
         | 
| 207 | 
            -
                     | 
| 208 | 
            -
             | 
| 209 | 
            -
             | 
| 210 | 
            -
             | 
| 211 | 
            -
                        temp = self.project_root / ".tmp"
         | 
| 212 | 
            -
                    temp.mkdir(parents=True, exist_ok=True)
         | 
| 213 | 
            -
                    return temp
         | 
| 214 | 
            -
                
         | 
| 135 | 
            +
                    temp_dir = self._path_manager.project_root / ".tmp"
         | 
| 136 | 
            +
                    self._path_manager.ensure_directory(temp_dir)
         | 
| 137 | 
            +
                    return temp_dir
         | 
| 138 | 
            +
             | 
| 215 139 | 
             
                @property
         | 
| 216 140 | 
             
                def claude_mpm_dir_hidden(self) -> Path:
         | 
| 217 141 | 
             
                    """Get the hidden .claude-mpm directory (creates if doesn't exist)."""
         | 
| 218 | 
            -
                     | 
| 219 | 
            -
             | 
| 220 | 
            -
             | 
| 221 | 
            -
             | 
| 222 | 
            -
             | 
| 223 | 
            -
                    hidden.mkdir(exist_ok=True)
         | 
| 224 | 
            -
                    return hidden
         | 
| 225 | 
            -
                
         | 
| 226 | 
            -
                @cached_property
         | 
| 142 | 
            +
                    hidden_dir = self._path_manager.get_config_dir("project")
         | 
| 143 | 
            +
                    self._path_manager.ensure_directory(hidden_dir)
         | 
| 144 | 
            +
                    return hidden_dir
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                @property
         | 
| 227 147 | 
             
                def version_file(self) -> Path:
         | 
| 228 148 | 
             
                    """Get the VERSION file path."""
         | 
| 229 | 
            -
                    return self.project_root / "VERSION"
         | 
| 230 | 
            -
             | 
| 231 | 
            -
                @ | 
| 149 | 
            +
                    return self._path_manager.project_root / "VERSION"
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                @property
         | 
| 232 152 | 
             
                def pyproject_file(self) -> Path:
         | 
| 233 153 | 
             
                    """Get the pyproject.toml file path."""
         | 
| 234 | 
            -
                    return self.project_root / "pyproject.toml"
         | 
| 235 | 
            -
             | 
| 236 | 
            -
                @ | 
| 154 | 
            +
                    return self._path_manager.project_root / "pyproject.toml"
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                @property
         | 
| 237 157 | 
             
                def package_json_file(self) -> Path:
         | 
| 238 158 | 
             
                    """Get the package.json file path."""
         | 
| 239 | 
            -
                    return self.project_root / "package.json"
         | 
| 240 | 
            -
             | 
| 241 | 
            -
                @ | 
| 159 | 
            +
                    return self._path_manager.project_root / "package.json"
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                @property
         | 
| 242 162 | 
             
                def claude_md_file(self) -> Path:
         | 
| 243 163 | 
             
                    """Get the CLAUDE.md file path."""
         | 
| 244 | 
            -
                    return self.project_root / "CLAUDE.md"
         | 
| 245 | 
            -
             | 
| 164 | 
            +
                    return self._path_manager.project_root / "CLAUDE.md"
         | 
| 165 | 
            +
             | 
| 246 166 | 
             
                def get_version(self) -> str:
         | 
| 247 | 
            -
                    """
         | 
| 248 | 
            -
                     | 
| 249 | 
            -
             | 
| 250 | 
            -
                    Returns:
         | 
| 251 | 
            -
                        Version string or 'unknown' if not found.
         | 
| 252 | 
            -
                    """
         | 
| 253 | 
            -
                    # Try VERSION file first
         | 
| 254 | 
            -
                    if self.version_file.exists():
         | 
| 255 | 
            -
                        return self.version_file.read_text().strip()
         | 
| 256 | 
            -
                    
         | 
| 257 | 
            -
                    # Try package metadata
         | 
| 258 | 
            -
                    try:
         | 
| 259 | 
            -
                        from importlib.metadata import version
         | 
| 260 | 
            -
                        return version('claude-mpm')
         | 
| 261 | 
            -
                    except Exception:
         | 
| 262 | 
            -
                        pass
         | 
| 263 | 
            -
                    
         | 
| 264 | 
            -
                    return 'unknown'
         | 
| 265 | 
            -
                
         | 
| 167 | 
            +
                    """Get the project version from various sources."""
         | 
| 168 | 
            +
                    return self._path_manager.get_version()
         | 
| 169 | 
            +
             | 
| 266 170 | 
             
                def ensure_in_path(self) -> None:
         | 
| 267 171 | 
             
                    """Ensure src directory is in Python path."""
         | 
| 268 | 
            -
                     | 
| 269 | 
            -
             | 
| 270 | 
            -
                        sys.path.insert(0, src_str)
         | 
| 271 | 
            -
                
         | 
| 172 | 
            +
                    self._path_manager.ensure_src_in_path()
         | 
| 173 | 
            +
             | 
| 272 174 | 
             
                def relative_to_project(self, path: Union[str, Path]) -> Path:
         | 
| 273 | 
            -
                    """
         | 
| 274 | 
            -
                    Get a path relative to the project root.
         | 
| 275 | 
            -
                    
         | 
| 276 | 
            -
                    Args:
         | 
| 277 | 
            -
                        path: Path to make relative
         | 
| 278 | 
            -
                        
         | 
| 279 | 
            -
                    Returns:
         | 
| 280 | 
            -
                        Path relative to project root
         | 
| 281 | 
            -
                    """
         | 
| 175 | 
            +
                    """Get a path relative to the project root."""
         | 
| 282 176 | 
             
                    abs_path = Path(path).resolve()
         | 
| 283 177 | 
             
                    try:
         | 
| 284 178 | 
             
                        return abs_path.relative_to(self.project_root)
         | 
| 285 179 | 
             
                    except ValueError:
         | 
| 286 180 | 
             
                        return abs_path
         | 
| 287 | 
            -
             | 
| 181 | 
            +
             | 
| 288 182 | 
             
                def resolve_config_path(self, config_name: str) -> Path:
         | 
| 289 | 
            -
                    """
         | 
| 290 | 
            -
                    Resolve a configuration file path.
         | 
| 291 | 
            -
                    
         | 
| 292 | 
            -
                    Args:
         | 
| 293 | 
            -
                        config_name: Name of the config file
         | 
| 294 | 
            -
                        
         | 
| 295 | 
            -
                    Returns:
         | 
| 296 | 
            -
                        Full path to the config file
         | 
| 297 | 
            -
                    """
         | 
| 183 | 
            +
                    """Resolve a configuration file path."""
         | 
| 298 184 | 
             
                    # Check in config directory first
         | 
| 299 185 | 
             
                    config_path = self.config_dir / config_name
         | 
| 300 186 | 
             
                    if config_path.exists():
         | 
| 301 187 | 
             
                        return config_path
         | 
| 302 | 
            -
             | 
| 188 | 
            +
             | 
| 303 189 | 
             
                    # Check in project root
         | 
| 304 190 | 
             
                    root_path = self.project_root / config_name
         | 
| 305 191 | 
             
                    if root_path.exists():
         | 
| 306 192 | 
             
                        return root_path
         | 
| 307 | 
            -
             | 
| 193 | 
            +
             | 
| 308 194 | 
             
                    # Return config dir path as default
         | 
| 309 195 | 
             
                    return config_path
         | 
| 310 | 
            -
             | 
| 196 | 
            +
             | 
| 311 197 | 
             
                def __str__(self) -> str:
         | 
| 312 198 | 
             
                    """String representation."""
         | 
| 313 199 | 
             
                    return f"ClaudeMPMPaths(root={self.project_root})"
         | 
| 314 | 
            -
             | 
| 200 | 
            +
             | 
| 315 201 | 
             
                def __repr__(self) -> str:
         | 
| 316 202 | 
             
                    """Developer representation."""
         | 
| 317 203 | 
             
                    return (
         | 
| @@ -369,4 +255,4 @@ def ensure_src_in_path() -> None: | |
| 369 255 |  | 
| 370 256 |  | 
| 371 257 | 
             
            # Auto-ensure src is in path when module is imported
         | 
| 372 | 
            -
            ensure_src_in_path()
         | 
| 258 | 
            +
            ensure_src_in_path()
         |