claude-mpm 3.4.10__py3-none-any.whl → 5.4.55__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/BUILD_NUMBER +1 -0
- claude_mpm/VERSION +1 -0
- claude_mpm/__init__.py +50 -12
- claude_mpm/__main__.py +7 -2
- claude_mpm/agents/BASE_AGENT.md +164 -0
- claude_mpm/agents/BASE_ENGINEER.md +658 -0
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +290 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
- claude_mpm/agents/MEMORY.md +72 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +1402 -0
- claude_mpm/agents/WORKFLOW.md +111 -0
- claude_mpm/agents/__init__.py +92 -80
- claude_mpm/agents/agent-template.yaml +83 -0
- claude_mpm/agents/agent_loader.py +560 -745
- claude_mpm/agents/agent_loader_integration.py +53 -55
- claude_mpm/agents/agents_metadata.py +186 -27
- claude_mpm/agents/async_agent_loader.py +436 -0
- claude_mpm/agents/base_agent.json +8 -4
- claude_mpm/agents/frontmatter_validator.py +754 -0
- claude_mpm/agents/system_agent_config.py +222 -155
- claude_mpm/agents/templates/README.md +465 -0
- claude_mpm/agents/templates/__init__.py +17 -13
- claude_mpm/agents/templates/circuit-breakers.md +1391 -0
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/git-file-tracking.md +584 -0
- claude_mpm/agents/templates/pm-examples.md +474 -0
- claude_mpm/agents/templates/pm-red-flags.md +310 -0
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -0
- claude_mpm/agents/templates/response-format.md +583 -0
- claude_mpm/agents/templates/structured-questions-examples.md +615 -0
- claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
- claude_mpm/agents/templates/ticketing-examples.md +277 -0
- claude_mpm/agents/templates/validation-templates.md +312 -0
- claude_mpm/cli/__init__.py +90 -128
- claude_mpm/cli/__main__.py +33 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/__init__.py +36 -12
- claude_mpm/cli/commands/agent_manager.py +1403 -0
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +335 -0
- claude_mpm/cli/commands/agents.py +2503 -168
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/aggregate.py +540 -0
- claude_mpm/cli/commands/analyze.py +553 -0
- claude_mpm/cli/commands/analyze_code.py +528 -0
- claude_mpm/cli/commands/auto_configure.py +1053 -0
- claude_mpm/cli/commands/cleanup.py +588 -0
- claude_mpm/cli/commands/cleanup_orphaned_agents.py +150 -0
- claude_mpm/cli/commands/config.py +586 -0
- claude_mpm/cli/commands/configure.py +2654 -0
- claude_mpm/cli/commands/configure_agent_display.py +282 -0
- claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
- claude_mpm/cli/commands/configure_hook_manager.py +225 -0
- claude_mpm/cli/commands/configure_models.py +18 -0
- claude_mpm/cli/commands/configure_navigation.py +184 -0
- claude_mpm/cli/commands/configure_paths.py +104 -0
- claude_mpm/cli/commands/configure_persistence.py +254 -0
- claude_mpm/cli/commands/configure_startup_manager.py +646 -0
- claude_mpm/cli/commands/configure_template_editor.py +497 -0
- claude_mpm/cli/commands/configure_validators.py +73 -0
- claude_mpm/cli/commands/dashboard.py +286 -0
- claude_mpm/cli/commands/debug.py +1386 -0
- claude_mpm/cli/commands/doctor.py +243 -0
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/info.py +195 -74
- claude_mpm/cli/commands/local_deploy.py +534 -0
- claude_mpm/cli/commands/mcp.py +205 -0
- claude_mpm/cli/commands/mcp_command_router.py +161 -0
- claude_mpm/cli/commands/mcp_config.py +154 -0
- claude_mpm/cli/commands/mcp_config_commands.py +20 -0
- claude_mpm/cli/commands/mcp_external_commands.py +249 -0
- claude_mpm/cli/commands/mcp_install_commands.py +346 -0
- claude_mpm/cli/commands/mcp_pipx_config.py +208 -0
- claude_mpm/cli/commands/mcp_server_commands.py +155 -0
- claude_mpm/cli/commands/mcp_setup_external.py +868 -0
- claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
- claude_mpm/cli/commands/memory.py +585 -846
- claude_mpm/cli/commands/monitor.py +228 -310
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +759 -0
- claude_mpm/cli/commands/mpm_init/display.py +341 -0
- claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/modes.py +397 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +722 -0
- claude_mpm/cli/commands/mpm_init_cli.py +396 -0
- claude_mpm/cli/commands/mpm_init_handler.py +195 -0
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/profile.py +276 -0
- claude_mpm/cli/commands/run.py +910 -488
- claude_mpm/cli/commands/search.py +458 -0
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +1246 -0
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/commands/tickets.py +536 -53
- claude_mpm/cli/commands/uninstall.py +176 -0
- claude_mpm/cli/commands/upgrade.py +152 -0
- claude_mpm/cli/commands/verify.py +119 -0
- claude_mpm/cli/executor.py +297 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +21 -0
- claude_mpm/cli/interactive/agent_wizard.py +1947 -0
- claude_mpm/cli/interactive/skills_wizard.py +491 -0
- claude_mpm/cli/parser.py +87 -563
- claude_mpm/cli/parsers/__init__.py +35 -0
- claude_mpm/cli/parsers/agent_manager_parser.py +393 -0
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +575 -0
- claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
- claude_mpm/cli/parsers/analyze_parser.py +135 -0
- claude_mpm/cli/parsers/auto_configure_parser.py +120 -0
- claude_mpm/cli/parsers/base_parser.py +644 -0
- claude_mpm/cli/parsers/config_parser.py +208 -0
- claude_mpm/cli/parsers/configure_parser.py +138 -0
- claude_mpm/cli/parsers/dashboard_parser.py +113 -0
- claude_mpm/cli/parsers/debug_parser.py +319 -0
- claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
- claude_mpm/cli/parsers/mcp_parser.py +195 -0
- claude_mpm/cli/parsers/memory_parser.py +138 -0
- claude_mpm/cli/parsers/monitor_parser.py +142 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
- claude_mpm/cli/parsers/profile_parser.py +147 -0
- claude_mpm/cli/parsers/run_parser.py +157 -0
- claude_mpm/cli/parsers/search_parser.py +245 -0
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +277 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/parsers/tickets_parser.py +203 -0
- claude_mpm/cli/shared/__init__.py +40 -0
- claude_mpm/cli/shared/argument_patterns.py +205 -0
- claude_mpm/cli/shared/base_command.py +242 -0
- claude_mpm/cli/shared/error_handling.py +242 -0
- claude_mpm/cli/shared/output_formatters.py +241 -0
- claude_mpm/cli/startup.py +1743 -0
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/startup_logging.py +839 -0
- claude_mpm/cli/utils.py +136 -47
- 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 +42 -64
- claude_mpm/commands/__init__.py +14 -0
- claude_mpm/commands/mpm-config.md +28 -0
- claude_mpm/commands/mpm-doctor.md +20 -0
- claude_mpm/commands/mpm-help.md +20 -0
- claude_mpm/commands/mpm-init.md +120 -0
- claude_mpm/commands/mpm-monitor.md +31 -0
- claude_mpm/commands/mpm-organize.md +120 -0
- claude_mpm/commands/mpm-postmortem.md +21 -0
- claude_mpm/commands/mpm-session-resume.md +30 -0
- claude_mpm/commands/mpm-status.md +20 -0
- claude_mpm/commands/mpm-ticket-view.md +109 -0
- claude_mpm/commands/mpm-version.md +20 -0
- claude_mpm/commands/mpm.md +31 -0
- claude_mpm/config/__init__.py +42 -2
- claude_mpm/config/agent_config.py +402 -0
- claude_mpm/config/agent_presets.py +488 -0
- claude_mpm/config/agent_sources.py +352 -0
- claude_mpm/config/experimental_features.py +217 -0
- claude_mpm/config/model_config.py +428 -0
- claude_mpm/config/paths.py +258 -0
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/config/socketio_config.py +125 -83
- claude_mpm/constants.py +132 -22
- claude_mpm/core/__init__.py +62 -36
- claude_mpm/core/agent_name_normalizer.py +71 -73
- claude_mpm/core/agent_registry.py +385 -492
- claude_mpm/core/agent_session_manager.py +81 -70
- claude_mpm/core/api_validator.py +330 -0
- claude_mpm/core/base_service.py +159 -122
- claude_mpm/core/cache.py +560 -0
- claude_mpm/core/claude_runner.py +696 -916
- claude_mpm/core/config.py +613 -122
- claude_mpm/core/config_aliases.py +74 -73
- claude_mpm/core/config_constants.py +314 -0
- claude_mpm/core/constants.py +361 -0
- claude_mpm/core/container.py +646 -104
- claude_mpm/core/enums.py +452 -0
- claude_mpm/core/error_handler.py +623 -0
- claude_mpm/core/exceptions.py +536 -0
- claude_mpm/core/factories.py +105 -109
- claude_mpm/core/file_utils.py +764 -0
- claude_mpm/core/framework/__init__.py +25 -0
- claude_mpm/core/framework/formatters/__init__.py +11 -0
- claude_mpm/core/framework/formatters/capability_generator.py +367 -0
- claude_mpm/core/framework/formatters/content_formatter.py +278 -0
- claude_mpm/core/framework/formatters/context_generator.py +185 -0
- claude_mpm/core/framework/loaders/__init__.py +13 -0
- claude_mpm/core/framework/loaders/agent_loader.py +213 -0
- claude_mpm/core/framework/loaders/file_loader.py +176 -0
- claude_mpm/core/framework/loaders/instruction_loader.py +222 -0
- claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
- claude_mpm/core/framework/processors/__init__.py +11 -0
- claude_mpm/core/framework/processors/memory_processor.py +230 -0
- claude_mpm/core/framework/processors/metadata_processor.py +146 -0
- claude_mpm/core/framework/processors/template_processor.py +244 -0
- claude_mpm/core/framework_loader.py +485 -414
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +246 -86
- claude_mpm/core/hook_performance_config.py +147 -0
- claude_mpm/core/injectable_service.py +72 -63
- claude_mpm/core/instruction_reinforcement_hook.py +267 -0
- claude_mpm/core/interactive_session.py +670 -0
- claude_mpm/core/interfaces.py +570 -164
- claude_mpm/core/lazy.py +467 -0
- claude_mpm/core/log_manager.py +707 -0
- claude_mpm/core/logger.py +295 -134
- claude_mpm/core/logging_config.py +474 -0
- claude_mpm/core/logging_utils.py +520 -0
- claude_mpm/core/minimal_framework_loader.py +24 -22
- claude_mpm/core/mixins.py +30 -29
- claude_mpm/core/oneshot_session.py +594 -0
- claude_mpm/core/optimized_agent_loader.py +479 -0
- claude_mpm/core/optimized_startup.py +554 -0
- claude_mpm/core/output_style_manager.py +483 -0
- claude_mpm/core/pm_hook_interceptor.py +197 -82
- claude_mpm/core/protocols/__init__.py +23 -0
- claude_mpm/core/protocols/runner_protocol.py +103 -0
- claude_mpm/core/protocols/session_protocol.py +131 -0
- claude_mpm/core/service_registry.py +153 -116
- claude_mpm/core/session_manager.py +179 -64
- claude_mpm/core/shared/__init__.py +17 -0
- claude_mpm/core/shared/config_loader.py +326 -0
- claude_mpm/core/shared/path_resolver.py +281 -0
- claude_mpm/core/shared/singleton_manager.py +221 -0
- claude_mpm/core/socketio_pool.py +400 -137
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/tool_access_control.py +64 -57
- claude_mpm/core/types.py +307 -0
- claude_mpm/core/typing_utils.py +553 -0
- claude_mpm/core/unified_agent_registry.py +969 -0
- claude_mpm/core/unified_config.py +570 -0
- claude_mpm/core/unified_paths.py +941 -0
- claude_mpm/dashboard/__init__.py +12 -0
- claude_mpm/dashboard/api/simple_directory.py +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
- claude_mpm/experimental/__init__.py +10 -0
- claude_mpm/experimental/cli_enhancements.py +104 -89
- claude_mpm/generators/__init__.py +1 -1
- claude_mpm/generators/agent_profile_generator.py +76 -66
- claude_mpm/hooks/__init__.py +37 -1
- claude_mpm/hooks/base_hook.py +37 -32
- claude_mpm/hooks/claude_hooks/__init__.py +1 -1
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/connection_pool.py +250 -0
- claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +888 -0
- claude_mpm/hooks/claude_hooks/hook_handler.py +652 -875
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +10 -7
- claude_mpm/hooks/claude_hooks/installer.py +806 -0
- claude_mpm/hooks/claude_hooks/memory_integration.py +249 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +412 -0
- claude_mpm/hooks/claude_hooks/services/__init__.py +15 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +229 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +254 -0
- claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
- claude_mpm/hooks/claude_hooks/services/state_manager.py +284 -0
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
- claude_mpm/hooks/claude_hooks/tool_analysis.py +224 -0
- claude_mpm/hooks/failure_learning/__init__.py +54 -0
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
- claude_mpm/hooks/instruction_reinforcement.py +301 -0
- claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
- claude_mpm/hooks/kuzu_memory_hook.py +386 -0
- claude_mpm/hooks/kuzu_response_hook.py +179 -0
- claude_mpm/hooks/memory_integration_hook.py +201 -107
- claude_mpm/hooks/session_resume_hook.py +121 -0
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/hooks/tool_call_interceptor.py +92 -76
- claude_mpm/hooks/validation_hooks.py +62 -54
- claude_mpm/init.py +518 -83
- claude_mpm/models/__init__.py +9 -9
- claude_mpm/models/agent_definition.py +40 -23
- claude_mpm/models/agent_session.py +538 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/schemas/__init__.py +12 -0
- claude_mpm/scripts/__init__.py +15 -0
- claude_mpm/scripts/claude-hook-handler.sh +227 -0
- claude_mpm/scripts/launch_monitor.py +165 -0
- claude_mpm/scripts/mpm_doctor.py +322 -0
- claude_mpm/scripts/socketio_daemon.py +189 -200
- claude_mpm/scripts/start_activity_logging.py +91 -0
- claude_mpm/services/__init__.py +208 -39
- claude_mpm/services/agent_capabilities_service.py +266 -0
- claude_mpm/services/agents/__init__.py +89 -0
- claude_mpm/services/agents/agent_builder.py +514 -0
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_recommendation_service.py +278 -0
- claude_mpm/services/agents/agent_review_service.py +280 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -0
- claude_mpm/services/agents/auto_config_manager.py +796 -0
- claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
- claude_mpm/services/agents/cache_git_manager.py +621 -0
- claude_mpm/services/agents/deployment/__init__.py +21 -0
- claude_mpm/services/agents/deployment/agent_config_provider.py +410 -0
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +358 -0
- claude_mpm/services/agents/deployment/agent_definition_factory.py +80 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +1037 -0
- claude_mpm/services/agents/deployment/agent_discovery_service.py +546 -0
- claude_mpm/services/agents/deployment/agent_environment_manager.py +288 -0
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +383 -0
- claude_mpm/services/agents/deployment/agent_format_converter.py +505 -0
- claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +160 -0
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +957 -0
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +273 -0
- claude_mpm/services/agents/deployment/agent_operation_service.py +573 -0
- claude_mpm/services/agents/deployment/agent_record_service.py +418 -0
- claude_mpm/services/agents/deployment/agent_restore_handler.py +84 -0
- claude_mpm/services/agents/deployment/agent_state_service.py +381 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +1369 -0
- claude_mpm/services/agents/deployment/agent_validator.py +376 -0
- claude_mpm/services/agents/deployment/agent_version_manager.py +322 -0
- claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +10 -13
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +149 -0
- claude_mpm/services/agents/deployment/async_agent_deployment.py +768 -0
- claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
- claude_mpm/services/agents/deployment/config/__init__.py +13 -0
- claude_mpm/services/agents/deployment/config/deployment_config.py +181 -0
- claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
- claude_mpm/services/agents/deployment/deployment_config_loader.py +178 -0
- claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
- claude_mpm/services/agents/deployment/deployment_type_detector.py +120 -0
- claude_mpm/services/agents/deployment/deployment_wrapper.py +129 -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 +70 -0
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +269 -0
- claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
- claude_mpm/services/agents/deployment/interface_adapter.py +226 -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/local_template_deployment.py +362 -0
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +1478 -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 +162 -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 +240 -0
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +110 -0
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +80 -0
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +92 -0
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +101 -0
- claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +102 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
- claude_mpm/services/agents/deployment/processors/agent_processor.py +269 -0
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +311 -0
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +862 -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/single_agent_deployer.py +315 -0
- claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
- claude_mpm/services/agents/deployment/strategies/base_strategy.py +113 -0
- claude_mpm/services/agents/deployment/strategies/project_strategy.py +148 -0
- claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
- claude_mpm/services/agents/deployment/strategies/system_strategy.py +131 -0
- claude_mpm/services/agents/deployment/strategies/user_strategy.py +130 -0
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +228 -0
- claude_mpm/services/agents/deployment/validation/__init__.py +21 -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 +319 -0
- claude_mpm/services/agents/deployment/validation/validation_result.py +214 -0
- claude_mpm/services/agents/git_source_manager.py +682 -0
- claude_mpm/services/agents/loading/__init__.py +11 -0
- claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +306 -228
- claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +106 -91
- claude_mpm/services/agents/loading/framework_agent_loader.py +433 -0
- claude_mpm/services/agents/local_template_manager.py +784 -0
- claude_mpm/services/agents/management/__init__.py +9 -0
- claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +92 -69
- claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +219 -168
- claude_mpm/services/agents/memory/__init__.py +22 -0
- claude_mpm/services/agents/memory/agent_memory_manager.py +784 -0
- claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +20 -18
- claude_mpm/services/agents/memory/content_manager.py +470 -0
- claude_mpm/services/agents/memory/memory_categorization_service.py +167 -0
- claude_mpm/services/agents/memory/memory_file_service.py +129 -0
- claude_mpm/services/agents/memory/memory_format_service.py +201 -0
- claude_mpm/services/agents/memory/memory_limits_service.py +101 -0
- claude_mpm/services/agents/memory/template_generator.py +83 -0
- claude_mpm/services/agents/observers.py +547 -0
- claude_mpm/services/agents/recommender.py +617 -0
- claude_mpm/services/agents/registry/__init__.py +30 -0
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +273 -0
- claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +370 -295
- claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
- claude_mpm/services/agents/sources/__init__.py +13 -0
- claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +1202 -0
- claude_mpm/services/agents/startup_sync.py +259 -0
- claude_mpm/services/agents/toolchain_detector.py +478 -0
- claude_mpm/services/analysis/__init__.py +35 -0
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/async_session_logger.py +665 -0
- claude_mpm/services/claude_session_logger.py +321 -0
- claude_mpm/services/cli/__init__.py +18 -0
- claude_mpm/services/cli/agent_cleanup_service.py +408 -0
- claude_mpm/services/cli/agent_dependency_service.py +395 -0
- claude_mpm/services/cli/agent_listing_service.py +463 -0
- claude_mpm/services/cli/agent_output_formatter.py +605 -0
- claude_mpm/services/cli/agent_validation_service.py +590 -0
- claude_mpm/services/cli/memory_crud_service.py +622 -0
- claude_mpm/services/cli/memory_output_formatter.py +604 -0
- claude_mpm/services/cli/resume_service.py +617 -0
- claude_mpm/services/cli/session_manager.py +604 -0
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +372 -0
- claude_mpm/services/cli/startup_checker.py +362 -0
- claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
- claude_mpm/services/command_deployment_service.py +446 -0
- claude_mpm/services/command_handler_service.py +221 -0
- claude_mpm/services/communication/__init__.py +22 -0
- claude_mpm/services/core/__init__.py +108 -0
- claude_mpm/services/core/base.py +269 -0
- claude_mpm/services/core/cache_manager.py +309 -0
- claude_mpm/services/core/interfaces/__init__.py +273 -0
- claude_mpm/services/core/interfaces/agent.py +514 -0
- claude_mpm/services/core/interfaces/communication.py +316 -0
- claude_mpm/services/core/interfaces/health.py +169 -0
- claude_mpm/services/core/interfaces/infrastructure.py +357 -0
- claude_mpm/services/core/interfaces/model.py +281 -0
- claude_mpm/services/core/interfaces/process.py +372 -0
- claude_mpm/services/core/interfaces/project.py +121 -0
- claude_mpm/services/core/interfaces/restart.py +307 -0
- claude_mpm/services/core/interfaces/service.py +405 -0
- claude_mpm/services/core/interfaces/stability.py +260 -0
- claude_mpm/services/core/interfaces.py +81 -0
- claude_mpm/services/core/memory_manager.py +682 -0
- claude_mpm/services/core/models/__init__.py +70 -0
- claude_mpm/services/core/models/agent_config.py +384 -0
- claude_mpm/services/core/models/health.py +162 -0
- claude_mpm/services/core/models/process.py +239 -0
- claude_mpm/services/core/models/restart.py +302 -0
- claude_mpm/services/core/models/stability.py +264 -0
- claude_mpm/services/core/models/toolchain.py +306 -0
- claude_mpm/services/core/path_resolver.py +517 -0
- claude_mpm/services/core/service_container.py +520 -0
- claude_mpm/services/core/service_interfaces.py +436 -0
- claude_mpm/services/diagnostics/__init__.py +18 -0
- claude_mpm/services/diagnostics/checks/__init__.py +38 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +370 -0
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/base_check.py +60 -0
- claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
- claude_mpm/services/diagnostics/checks/common_issues_check.py +363 -0
- claude_mpm/services/diagnostics/checks/configuration_check.py +306 -0
- claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
- claude_mpm/services/diagnostics/checks/installation_check.py +520 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +415 -0
- claude_mpm/services/diagnostics/checks/mcp_check.py +330 -0
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
- claude_mpm/services/diagnostics/checks/monitor_check.py +281 -0
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/checks/startup_log_check.py +319 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +286 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +578 -0
- claude_mpm/services/diagnostics/models.py +138 -0
- claude_mpm/services/event_aggregator.py +582 -0
- claude_mpm/services/event_bus/__init__.py +18 -0
- claude_mpm/services/event_bus/config.py +186 -0
- claude_mpm/services/event_bus/direct_relay.py +312 -0
- claude_mpm/services/event_bus/event_bus.py +396 -0
- claude_mpm/services/event_bus/relay.py +326 -0
- claude_mpm/services/events/__init__.py +44 -0
- claude_mpm/services/events/consumers/__init__.py +18 -0
- claude_mpm/services/events/consumers/dead_letter.py +306 -0
- claude_mpm/services/events/consumers/logging.py +184 -0
- claude_mpm/services/events/consumers/metrics.py +241 -0
- claude_mpm/services/events/consumers/socketio.py +377 -0
- claude_mpm/services/events/core.py +480 -0
- claude_mpm/services/events/interfaces.py +214 -0
- claude_mpm/services/events/producers/__init__.py +14 -0
- claude_mpm/services/events/producers/hook.py +269 -0
- claude_mpm/services/events/producers/system.py +329 -0
- claude_mpm/services/exceptions.py +433 -353
- claude_mpm/services/framework_claude_md_generator/__init__.py +81 -80
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +74 -67
- claude_mpm/services/framework_claude_md_generator/content_validator.py +66 -62
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +82 -60
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +36 -37
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +41 -40
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +15 -15
- claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +5 -4
- 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 +5 -4
- 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 +26 -30
- claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
- claude_mpm/services/framework_claude_md_generator/version_manager.py +31 -30
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +579 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/hook_installer_service.py +506 -0
- claude_mpm/services/hook_service.py +159 -111
- claude_mpm/services/infrastructure/__init__.py +52 -0
- claude_mpm/services/infrastructure/context_preservation.py +569 -0
- claude_mpm/services/infrastructure/daemon_manager.py +279 -0
- claude_mpm/services/infrastructure/logging.py +209 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +39 -0
- claude_mpm/services/infrastructure/monitoring/aggregator.py +432 -0
- claude_mpm/services/infrastructure/monitoring/base.py +122 -0
- claude_mpm/services/infrastructure/monitoring/legacy.py +203 -0
- claude_mpm/services/infrastructure/monitoring/network.py +219 -0
- claude_mpm/services/infrastructure/monitoring/process.py +343 -0
- claude_mpm/services/infrastructure/monitoring/resources.py +244 -0
- claude_mpm/services/infrastructure/monitoring/service.py +368 -0
- claude_mpm/services/infrastructure/monitoring.py +71 -0
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/instructions/__init__.py +9 -0
- claude_mpm/services/instructions/instruction_cache_service.py +374 -0
- claude_mpm/services/local_ops/__init__.py +155 -0
- claude_mpm/services/local_ops/crash_detector.py +257 -0
- claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
- claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
- claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
- claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
- claude_mpm/services/local_ops/health_manager.py +427 -0
- claude_mpm/services/local_ops/log_monitor.py +396 -0
- claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
- claude_mpm/services/local_ops/process_manager.py +595 -0
- claude_mpm/services/local_ops/resource_monitor.py +331 -0
- claude_mpm/services/local_ops/restart_manager.py +401 -0
- claude_mpm/services/local_ops/restart_policy.py +387 -0
- claude_mpm/services/local_ops/state_manager.py +372 -0
- claude_mpm/services/local_ops/unified_manager.py +600 -0
- claude_mpm/services/mcp_config_manager.py +1542 -0
- claude_mpm/services/mcp_service_verifier.py +732 -0
- claude_mpm/services/memory/__init__.py +19 -0
- claude_mpm/services/{memory_builder.py → memory/builder.py} +465 -373
- claude_mpm/services/memory/cache/__init__.py +14 -0
- claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +237 -200
- claude_mpm/services/memory/cache/simple_cache.py +331 -0
- claude_mpm/services/memory/failure_tracker.py +578 -0
- claude_mpm/services/memory/indexed_memory.py +648 -0
- claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +272 -243
- claude_mpm/services/memory/router.py +951 -0
- claude_mpm/services/memory_hook_service.py +470 -0
- claude_mpm/services/model/__init__.py +147 -0
- claude_mpm/services/model/base_provider.py +365 -0
- claude_mpm/services/model/claude_provider.py +412 -0
- claude_mpm/services/model/model_router.py +452 -0
- claude_mpm/services/model/ollama_provider.py +415 -0
- claude_mpm/services/monitor/__init__.py +20 -0
- claude_mpm/services/monitor/daemon.py +698 -0
- claude_mpm/services/monitor/daemon_manager.py +1076 -0
- claude_mpm/services/monitor/event_emitter.py +350 -0
- claude_mpm/services/monitor/handlers/__init__.py +21 -0
- claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
- claude_mpm/services/monitor/handlers/dashboard.py +299 -0
- claude_mpm/services/monitor/handlers/file.py +264 -0
- claude_mpm/services/monitor/handlers/hooks.py +512 -0
- claude_mpm/services/monitor/management/__init__.py +18 -0
- claude_mpm/services/monitor/management/health.py +124 -0
- claude_mpm/services/monitor/management/lifecycle.py +730 -0
- claude_mpm/services/monitor/server.py +1493 -0
- claude_mpm/services/monitor_build_service.py +349 -0
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/orphan_detection.py +786 -0
- claude_mpm/services/pm_skills_deployer.py +707 -0
- claude_mpm/services/port_manager.py +597 -0
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/profile_manager.py +337 -0
- claude_mpm/services/project/__init__.py +44 -0
- claude_mpm/services/{project_analyzer.py → project/analyzer.py} +541 -291
- claude_mpm/services/project/analyzer_v2.py +566 -0
- claude_mpm/services/project/architecture_analyzer.py +461 -0
- claude_mpm/services/project/archive_manager.py +1045 -0
- claude_mpm/services/project/dependency_analyzer.py +462 -0
- claude_mpm/services/project/detection_strategies.py +719 -0
- claude_mpm/services/project/documentation_manager.py +554 -0
- claude_mpm/services/project/enhanced_analyzer.py +572 -0
- claude_mpm/services/project/language_analyzer.py +265 -0
- claude_mpm/services/project/metrics_collector.py +407 -0
- claude_mpm/services/project/project_organizer.py +1009 -0
- claude_mpm/services/project/registry.py +636 -0
- claude_mpm/services/project/toolchain_analyzer.py +583 -0
- claude_mpm/services/project_port_allocator.py +596 -0
- claude_mpm/services/recovery_manager.py +293 -240
- claude_mpm/services/response_tracker.py +267 -0
- claude_mpm/services/runner_configuration_service.py +605 -0
- claude_mpm/services/self_upgrade_service.py +608 -0
- claude_mpm/services/session_management_service.py +314 -0
- claude_mpm/services/session_manager.py +380 -0
- claude_mpm/services/shared/__init__.py +21 -0
- claude_mpm/services/shared/async_service_base.py +216 -0
- claude_mpm/services/shared/config_service_base.py +301 -0
- claude_mpm/services/shared/lifecycle_service_base.py +308 -0
- claude_mpm/services/shared/manager_base.py +315 -0
- claude_mpm/services/shared/service_factory.py +309 -0
- claude_mpm/services/skills/__init__.py +21 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1324 -0
- claude_mpm/services/skills/selective_skill_deployer.py +744 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +1168 -0
- claude_mpm/services/socketio/__init__.py +25 -0
- claude_mpm/services/socketio/client_proxy.py +229 -0
- claude_mpm/services/socketio/dashboard_server.py +362 -0
- claude_mpm/services/socketio/event_normalizer.py +798 -0
- claude_mpm/services/socketio/handlers/__init__.py +30 -0
- claude_mpm/services/socketio/handlers/base.py +136 -0
- claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
- claude_mpm/services/socketio/handlers/connection.py +643 -0
- claude_mpm/services/socketio/handlers/connection_handler.py +333 -0
- claude_mpm/services/socketio/handlers/file.py +263 -0
- claude_mpm/services/socketio/handlers/git.py +962 -0
- claude_mpm/services/socketio/handlers/hook.py +211 -0
- claude_mpm/services/socketio/handlers/memory.py +26 -0
- claude_mpm/services/socketio/handlers/project.py +24 -0
- claude_mpm/services/socketio/handlers/registry.py +214 -0
- claude_mpm/services/socketio/migration_utils.py +343 -0
- claude_mpm/services/socketio/monitor_client.py +364 -0
- claude_mpm/services/socketio/server/__init__.py +18 -0
- claude_mpm/services/socketio/server/broadcaster.py +569 -0
- claude_mpm/services/socketio/server/connection_manager.py +579 -0
- claude_mpm/services/socketio/server/core.py +1079 -0
- claude_mpm/services/socketio/server/eventbus_integration.py +245 -0
- claude_mpm/services/socketio/server/main.py +501 -0
- claude_mpm/services/socketio_client_manager.py +173 -143
- claude_mpm/services/socketio_server.py +38 -1657
- claude_mpm/services/subprocess_launcher_service.py +322 -0
- claude_mpm/services/system_instructions_service.py +270 -0
- claude_mpm/services/ticket_manager.py +25 -209
- claude_mpm/services/ticket_services/__init__.py +26 -0
- claude_mpm/services/ticket_services/crud_service.py +328 -0
- claude_mpm/services/ticket_services/formatter_service.py +290 -0
- claude_mpm/services/ticket_services/search_service.py +324 -0
- claude_mpm/services/ticket_services/validation_service.py +303 -0
- claude_mpm/services/ticket_services/workflow_service.py +244 -0
- claude_mpm/services/unified/__init__.py +65 -0
- claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
- claude_mpm/services/unified/config_strategies/__init__.py +175 -0
- claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
- claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
- claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
- claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
- claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
- claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
- claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
- claude_mpm/services/unified/deployment_strategies/base.py +553 -0
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
- claude_mpm/services/unified/deployment_strategies/local.py +607 -0
- claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
- claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
- claude_mpm/services/unified/interfaces.py +475 -0
- claude_mpm/services/unified/migration.py +509 -0
- claude_mpm/services/unified/strategies.py +534 -0
- claude_mpm/services/unified/unified_analyzer.py +542 -0
- claude_mpm/services/unified/unified_config.py +691 -0
- claude_mpm/services/unified/unified_deployment.py +466 -0
- claude_mpm/services/utility_service.py +280 -0
- claude_mpm/services/version_control/__init__.py +34 -37
- claude_mpm/services/version_control/branch_strategy.py +26 -17
- claude_mpm/services/version_control/conflict_resolution.py +52 -36
- claude_mpm/services/version_control/git_operations.py +183 -49
- claude_mpm/services/version_control/semantic_versioning.py +172 -61
- claude_mpm/services/version_control/version_parser.py +546 -0
- claude_mpm/services/version_service.py +379 -0
- claude_mpm/services/visualization/__init__.py +15 -0
- claude_mpm/services/visualization/mermaid_generator.py +937 -0
- claude_mpm/skills/__init__.py +42 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
- claude_mpm/skills/bundled/__init__.py +6 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +573 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/security-scanning.md +439 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +286 -0
- claude_mpm/skills/skill_manager.py +405 -0
- claude_mpm/skills/skills_registry.py +347 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/storage/__init__.py +9 -0
- claude_mpm/storage/state_storage.py +546 -0
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/templates/questions/__init__.py +38 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +311 -0
- claude_mpm/templates/questions/project_init.py +385 -0
- claude_mpm/templates/questions/ticket_mgmt.py +394 -0
- claude_mpm/ticket_wrapper.py +2 -2
- claude_mpm/tools/__init__.py +10 -0
- claude_mpm/tools/__main__.py +208 -0
- claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
- claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
- claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
- claude_mpm/tools/code_tree_analyzer/core.py +380 -0
- claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
- claude_mpm/tools/code_tree_analyzer/events.py +168 -0
- claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
- claude_mpm/tools/code_tree_analyzer/models.py +39 -0
- claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
- claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
- claude_mpm/tools/code_tree_builder.py +631 -0
- claude_mpm/tools/code_tree_events.py +420 -0
- claude_mpm/tools/socketio_debug.py +671 -0
- claude_mpm/utils/__init__.py +8 -8
- claude_mpm/utils/agent_dependency_loader.py +1090 -0
- claude_mpm/utils/agent_filters.py +261 -0
- claude_mpm/utils/common.py +544 -0
- claude_mpm/utils/config_manager.py +168 -126
- claude_mpm/utils/console.py +11 -0
- claude_mpm/utils/database_connector.py +298 -0
- claude_mpm/utils/dependency_cache.py +373 -0
- claude_mpm/utils/dependency_manager.py +60 -59
- claude_mpm/utils/dependency_strategies.py +381 -0
- claude_mpm/utils/display_helper.py +260 -0
- claude_mpm/utils/environment_context.py +313 -0
- claude_mpm/utils/error_handler.py +78 -66
- claude_mpm/utils/file_utils.py +305 -0
- claude_mpm/utils/framework_detection.py +12 -11
- claude_mpm/utils/git_analyzer.py +407 -0
- claude_mpm/utils/gitignore.py +244 -0
- claude_mpm/utils/import_migration_example.py +12 -60
- claude_mpm/utils/imports.py +48 -45
- claude_mpm/utils/log_cleanup.py +627 -0
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/path_operations.py +110 -104
- claude_mpm/utils/progress.py +387 -0
- claude_mpm/utils/robust_installer.py +823 -0
- claude_mpm/utils/session_logging.py +121 -0
- claude_mpm/utils/structured_questions.py +619 -0
- claude_mpm/utils/subprocess_utils.py +343 -0
- claude_mpm/validation/__init__.py +1 -1
- claude_mpm/validation/agent_validator.py +214 -108
- claude_mpm/validation/frontmatter_validator.py +252 -0
- claude_mpm-5.4.55.dist-info/METADATA +999 -0
- claude_mpm-5.4.55.dist-info/RECORD +868 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/entry_points.txt +1 -3
- claude_mpm-5.4.55.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.55.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -88
- claude_mpm/agents/INSTRUCTIONS.md +0 -352
- claude_mpm/agents/backups/INSTRUCTIONS.md +0 -352
- claude_mpm/agents/base_agent_loader.py +0 -529
- claude_mpm/agents/schema/agent_schema.json +0 -314
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -36
- claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/documentation_agent_20250726_234551.json +0 -45
- claude_mpm/agents/templates/backup/engineer_agent_20250726_234551.json +0 -49
- claude_mpm/agents/templates/backup/ops_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/qa_agent_20250726_234551.json +0 -45
- claude_mpm/agents/templates/backup/research_agent_20250726_234551.json +0 -49
- claude_mpm/agents/templates/backup/security_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/version_control_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/data_engineer.json +0 -110
- claude_mpm/agents/templates/documentation.json +0 -109
- claude_mpm/agents/templates/engineer.json +0 -113
- claude_mpm/agents/templates/ops.json +0 -109
- claude_mpm/agents/templates/pm.json +0 -25
- claude_mpm/agents/templates/qa.json +0 -111
- claude_mpm/agents/templates/research.json +0 -65
- claude_mpm/agents/templates/security.json +0 -113
- claude_mpm/agents/templates/test_integration.json +0 -112
- claude_mpm/agents/templates/version_control.json +0 -107
- claude_mpm/cli/commands/ui.py +0 -57
- claude_mpm/core/simple_runner.py +0 -1046
- claude_mpm/dashboard/open_dashboard.py +0 -34
- claude_mpm/deployment_paths.py +0 -261
- claude_mpm/hooks/builtin/__init__.py +0 -1
- claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
- claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
- claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
- claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
- claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
- claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
- claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
- claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
- claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
- claude_mpm/orchestration/__init__.py +0 -6
- claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
- claude_mpm/orchestration/archive/factory.py +0 -215
- claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
- claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
- claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
- claude_mpm/orchestration/archive/orchestrator.py +0 -501
- claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
- claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
- claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
- claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
- claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
- claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
- claude_mpm/schemas/workflow_validator.py +0 -411
- claude_mpm/services/agent_deployment.py +0 -1534
- claude_mpm/services/agent_lifecycle_manager.py +0 -1169
- claude_mpm/services/agent_memory_manager.py +0 -1415
- claude_mpm/services/agent_registry.py +0 -676
- claude_mpm/services/deployed_agent_discovery.py +0 -226
- claude_mpm/services/framework_agent_loader.py +0 -337
- claude_mpm/services/framework_claude_md_generator.py +0 -621
- claude_mpm/services/health_monitor.py +0 -892
- claude_mpm/services/memory_router.py +0 -538
- claude_mpm/services/parent_directory_manager/__init__.py +0 -577
- claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
- claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
- claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
- claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
- claude_mpm/services/parent_directory_manager/operations.py +0 -186
- claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
- claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
- claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
- claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
- claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
- 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 -508
- claude_mpm/ui/__init__.py +0 -1
- claude_mpm/ui/rich_terminal_ui.py +0 -295
- claude_mpm/ui/terminal_ui.py +0 -328
- claude_mpm/utils/paths.py +0 -289
- claude_mpm-3.4.10.dist-info/METADATA +0 -183
- claude_mpm-3.4.10.dist-info/RECORD +0 -201
- claude_mpm-3.4.10.dist-info/licenses/LICENSE +0 -21
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/WHEEL +0 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,941 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Unified Path Management System for Claude MPM
|
|
4
|
+
==============================================
|
|
5
|
+
|
|
6
|
+
This module consolidates all path management functionality from the duplicate modules:
|
|
7
|
+
- config/paths.py (ClaudeMPMPaths)
|
|
8
|
+
- utils/paths.py (get_path_manager())
|
|
9
|
+
- deployment_paths.py (get_path_manager())
|
|
10
|
+
- core/config_paths.py (get_path_manager())
|
|
11
|
+
|
|
12
|
+
Design Principles:
|
|
13
|
+
- Single source of truth for all path operations
|
|
14
|
+
- Consistent API across all path types
|
|
15
|
+
- Robust deployment scenario handling
|
|
16
|
+
- Efficient caching with cache invalidation
|
|
17
|
+
- Clear separation of concerns
|
|
18
|
+
- Backward compatibility during migration
|
|
19
|
+
|
|
20
|
+
Architecture:
|
|
21
|
+
- UnifiedPathManager: Main singleton class
|
|
22
|
+
- PathType enum: Categorizes different path types
|
|
23
|
+
- PathContext: Handles deployment context detection
|
|
24
|
+
- Cached properties with smart invalidation
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
import os
|
|
28
|
+
import sys
|
|
29
|
+
from enum import Enum
|
|
30
|
+
from functools import lru_cache
|
|
31
|
+
from pathlib import Path
|
|
32
|
+
from typing import Optional, Union
|
|
33
|
+
|
|
34
|
+
from claude_mpm.core.logging_utils import get_logger
|
|
35
|
+
|
|
36
|
+
logger = get_logger(__name__)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class PathType(Enum):
|
|
40
|
+
"""Enumeration of different path types for categorization."""
|
|
41
|
+
|
|
42
|
+
PROJECT = "project"
|
|
43
|
+
FRAMEWORK = "framework"
|
|
44
|
+
USER = "user"
|
|
45
|
+
SYSTEM = "system"
|
|
46
|
+
CONFIG = "config"
|
|
47
|
+
AGENTS = "agents"
|
|
48
|
+
TEMPLATES = "templates"
|
|
49
|
+
SCRIPTS = "scripts"
|
|
50
|
+
STATIC = "static"
|
|
51
|
+
LOGS = "logs"
|
|
52
|
+
CACHE = "cache"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class DeploymentContext(Enum):
|
|
56
|
+
"""Enumeration of deployment contexts."""
|
|
57
|
+
|
|
58
|
+
DEVELOPMENT = "development"
|
|
59
|
+
EDITABLE_INSTALL = "editable_install"
|
|
60
|
+
PIP_INSTALL = "pip_install"
|
|
61
|
+
PIPX_INSTALL = "pipx_install"
|
|
62
|
+
SYSTEM_PACKAGE = "system_package"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class PathContext:
|
|
66
|
+
"""Handles deployment context detection and path resolution."""
|
|
67
|
+
|
|
68
|
+
@staticmethod
|
|
69
|
+
def _is_editable_install() -> bool:
|
|
70
|
+
"""Check if the current installation is editable (development mode).
|
|
71
|
+
|
|
72
|
+
This checks for various indicators of an editable/development installation:
|
|
73
|
+
- Presence of pyproject.toml in parent directories
|
|
74
|
+
- .pth files pointing to the source directory
|
|
75
|
+
- Direct source installation (src/ directory structure)
|
|
76
|
+
- Current working directory is within a development project
|
|
77
|
+
"""
|
|
78
|
+
try:
|
|
79
|
+
import claude_mpm
|
|
80
|
+
|
|
81
|
+
module_path = Path(claude_mpm.__file__).parent
|
|
82
|
+
|
|
83
|
+
# Check if we're in a src/ directory structure with pyproject.toml
|
|
84
|
+
current = module_path
|
|
85
|
+
for _ in range(5): # Check up to 5 levels up
|
|
86
|
+
if (current / "pyproject.toml").exists() and (
|
|
87
|
+
current / "src" / "claude_mpm"
|
|
88
|
+
).exists():
|
|
89
|
+
# Found pyproject.toml with development setup
|
|
90
|
+
logger.debug(f"Found development installation at {current}")
|
|
91
|
+
return True
|
|
92
|
+
if current == current.parent:
|
|
93
|
+
break
|
|
94
|
+
current = current.parent
|
|
95
|
+
|
|
96
|
+
# Additional check: If we're running from within a claude-mpm development directory
|
|
97
|
+
# This handles the case where pipx claude-mpm is invoked from within the dev directory
|
|
98
|
+
cwd = Path.cwd()
|
|
99
|
+
current = cwd
|
|
100
|
+
for _ in range(5): # Check up to 5 levels up from current directory
|
|
101
|
+
if (current / "pyproject.toml").exists() and (
|
|
102
|
+
current / "src" / "claude_mpm"
|
|
103
|
+
).exists():
|
|
104
|
+
# Check if this is the claude-mpm project
|
|
105
|
+
try:
|
|
106
|
+
pyproject_content = (current / "pyproject.toml").read_text()
|
|
107
|
+
if (
|
|
108
|
+
"claude-mpm" in pyproject_content
|
|
109
|
+
and "claude_mpm" in pyproject_content
|
|
110
|
+
):
|
|
111
|
+
logger.debug(
|
|
112
|
+
f"Running from within claude-mpm development directory: {current}"
|
|
113
|
+
)
|
|
114
|
+
# Verify this is a development setup by checking for key files
|
|
115
|
+
if (current / "scripts" / "claude-mpm").exists():
|
|
116
|
+
return True
|
|
117
|
+
except Exception:
|
|
118
|
+
pass
|
|
119
|
+
if current == current.parent:
|
|
120
|
+
break
|
|
121
|
+
current = current.parent
|
|
122
|
+
|
|
123
|
+
# Check for .pth files indicating editable install
|
|
124
|
+
try:
|
|
125
|
+
import site
|
|
126
|
+
|
|
127
|
+
for site_dir in site.getsitepackages():
|
|
128
|
+
site_path = Path(site_dir)
|
|
129
|
+
if site_path.exists():
|
|
130
|
+
# Check for .pth files
|
|
131
|
+
for pth_file in site_path.glob("*.pth"):
|
|
132
|
+
try:
|
|
133
|
+
content = pth_file.read_text()
|
|
134
|
+
# Check if the .pth file points to our module's parent
|
|
135
|
+
if (
|
|
136
|
+
str(module_path.parent) in content
|
|
137
|
+
or str(module_path) in content
|
|
138
|
+
):
|
|
139
|
+
logger.debug(
|
|
140
|
+
f"Found editable install via .pth file: {pth_file}"
|
|
141
|
+
)
|
|
142
|
+
return True
|
|
143
|
+
except Exception:
|
|
144
|
+
continue
|
|
145
|
+
|
|
146
|
+
# Check for egg-link files
|
|
147
|
+
for egg_link in site_path.glob("*egg-link"):
|
|
148
|
+
if "claude" in egg_link.name.lower():
|
|
149
|
+
try:
|
|
150
|
+
content = egg_link.read_text()
|
|
151
|
+
if (
|
|
152
|
+
str(module_path.parent) in content
|
|
153
|
+
or str(module_path) in content
|
|
154
|
+
):
|
|
155
|
+
logger.debug(
|
|
156
|
+
f"Found editable install via egg-link: {egg_link}"
|
|
157
|
+
)
|
|
158
|
+
return True
|
|
159
|
+
except Exception:
|
|
160
|
+
continue
|
|
161
|
+
except ImportError:
|
|
162
|
+
pass
|
|
163
|
+
|
|
164
|
+
except Exception as e:
|
|
165
|
+
logger.debug(f"Error checking for editable install: {e}")
|
|
166
|
+
|
|
167
|
+
return False
|
|
168
|
+
|
|
169
|
+
@staticmethod
|
|
170
|
+
@lru_cache(maxsize=1)
|
|
171
|
+
def detect_deployment_context() -> DeploymentContext:
|
|
172
|
+
"""Detect the current deployment context.
|
|
173
|
+
|
|
174
|
+
Priority order:
|
|
175
|
+
1. Environment variable override (CLAUDE_MPM_DEV_MODE)
|
|
176
|
+
2. Current working directory is a claude-mpm development project
|
|
177
|
+
3. Editable installation detection
|
|
178
|
+
4. Path-based detection (development, pipx, system, pip)
|
|
179
|
+
"""
|
|
180
|
+
# Check for environment variable override
|
|
181
|
+
if os.environ.get("CLAUDE_MPM_DEV_MODE", "").lower() in ("1", "true", "yes"):
|
|
182
|
+
logger.debug(
|
|
183
|
+
"Development mode forced via CLAUDE_MPM_DEV_MODE environment variable"
|
|
184
|
+
)
|
|
185
|
+
return DeploymentContext.DEVELOPMENT
|
|
186
|
+
|
|
187
|
+
# Check if current working directory is a claude-mpm development project
|
|
188
|
+
# This handles the case where pipx claude-mpm is run from within the dev directory
|
|
189
|
+
cwd = Path.cwd()
|
|
190
|
+
current = cwd
|
|
191
|
+
for _ in range(5): # Check up to 5 levels up from current directory
|
|
192
|
+
if (current / "pyproject.toml").exists() and (
|
|
193
|
+
current / "src" / "claude_mpm"
|
|
194
|
+
).exists():
|
|
195
|
+
# Check if this is the claude-mpm project
|
|
196
|
+
try:
|
|
197
|
+
pyproject_content = (current / "pyproject.toml").read_text()
|
|
198
|
+
if (
|
|
199
|
+
'name = "claude-mpm"' in pyproject_content
|
|
200
|
+
or '"claude-mpm"' in pyproject_content
|
|
201
|
+
):
|
|
202
|
+
logger.debug(
|
|
203
|
+
f"Detected claude-mpm development directory at {current}"
|
|
204
|
+
)
|
|
205
|
+
logger.debug(
|
|
206
|
+
"Using development mode for local source preference"
|
|
207
|
+
)
|
|
208
|
+
return DeploymentContext.DEVELOPMENT
|
|
209
|
+
except Exception:
|
|
210
|
+
pass
|
|
211
|
+
if current == current.parent:
|
|
212
|
+
break
|
|
213
|
+
current = current.parent
|
|
214
|
+
|
|
215
|
+
try:
|
|
216
|
+
import claude_mpm
|
|
217
|
+
|
|
218
|
+
module_path = Path(claude_mpm.__file__).parent
|
|
219
|
+
|
|
220
|
+
# First check if this is an editable install, regardless of path
|
|
221
|
+
# This is important for cases where pipx points to a development installation
|
|
222
|
+
if PathContext._is_editable_install():
|
|
223
|
+
logger.debug("Detected editable/development installation")
|
|
224
|
+
# Check if we should use development paths
|
|
225
|
+
# This could be because we're in a src/ directory or running from dev directory
|
|
226
|
+
if module_path.parent.name == "src":
|
|
227
|
+
return DeploymentContext.DEVELOPMENT
|
|
228
|
+
if "pipx" in str(module_path):
|
|
229
|
+
# Running via pipx but from within a development directory
|
|
230
|
+
# Use development mode to prefer local source over pipx installation
|
|
231
|
+
cwd = Path.cwd()
|
|
232
|
+
current = cwd
|
|
233
|
+
for _ in range(5):
|
|
234
|
+
if (current / "src" / "claude_mpm").exists() and (
|
|
235
|
+
current / "pyproject.toml"
|
|
236
|
+
).exists():
|
|
237
|
+
logger.debug(
|
|
238
|
+
"Running pipx from development directory, using development mode"
|
|
239
|
+
)
|
|
240
|
+
return DeploymentContext.DEVELOPMENT
|
|
241
|
+
if current == current.parent:
|
|
242
|
+
break
|
|
243
|
+
current = current.parent
|
|
244
|
+
return DeploymentContext.EDITABLE_INSTALL
|
|
245
|
+
return DeploymentContext.EDITABLE_INSTALL
|
|
246
|
+
|
|
247
|
+
# Check for development mode based on directory structure
|
|
248
|
+
# module_path is typically /path/to/project/src/claude_mpm
|
|
249
|
+
if (
|
|
250
|
+
module_path.parent.name == "src"
|
|
251
|
+
and (module_path.parent.parent / "src" / "claude_mpm").exists()
|
|
252
|
+
):
|
|
253
|
+
logger.debug(
|
|
254
|
+
f"Detected development mode via directory structure at {module_path}"
|
|
255
|
+
)
|
|
256
|
+
return DeploymentContext.DEVELOPMENT
|
|
257
|
+
|
|
258
|
+
# Check for pipx install
|
|
259
|
+
if "pipx" in str(module_path):
|
|
260
|
+
logger.debug(f"Detected pipx installation at {module_path}")
|
|
261
|
+
return DeploymentContext.PIPX_INSTALL
|
|
262
|
+
|
|
263
|
+
# Check for system package
|
|
264
|
+
if "dist-packages" in str(module_path):
|
|
265
|
+
logger.debug(f"Detected system package installation at {module_path}")
|
|
266
|
+
return DeploymentContext.SYSTEM_PACKAGE
|
|
267
|
+
|
|
268
|
+
# Check for site-packages (could be pip or editable)
|
|
269
|
+
if "site-packages" in str(module_path):
|
|
270
|
+
# Already checked for editable above, so this is a regular pip install
|
|
271
|
+
logger.debug(f"Detected pip installation at {module_path}")
|
|
272
|
+
return DeploymentContext.PIP_INSTALL
|
|
273
|
+
|
|
274
|
+
# Default to pip install
|
|
275
|
+
logger.debug(f"Defaulting to pip installation for {module_path}")
|
|
276
|
+
return DeploymentContext.PIP_INSTALL
|
|
277
|
+
|
|
278
|
+
except ImportError:
|
|
279
|
+
logger.debug(
|
|
280
|
+
"ImportError during context detection, defaulting to development"
|
|
281
|
+
)
|
|
282
|
+
return DeploymentContext.DEVELOPMENT
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
class UnifiedPathManager:
|
|
286
|
+
"""
|
|
287
|
+
Unified path management system that consolidates all path-related functionality.
|
|
288
|
+
|
|
289
|
+
This class provides a single, authoritative interface for all path operations
|
|
290
|
+
in Claude MPM, replacing the multiple duplicate path management modules.
|
|
291
|
+
"""
|
|
292
|
+
|
|
293
|
+
_instance: Optional["UnifiedPathManager"] = None
|
|
294
|
+
_cache_invalidated: bool = False
|
|
295
|
+
|
|
296
|
+
# Configuration constants
|
|
297
|
+
CONFIG_DIR_NAME = ".claude-mpm"
|
|
298
|
+
LEGACY_CONFIG_DIR_NAME = ".claude-pm" # For migration support
|
|
299
|
+
|
|
300
|
+
def __new__(cls) -> "UnifiedPathManager":
|
|
301
|
+
"""Singleton pattern to ensure single instance."""
|
|
302
|
+
if cls._instance is None:
|
|
303
|
+
cls._instance = super().__new__(cls)
|
|
304
|
+
cls._instance._initialized = False
|
|
305
|
+
return cls._instance
|
|
306
|
+
|
|
307
|
+
def __init__(self):
|
|
308
|
+
"""Initialize the path manager."""
|
|
309
|
+
if self._initialized:
|
|
310
|
+
return
|
|
311
|
+
|
|
312
|
+
self._deployment_context = PathContext.detect_deployment_context()
|
|
313
|
+
self._project_markers = [
|
|
314
|
+
".git",
|
|
315
|
+
"pyproject.toml",
|
|
316
|
+
"package.json",
|
|
317
|
+
"Cargo.toml",
|
|
318
|
+
"go.mod",
|
|
319
|
+
"pom.xml",
|
|
320
|
+
"build.gradle",
|
|
321
|
+
self.CONFIG_DIR_NAME,
|
|
322
|
+
]
|
|
323
|
+
self._initialized = True
|
|
324
|
+
|
|
325
|
+
# Use debug level for initialization details
|
|
326
|
+
logger.debug(
|
|
327
|
+
f"UnifiedPathManager initialized with context: {self._deployment_context.value}"
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
# ========================================================================
|
|
331
|
+
# Core Path Resolution Methods
|
|
332
|
+
# ========================================================================
|
|
333
|
+
|
|
334
|
+
@property
|
|
335
|
+
@lru_cache(maxsize=1)
|
|
336
|
+
def framework_root(self) -> Path:
|
|
337
|
+
"""Get the framework root directory."""
|
|
338
|
+
try:
|
|
339
|
+
import claude_mpm
|
|
340
|
+
|
|
341
|
+
module_path = Path(claude_mpm.__file__).parent
|
|
342
|
+
|
|
343
|
+
if self._deployment_context in (
|
|
344
|
+
DeploymentContext.DEVELOPMENT,
|
|
345
|
+
DeploymentContext.EDITABLE_INSTALL,
|
|
346
|
+
):
|
|
347
|
+
# For development mode, first check if we're running from within a dev directory
|
|
348
|
+
# This handles the case where pipx is invoked from a development directory
|
|
349
|
+
cwd = Path.cwd()
|
|
350
|
+
current = cwd
|
|
351
|
+
for _ in range(5):
|
|
352
|
+
if (current / "src" / "claude_mpm").exists() and (
|
|
353
|
+
current / "pyproject.toml"
|
|
354
|
+
).exists():
|
|
355
|
+
# Verify this is the claude-mpm project
|
|
356
|
+
try:
|
|
357
|
+
pyproject_content = (current / "pyproject.toml").read_text()
|
|
358
|
+
if "claude-mpm" in pyproject_content:
|
|
359
|
+
logger.debug(
|
|
360
|
+
f"Found framework root via cwd at {current}"
|
|
361
|
+
)
|
|
362
|
+
return current
|
|
363
|
+
except Exception:
|
|
364
|
+
pass
|
|
365
|
+
if current == current.parent:
|
|
366
|
+
break
|
|
367
|
+
current = current.parent
|
|
368
|
+
|
|
369
|
+
# Development or editable install: go up to project root from module
|
|
370
|
+
current = module_path
|
|
371
|
+
while current != current.parent:
|
|
372
|
+
if (current / "src" / "claude_mpm").exists() and (
|
|
373
|
+
current / "pyproject.toml"
|
|
374
|
+
).exists():
|
|
375
|
+
logger.debug(f"Found framework root at {current}")
|
|
376
|
+
return current
|
|
377
|
+
current = current.parent
|
|
378
|
+
|
|
379
|
+
# Secondary check: Look for pyproject.toml without src structure
|
|
380
|
+
current = module_path
|
|
381
|
+
while current != current.parent:
|
|
382
|
+
if (current / "pyproject.toml").exists():
|
|
383
|
+
logger.debug(f"Found framework root (no src) at {current}")
|
|
384
|
+
return current
|
|
385
|
+
current = current.parent
|
|
386
|
+
|
|
387
|
+
# For installed packages, the module path is the framework root
|
|
388
|
+
return (
|
|
389
|
+
module_path.parent if module_path.name == "claude_mpm" else module_path
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
except ImportError:
|
|
393
|
+
# Fallback: search from current file location
|
|
394
|
+
current = Path(__file__).parent
|
|
395
|
+
while current != current.parent:
|
|
396
|
+
if (current / "src" / "claude_mpm").exists():
|
|
397
|
+
return current
|
|
398
|
+
current = current.parent
|
|
399
|
+
|
|
400
|
+
raise FileNotFoundError("Could not determine framework root") from None
|
|
401
|
+
|
|
402
|
+
@property
|
|
403
|
+
@lru_cache(maxsize=1)
|
|
404
|
+
def project_root(self) -> Path:
|
|
405
|
+
"""Get the current project root directory."""
|
|
406
|
+
current = Path.cwd()
|
|
407
|
+
while current != current.parent:
|
|
408
|
+
for marker in self._project_markers:
|
|
409
|
+
if (current / marker).exists():
|
|
410
|
+
logger.debug(f"Found project root at {current} via {marker}")
|
|
411
|
+
return current
|
|
412
|
+
current = current.parent
|
|
413
|
+
|
|
414
|
+
# Fallback to current directory
|
|
415
|
+
logger.warning("Could not find project root, using current directory")
|
|
416
|
+
return Path.cwd()
|
|
417
|
+
|
|
418
|
+
@property
|
|
419
|
+
def package_root(self) -> Path:
|
|
420
|
+
"""Get the claude_mpm package root directory."""
|
|
421
|
+
if self._deployment_context in (
|
|
422
|
+
DeploymentContext.DEVELOPMENT,
|
|
423
|
+
DeploymentContext.EDITABLE_INSTALL,
|
|
424
|
+
):
|
|
425
|
+
# In development mode, always use the source directory
|
|
426
|
+
package_path = self.framework_root / "src" / "claude_mpm"
|
|
427
|
+
if package_path.exists():
|
|
428
|
+
return package_path
|
|
429
|
+
|
|
430
|
+
try:
|
|
431
|
+
import claude_mpm
|
|
432
|
+
|
|
433
|
+
return Path(claude_mpm.__file__).parent
|
|
434
|
+
except ImportError:
|
|
435
|
+
return self.framework_root / "src" / "claude_mpm"
|
|
436
|
+
|
|
437
|
+
# ========================================================================
|
|
438
|
+
# Configuration Paths
|
|
439
|
+
# ========================================================================
|
|
440
|
+
|
|
441
|
+
def get_config_dir(self, scope: str = "project") -> Path:
|
|
442
|
+
"""Get configuration directory for specified scope."""
|
|
443
|
+
if scope == "user":
|
|
444
|
+
return Path.home() / self.CONFIG_DIR_NAME
|
|
445
|
+
if scope == "project":
|
|
446
|
+
return self.project_root / self.CONFIG_DIR_NAME
|
|
447
|
+
if scope == "framework":
|
|
448
|
+
return self.framework_root / self.CONFIG_DIR_NAME
|
|
449
|
+
raise ValueError(
|
|
450
|
+
f"Invalid scope: {scope}. Must be 'user', 'project', or 'framework'"
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
def get_user_config_dir(self) -> Path:
|
|
454
|
+
"""Get the user-level configuration directory."""
|
|
455
|
+
return Path.home() / self.CONFIG_DIR_NAME
|
|
456
|
+
|
|
457
|
+
def get_project_config_dir(self, project_root: Optional[Path] = None) -> Path:
|
|
458
|
+
"""Get the project-level configuration directory."""
|
|
459
|
+
root = project_root or self.project_root
|
|
460
|
+
return root / self.CONFIG_DIR_NAME
|
|
461
|
+
|
|
462
|
+
# ========================================================================
|
|
463
|
+
# Agent Paths
|
|
464
|
+
# ========================================================================
|
|
465
|
+
|
|
466
|
+
def get_agents_dir(self, scope: str = "framework") -> Path:
|
|
467
|
+
"""Get agents directory for specified scope."""
|
|
468
|
+
if scope == "user":
|
|
469
|
+
return self.get_user_config_dir() / "agents"
|
|
470
|
+
if scope == "project":
|
|
471
|
+
return self.get_project_config_dir() / "agents"
|
|
472
|
+
if scope == "framework":
|
|
473
|
+
if self._deployment_context in (
|
|
474
|
+
DeploymentContext.DEVELOPMENT,
|
|
475
|
+
DeploymentContext.EDITABLE_INSTALL,
|
|
476
|
+
):
|
|
477
|
+
return self.framework_root / "src" / "claude_mpm" / "agents"
|
|
478
|
+
return self.package_root / "agents"
|
|
479
|
+
raise ValueError(
|
|
480
|
+
f"Invalid scope: {scope}. Must be 'user', 'project', or 'framework'"
|
|
481
|
+
)
|
|
482
|
+
|
|
483
|
+
def get_user_agents_dir(self) -> Path:
|
|
484
|
+
"""Get the user-level agents directory."""
|
|
485
|
+
return self.get_user_config_dir() / "agents"
|
|
486
|
+
|
|
487
|
+
def get_project_agents_dir(self, project_root: Optional[Path] = None) -> Path:
|
|
488
|
+
"""Get the project-level agents directory."""
|
|
489
|
+
return self.get_project_config_dir(project_root) / "agents"
|
|
490
|
+
|
|
491
|
+
def get_system_agents_dir(self) -> Path:
|
|
492
|
+
"""Get the system-level agents directory."""
|
|
493
|
+
return self.get_agents_dir("framework")
|
|
494
|
+
|
|
495
|
+
def get_templates_dir(self) -> Path:
|
|
496
|
+
"""Get the agent templates directory."""
|
|
497
|
+
return self.get_agents_dir("framework") / "templates"
|
|
498
|
+
|
|
499
|
+
# ========================================================================
|
|
500
|
+
# Resource and Static Paths
|
|
501
|
+
# ========================================================================
|
|
502
|
+
|
|
503
|
+
def get_scripts_dir(self) -> Path:
|
|
504
|
+
"""Get the scripts directory."""
|
|
505
|
+
if self._deployment_context in (
|
|
506
|
+
DeploymentContext.DEVELOPMENT,
|
|
507
|
+
DeploymentContext.EDITABLE_INSTALL,
|
|
508
|
+
):
|
|
509
|
+
return self.framework_root / "scripts"
|
|
510
|
+
return self.package_root / "scripts"
|
|
511
|
+
|
|
512
|
+
def get_static_dir(self) -> Path:
|
|
513
|
+
"""Get the static files directory."""
|
|
514
|
+
return self.package_root / "dashboard" / "static"
|
|
515
|
+
|
|
516
|
+
def get_templates_web_dir(self) -> Path:
|
|
517
|
+
"""Get the web templates directory."""
|
|
518
|
+
return self.package_root / "dashboard" / "templates"
|
|
519
|
+
|
|
520
|
+
# ========================================================================
|
|
521
|
+
# Utility and Working Paths
|
|
522
|
+
# ========================================================================
|
|
523
|
+
|
|
524
|
+
def get_logs_dir(self, scope: str = "project") -> Path:
|
|
525
|
+
"""Get logs directory for specified scope."""
|
|
526
|
+
base_dir = self.get_config_dir(scope)
|
|
527
|
+
return base_dir / "logs"
|
|
528
|
+
|
|
529
|
+
def get_cache_dir(self, scope: str = "user") -> Path:
|
|
530
|
+
"""Get cache directory for specified scope."""
|
|
531
|
+
base_dir = self.get_config_dir(scope)
|
|
532
|
+
return base_dir / "cache"
|
|
533
|
+
|
|
534
|
+
def get_backups_dir(self, scope: str = "user") -> Path:
|
|
535
|
+
"""Get backups directory for specified scope."""
|
|
536
|
+
base_dir = self.get_config_dir(scope)
|
|
537
|
+
return base_dir / "backups"
|
|
538
|
+
|
|
539
|
+
def get_memories_dir(self, scope: str = "project") -> Path:
|
|
540
|
+
"""Get memories directory for specified scope."""
|
|
541
|
+
base_dir = self.get_config_dir(scope)
|
|
542
|
+
return base_dir / "memories"
|
|
543
|
+
|
|
544
|
+
# ========================================================================
|
|
545
|
+
# File Path Resolution
|
|
546
|
+
# ========================================================================
|
|
547
|
+
|
|
548
|
+
def get_resource_path(self, resource_type: str, filename: str) -> Path:
|
|
549
|
+
"""Get path to a resource file."""
|
|
550
|
+
resource_dirs = {
|
|
551
|
+
"scripts": self.get_scripts_dir(),
|
|
552
|
+
"templates": self.get_templates_dir(),
|
|
553
|
+
"static": self.get_static_dir(),
|
|
554
|
+
"agents": self.get_agents_dir("framework"),
|
|
555
|
+
"web_templates": self.get_templates_web_dir(),
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
base_dir = resource_dirs.get(resource_type, self.package_root)
|
|
559
|
+
return base_dir / filename
|
|
560
|
+
|
|
561
|
+
def find_file_upwards(
|
|
562
|
+
self, filename: str, start_path: Optional[Path] = None
|
|
563
|
+
) -> Optional[Path]:
|
|
564
|
+
"""Search for a file by traversing up the directory tree."""
|
|
565
|
+
current = start_path or Path.cwd()
|
|
566
|
+
|
|
567
|
+
while current != current.parent:
|
|
568
|
+
candidate = current / filename
|
|
569
|
+
if candidate.exists():
|
|
570
|
+
return candidate
|
|
571
|
+
current = current.parent
|
|
572
|
+
|
|
573
|
+
return None
|
|
574
|
+
|
|
575
|
+
def get_package_resource_path(self, resource_path: str) -> Path:
|
|
576
|
+
"""Get the path to a resource within the claude_mpm package."""
|
|
577
|
+
# Try using importlib.resources for proper package resource access
|
|
578
|
+
try:
|
|
579
|
+
from importlib import resources
|
|
580
|
+
|
|
581
|
+
parts = resource_path.split("/")
|
|
582
|
+
if len(parts) == 1:
|
|
583
|
+
with resources.path("claude_mpm", parts[0]) as p:
|
|
584
|
+
if p.exists():
|
|
585
|
+
return p
|
|
586
|
+
else:
|
|
587
|
+
# For nested paths, navigate step by step
|
|
588
|
+
package = "claude_mpm"
|
|
589
|
+
for part in parts[:-1]:
|
|
590
|
+
package = f"{package}.{part}"
|
|
591
|
+
with resources.path(package, parts[-1]) as p:
|
|
592
|
+
if p.exists():
|
|
593
|
+
return p
|
|
594
|
+
except (ImportError, ModuleNotFoundError, TypeError, AttributeError):
|
|
595
|
+
# Fall back to file system detection
|
|
596
|
+
pass
|
|
597
|
+
|
|
598
|
+
# Fallback: Use package root
|
|
599
|
+
resource = self.package_root / resource_path
|
|
600
|
+
if resource.exists():
|
|
601
|
+
return resource
|
|
602
|
+
|
|
603
|
+
raise FileNotFoundError(f"Resource not found: {resource_path}")
|
|
604
|
+
|
|
605
|
+
# ========================================================================
|
|
606
|
+
# Path Validation and Utilities
|
|
607
|
+
# ========================================================================
|
|
608
|
+
|
|
609
|
+
def ensure_directory(self, path: Path) -> Path:
|
|
610
|
+
"""Ensure a directory exists, creating it if necessary."""
|
|
611
|
+
path.mkdir(parents=True, exist_ok=True)
|
|
612
|
+
return path
|
|
613
|
+
|
|
614
|
+
def validate_not_legacy(self, path: Path) -> bool:
|
|
615
|
+
"""Check if a path contains the legacy configuration directory name."""
|
|
616
|
+
return self.LEGACY_CONFIG_DIR_NAME not in str(path)
|
|
617
|
+
|
|
618
|
+
def get_relative_to_root(
|
|
619
|
+
self, path: Union[str, Path], root_type: str = "project"
|
|
620
|
+
) -> Path:
|
|
621
|
+
"""Get a path relative to a specific root."""
|
|
622
|
+
if root_type == "project":
|
|
623
|
+
root = self.project_root
|
|
624
|
+
elif root_type == "framework":
|
|
625
|
+
root = self.framework_root
|
|
626
|
+
else:
|
|
627
|
+
raise ValueError(
|
|
628
|
+
f"Invalid root_type: {root_type}. Must be 'project' or 'framework'"
|
|
629
|
+
)
|
|
630
|
+
|
|
631
|
+
return root / path
|
|
632
|
+
|
|
633
|
+
def resolve_import_path(self, module_path: str) -> Path:
|
|
634
|
+
"""Resolve a module import path to a file path."""
|
|
635
|
+
parts = module_path.split(".")
|
|
636
|
+
if parts[0] == "claude_mpm":
|
|
637
|
+
parts = parts[1:] # Remove package name
|
|
638
|
+
|
|
639
|
+
return self.package_root.joinpath(*parts).with_suffix(".py")
|
|
640
|
+
|
|
641
|
+
# ========================================================================
|
|
642
|
+
# Cache Management
|
|
643
|
+
# ========================================================================
|
|
644
|
+
|
|
645
|
+
def clear_cache(self):
|
|
646
|
+
"""Clear all cached path lookups."""
|
|
647
|
+
# Clear lru_cache instances
|
|
648
|
+
try:
|
|
649
|
+
# Clear property caches if they exist
|
|
650
|
+
if hasattr(type(self).framework_root, "fget") and hasattr(
|
|
651
|
+
type(self).framework_root.fget, "cache_clear"
|
|
652
|
+
):
|
|
653
|
+
type(self).framework_root.fget.cache_clear()
|
|
654
|
+
if hasattr(type(self).project_root, "fget") and hasattr(
|
|
655
|
+
type(self).project_root.fget, "cache_clear"
|
|
656
|
+
):
|
|
657
|
+
type(self).project_root.fget.cache_clear()
|
|
658
|
+
except AttributeError:
|
|
659
|
+
# Properties might not have cache_clear if not using lru_cache
|
|
660
|
+
pass
|
|
661
|
+
|
|
662
|
+
# Clear static method cache
|
|
663
|
+
PathContext.detect_deployment_context.cache_clear()
|
|
664
|
+
|
|
665
|
+
logger.debug("Cleared all UnifiedPathManager caches")
|
|
666
|
+
|
|
667
|
+
def invalidate_cache(self):
|
|
668
|
+
"""Mark cache as invalidated for next access."""
|
|
669
|
+
self._cache_invalidated = True
|
|
670
|
+
self.clear_cache()
|
|
671
|
+
|
|
672
|
+
# ========================================================================
|
|
673
|
+
# Legacy Compatibility Methods
|
|
674
|
+
# ========================================================================
|
|
675
|
+
|
|
676
|
+
def get_version(self) -> str:
|
|
677
|
+
"""Get the project version."""
|
|
678
|
+
version_candidates = [
|
|
679
|
+
self.framework_root / "VERSION",
|
|
680
|
+
self.package_root / "VERSION",
|
|
681
|
+
self.project_root / "VERSION",
|
|
682
|
+
]
|
|
683
|
+
|
|
684
|
+
for version_file in version_candidates:
|
|
685
|
+
if version_file.exists():
|
|
686
|
+
return version_file.read_text().strip()
|
|
687
|
+
|
|
688
|
+
# Fallback to package metadata
|
|
689
|
+
try:
|
|
690
|
+
import claude_mpm
|
|
691
|
+
|
|
692
|
+
return getattr(claude_mpm, "__version__", "unknown")
|
|
693
|
+
except (ImportError, AttributeError):
|
|
694
|
+
return "unknown"
|
|
695
|
+
|
|
696
|
+
def ensure_src_in_path(self):
|
|
697
|
+
"""Ensure src directory is in Python path."""
|
|
698
|
+
src_dir = self.framework_root / "src"
|
|
699
|
+
if src_dir.exists() and str(src_dir) not in sys.path:
|
|
700
|
+
sys.path.insert(0, str(src_dir))
|
|
701
|
+
|
|
702
|
+
def get_executable_path(self) -> Optional[Path]:
|
|
703
|
+
"""Get the path to the claude-mpm executable for the current deployment context.
|
|
704
|
+
|
|
705
|
+
This method provides deployment-context-aware executable path detection,
|
|
706
|
+
particularly useful for MCP server configuration.
|
|
707
|
+
|
|
708
|
+
Returns:
|
|
709
|
+
Path to executable or None if not found
|
|
710
|
+
"""
|
|
711
|
+
import shutil
|
|
712
|
+
|
|
713
|
+
# Try standard which first
|
|
714
|
+
which_result = shutil.which("claude-mpm")
|
|
715
|
+
if which_result:
|
|
716
|
+
return Path(which_result)
|
|
717
|
+
|
|
718
|
+
# Enhanced detection based on deployment context
|
|
719
|
+
if self._deployment_context == DeploymentContext.PIPX_INSTALL:
|
|
720
|
+
return self._find_pipx_executable()
|
|
721
|
+
if self._deployment_context in (
|
|
722
|
+
DeploymentContext.DEVELOPMENT,
|
|
723
|
+
DeploymentContext.EDITABLE_INSTALL,
|
|
724
|
+
):
|
|
725
|
+
return self._find_development_executable()
|
|
726
|
+
if self._deployment_context == DeploymentContext.PIP_INSTALL:
|
|
727
|
+
return self._find_pip_executable()
|
|
728
|
+
|
|
729
|
+
return None
|
|
730
|
+
|
|
731
|
+
def _find_pipx_executable(self) -> Optional[Path]:
|
|
732
|
+
"""Find claude-mpm executable in pipx installation."""
|
|
733
|
+
try:
|
|
734
|
+
import claude_mpm
|
|
735
|
+
|
|
736
|
+
module_path = Path(claude_mpm.__file__).parent
|
|
737
|
+
|
|
738
|
+
if "pipx" not in str(module_path):
|
|
739
|
+
return None
|
|
740
|
+
|
|
741
|
+
# Common pipx executable locations
|
|
742
|
+
home = Path.home()
|
|
743
|
+
pipx_paths = [
|
|
744
|
+
home / ".local" / "bin" / "claude-mpm",
|
|
745
|
+
home
|
|
746
|
+
/ ".local"
|
|
747
|
+
/ "share"
|
|
748
|
+
/ "pipx"
|
|
749
|
+
/ "venvs"
|
|
750
|
+
/ "claude-mpm"
|
|
751
|
+
/ "bin"
|
|
752
|
+
/ "claude-mpm",
|
|
753
|
+
]
|
|
754
|
+
|
|
755
|
+
# Windows paths
|
|
756
|
+
if sys.platform == "win32":
|
|
757
|
+
pipx_paths.extend(
|
|
758
|
+
[
|
|
759
|
+
home / "AppData" / "Local" / "pipx" / "bin" / "claude-mpm.exe",
|
|
760
|
+
home / ".local" / "bin" / "claude-mpm.exe",
|
|
761
|
+
]
|
|
762
|
+
)
|
|
763
|
+
|
|
764
|
+
for path in pipx_paths:
|
|
765
|
+
if path.exists():
|
|
766
|
+
logger.debug(f"Found pipx executable: {path}")
|
|
767
|
+
return path
|
|
768
|
+
|
|
769
|
+
# Try to derive from module path
|
|
770
|
+
# Navigate up from module to find venv, then to bin
|
|
771
|
+
venv_path = module_path
|
|
772
|
+
for _ in range(5): # Prevent infinite loops
|
|
773
|
+
if (
|
|
774
|
+
venv_path.name == "claude-mpm"
|
|
775
|
+
and (venv_path / "pyvenv.cfg").exists()
|
|
776
|
+
):
|
|
777
|
+
# Found the venv directory
|
|
778
|
+
bin_dir = venv_path / (
|
|
779
|
+
"Scripts" if sys.platform == "win32" else "bin"
|
|
780
|
+
)
|
|
781
|
+
exe_name = (
|
|
782
|
+
"claude-mpm.exe" if sys.platform == "win32" else "claude-mpm"
|
|
783
|
+
)
|
|
784
|
+
exe_path = bin_dir / exe_name
|
|
785
|
+
|
|
786
|
+
if exe_path.exists():
|
|
787
|
+
logger.debug(
|
|
788
|
+
f"Found pipx executable via module path: {exe_path}"
|
|
789
|
+
)
|
|
790
|
+
return exe_path
|
|
791
|
+
break
|
|
792
|
+
|
|
793
|
+
if venv_path == venv_path.parent:
|
|
794
|
+
break
|
|
795
|
+
venv_path = venv_path.parent
|
|
796
|
+
|
|
797
|
+
except Exception as e:
|
|
798
|
+
logger.debug(f"Error finding pipx executable: {e}")
|
|
799
|
+
|
|
800
|
+
return None
|
|
801
|
+
|
|
802
|
+
def _find_development_executable(self) -> Optional[Path]:
|
|
803
|
+
"""Find claude-mpm executable in development installation."""
|
|
804
|
+
# For development, prefer the script in the project
|
|
805
|
+
scripts_dir = self.get_scripts_dir()
|
|
806
|
+
dev_executable = scripts_dir / "claude-mpm"
|
|
807
|
+
|
|
808
|
+
if dev_executable.exists():
|
|
809
|
+
return dev_executable
|
|
810
|
+
|
|
811
|
+
# Check if we're in a development venv
|
|
812
|
+
if hasattr(sys, "real_prefix") or (
|
|
813
|
+
hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix
|
|
814
|
+
):
|
|
815
|
+
venv_bin = Path(sys.prefix) / (
|
|
816
|
+
"Scripts" if sys.platform == "win32" else "bin"
|
|
817
|
+
)
|
|
818
|
+
venv_executable = venv_bin / "claude-mpm"
|
|
819
|
+
if venv_executable.exists():
|
|
820
|
+
return venv_executable
|
|
821
|
+
|
|
822
|
+
return None
|
|
823
|
+
|
|
824
|
+
def _find_pip_executable(self) -> Optional[Path]:
|
|
825
|
+
"""Find claude-mpm executable in pip installation."""
|
|
826
|
+
# For pip installs, check the current Python environment
|
|
827
|
+
if hasattr(sys, "real_prefix") or (
|
|
828
|
+
hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix
|
|
829
|
+
):
|
|
830
|
+
# In a virtual environment
|
|
831
|
+
venv_bin = Path(sys.prefix) / (
|
|
832
|
+
"Scripts" if sys.platform == "win32" else "bin"
|
|
833
|
+
)
|
|
834
|
+
venv_executable = venv_bin / "claude-mpm"
|
|
835
|
+
if venv_executable.exists():
|
|
836
|
+
return venv_executable
|
|
837
|
+
|
|
838
|
+
# Check system-wide installation
|
|
839
|
+
try:
|
|
840
|
+
import site
|
|
841
|
+
|
|
842
|
+
for site_dir in site.getsitepackages():
|
|
843
|
+
# Look for installed scripts
|
|
844
|
+
site_path = Path(site_dir)
|
|
845
|
+
scripts_dir = site_path.parent / (
|
|
846
|
+
"Scripts" if sys.platform == "win32" else "bin"
|
|
847
|
+
)
|
|
848
|
+
if scripts_dir.exists():
|
|
849
|
+
exe_path = scripts_dir / "claude-mpm"
|
|
850
|
+
if exe_path.exists():
|
|
851
|
+
return exe_path
|
|
852
|
+
except Exception as e:
|
|
853
|
+
logger.debug(f"Error finding pip executable: {e}")
|
|
854
|
+
|
|
855
|
+
return None
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
# ============================================================================
|
|
859
|
+
# Singleton Instance and Convenience Functions
|
|
860
|
+
# ============================================================================
|
|
861
|
+
|
|
862
|
+
# Global singleton instance
|
|
863
|
+
_path_manager: Optional[UnifiedPathManager] = None
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
def get_path_manager() -> UnifiedPathManager:
|
|
867
|
+
"""Get the global UnifiedPathManager instance."""
|
|
868
|
+
global _path_manager
|
|
869
|
+
if _path_manager is None:
|
|
870
|
+
_path_manager = UnifiedPathManager()
|
|
871
|
+
return _path_manager
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
# Convenience functions for backward compatibility
|
|
875
|
+
def get_project_root() -> Path:
|
|
876
|
+
"""Get the current project root directory."""
|
|
877
|
+
return get_path_manager().project_root
|
|
878
|
+
|
|
879
|
+
|
|
880
|
+
def get_framework_root() -> Path:
|
|
881
|
+
"""Get the framework root directory."""
|
|
882
|
+
return get_path_manager().framework_root
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
def get_package_root() -> Path:
|
|
886
|
+
"""Get the claude_mpm package root directory."""
|
|
887
|
+
return get_path_manager().package_root
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
def get_scripts_dir() -> Path:
|
|
891
|
+
"""Get the scripts directory."""
|
|
892
|
+
return get_path_manager().get_scripts_dir()
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
def get_agents_dir() -> Path:
|
|
896
|
+
"""Get the framework agents directory."""
|
|
897
|
+
return get_path_manager().get_agents_dir("framework")
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
def get_config_dir(scope: str = "project") -> Path:
|
|
901
|
+
"""Get configuration directory for specified scope."""
|
|
902
|
+
return get_path_manager().get_config_dir(scope)
|
|
903
|
+
|
|
904
|
+
|
|
905
|
+
def find_file_upwards(
|
|
906
|
+
filename: str, start_path: Optional[Path] = None
|
|
907
|
+
) -> Optional[Path]:
|
|
908
|
+
"""Search for a file by traversing up the directory tree."""
|
|
909
|
+
return get_path_manager().find_file_upwards(filename, start_path)
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
def get_package_resource_path(resource_path: str) -> Path:
|
|
913
|
+
"""Get the path to a resource within the claude_mpm package."""
|
|
914
|
+
return get_path_manager().get_package_resource_path(resource_path)
|
|
915
|
+
|
|
916
|
+
|
|
917
|
+
def get_executable_path() -> Optional[Path]:
|
|
918
|
+
"""Get the claude-mpm executable path for the current deployment context."""
|
|
919
|
+
return get_path_manager().get_executable_path()
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
# ============================================================================
|
|
923
|
+
# Export All Public Symbols
|
|
924
|
+
# ============================================================================
|
|
925
|
+
|
|
926
|
+
__all__ = [
|
|
927
|
+
"DeploymentContext",
|
|
928
|
+
"PathContext",
|
|
929
|
+
"PathType",
|
|
930
|
+
"UnifiedPathManager",
|
|
931
|
+
"find_file_upwards",
|
|
932
|
+
"get_agents_dir",
|
|
933
|
+
"get_config_dir",
|
|
934
|
+
"get_executable_path",
|
|
935
|
+
"get_framework_root",
|
|
936
|
+
"get_package_resource_path",
|
|
937
|
+
"get_package_root",
|
|
938
|
+
"get_path_manager",
|
|
939
|
+
"get_project_root",
|
|
940
|
+
"get_scripts_dir",
|
|
941
|
+
]
|