claude-mpm 3.4.10__py3-none-any.whl → 5.4.85__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_FOUNDERS_OUTPUT_STYLE.md +405 -0
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +112 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +186 -0
- claude_mpm/agents/MEMORY.md +72 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +1429 -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 +94 -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 +2501 -168
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/agents_reconcile.py +197 -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 +3253 -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 +1398 -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 +298 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +31 -0
- claude_mpm/cli/interactive/agent_wizard.py +1927 -0
- claude_mpm/cli/interactive/questionary_styles.py +65 -0
- claude_mpm/cli/interactive/skill_selector.py +481 -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 +649 -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 +1578 -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 +133 -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 +491 -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 +612 -0
- claude_mpm/core/unified_paths.py +958 -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/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/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 +1377 -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_reconciler.py +577 -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/startup_reconciliation.py +138 -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 +1205 -0
- claude_mpm/services/agents/startup_sync.py +262 -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 +711 -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 +1340 -0
- claude_mpm/services/skills/selective_skill_deployer.py +743 -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/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -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/INTEGRATION.md +611 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -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/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -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/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -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/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/pm/pm-bug-reporting/pm-bug-reporting.md +248 -0
- claude_mpm/skills/bundled/pm/pm-delegation-patterns/SKILL.md +167 -0
- claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md +113 -0
- claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md +124 -0
- claude_mpm/skills/bundled/pm/pm-teaching-mode/SKILL.md +657 -0
- claude_mpm/skills/bundled/pm/pm-ticketing-integration/SKILL.md +154 -0
- claude_mpm/skills/bundled/pm/pm-verification-protocols/SKILL.md +198 -0
- claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/security-scanning.md +439 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
- claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
- claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
- claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
- claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
- claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
- claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
- claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
- claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
- claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
- claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -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/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -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 +1189 -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 +844 -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.85.dist-info/METADATA +1023 -0
- claude_mpm-5.4.85.dist-info/RECORD +980 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/entry_points.txt +1 -3
- claude_mpm-5.4.85.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.85.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.85.dist-info}/WHEEL +0 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/top_level.txt +0 -0
claude_mpm/core/container.py
CHANGED
|
@@ -13,27 +13,29 @@ that supports:
|
|
|
13
13
|
|
|
14
14
|
import inspect
|
|
15
15
|
import threading
|
|
16
|
-
from abc import ABC
|
|
17
16
|
from enum import Enum
|
|
18
17
|
from typing import Any, Callable, Dict, List, Optional, Set, Type, TypeVar, Union
|
|
19
18
|
|
|
19
|
+
from claude_mpm.services.core.interfaces import IServiceContainer
|
|
20
|
+
|
|
20
21
|
from .logger import get_logger
|
|
21
22
|
|
|
22
23
|
logger = get_logger(__name__)
|
|
23
24
|
|
|
24
|
-
T = TypeVar(
|
|
25
|
+
T = TypeVar("T")
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
class ServiceLifetime(Enum):
|
|
28
29
|
"""Service lifetime options."""
|
|
30
|
+
|
|
29
31
|
SINGLETON = "singleton" # One instance per container
|
|
30
32
|
TRANSIENT = "transient" # New instance per request
|
|
31
|
-
SCOPED = "scoped"
|
|
33
|
+
SCOPED = "scoped" # One instance per scope
|
|
32
34
|
|
|
33
35
|
|
|
34
36
|
class ServiceRegistration:
|
|
35
37
|
"""Represents a service registration in the container."""
|
|
36
|
-
|
|
38
|
+
|
|
37
39
|
def __init__(
|
|
38
40
|
self,
|
|
39
41
|
service_type: Type,
|
|
@@ -41,11 +43,11 @@ class ServiceRegistration:
|
|
|
41
43
|
factory: Optional[Callable] = None,
|
|
42
44
|
instance: Optional[Any] = None,
|
|
43
45
|
lifetime: ServiceLifetime = ServiceLifetime.SINGLETON,
|
|
44
|
-
dependencies: Optional[Dict[str, Type]] = None
|
|
46
|
+
dependencies: Optional[Dict[str, Type]] = None,
|
|
45
47
|
):
|
|
46
48
|
"""
|
|
47
49
|
Initialize service registration.
|
|
48
|
-
|
|
50
|
+
|
|
49
51
|
Args:
|
|
50
52
|
service_type: The interface/base type being registered
|
|
51
53
|
implementation: The concrete implementation class
|
|
@@ -61,59 +63,155 @@ class ServiceRegistration:
|
|
|
61
63
|
self.lifetime = lifetime
|
|
62
64
|
self.dependencies = dependencies or {}
|
|
63
65
|
self._lock = threading.Lock()
|
|
64
|
-
|
|
65
|
-
def create_instance(self, container:
|
|
66
|
+
|
|
67
|
+
def create_instance(self, container: "DIContainer") -> Any:
|
|
66
68
|
"""Create an instance of the service."""
|
|
67
69
|
if self.instance is not None:
|
|
68
70
|
return self.instance
|
|
69
|
-
|
|
71
|
+
|
|
70
72
|
if self.factory:
|
|
71
73
|
return self.factory(container)
|
|
72
|
-
|
|
74
|
+
|
|
73
75
|
# Get constructor parameters
|
|
74
76
|
if inspect.isclass(self.implementation):
|
|
75
77
|
return container.create_instance(self.implementation, self.dependencies)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return self.implementation
|
|
78
|
+
# It's already an instance or callable
|
|
79
|
+
return self.implementation
|
|
79
80
|
|
|
80
81
|
|
|
81
82
|
class CircularDependencyError(Exception):
|
|
82
83
|
"""Raised when circular dependencies are detected."""
|
|
83
|
-
pass
|
|
84
84
|
|
|
85
85
|
|
|
86
86
|
class ServiceNotFoundError(Exception):
|
|
87
87
|
"""Raised when a requested service is not registered."""
|
|
88
|
-
pass
|
|
89
88
|
|
|
90
89
|
|
|
91
|
-
class
|
|
90
|
+
class ServiceScope:
|
|
91
|
+
"""
|
|
92
|
+
Represents a service scope for scoped lifetime services.
|
|
93
|
+
|
|
94
|
+
Scoped services live for the duration of the scope and are shared
|
|
95
|
+
within that scope.
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
def __init__(self, container: "DIContainer"):
|
|
99
|
+
"""Initialize service scope."""
|
|
100
|
+
self._container = container
|
|
101
|
+
self._scoped_instances: Dict[Type, Any] = {}
|
|
102
|
+
self._disposed = False
|
|
103
|
+
self._lock = threading.Lock()
|
|
104
|
+
|
|
105
|
+
def get_scoped_instance(self, service_type: Type) -> Optional[Any]:
|
|
106
|
+
"""Get scoped instance if exists."""
|
|
107
|
+
with self._lock:
|
|
108
|
+
return self._scoped_instances.get(service_type)
|
|
109
|
+
|
|
110
|
+
def set_scoped_instance(self, service_type: Type, instance: Any) -> None:
|
|
111
|
+
"""Store scoped instance."""
|
|
112
|
+
with self._lock:
|
|
113
|
+
if not self._disposed:
|
|
114
|
+
self._scoped_instances[service_type] = instance
|
|
115
|
+
|
|
116
|
+
def dispose(self) -> None:
|
|
117
|
+
"""
|
|
118
|
+
Dispose of the scope and all scoped instances.
|
|
119
|
+
|
|
120
|
+
Calls dispose() on instances that implement IDisposable.
|
|
121
|
+
"""
|
|
122
|
+
with self._lock:
|
|
123
|
+
if self._disposed:
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
for service_type, instance in self._scoped_instances.items():
|
|
127
|
+
# Call dispose if available
|
|
128
|
+
if hasattr(instance, "dispose"):
|
|
129
|
+
try:
|
|
130
|
+
instance.dispose()
|
|
131
|
+
except Exception as e:
|
|
132
|
+
logger.error(
|
|
133
|
+
f"Error disposing scoped service {service_type}: {e}"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
self._scoped_instances.clear()
|
|
137
|
+
self._disposed = True
|
|
138
|
+
|
|
139
|
+
def __enter__(self):
|
|
140
|
+
"""Context manager entry."""
|
|
141
|
+
return self
|
|
142
|
+
|
|
143
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
144
|
+
"""Context manager exit - dispose scope."""
|
|
145
|
+
self.dispose()
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class DIContainer(IServiceContainer):
|
|
92
149
|
"""
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
150
|
+
Enhanced Dependency Injection Container.
|
|
151
|
+
|
|
152
|
+
Implements IServiceContainer interface to provide a complete
|
|
153
|
+
dependency injection solution.
|
|
154
|
+
|
|
155
|
+
Provides:
|
|
156
|
+
- Service registration with multiple lifetime options
|
|
157
|
+
- Automatic constructor injection
|
|
158
|
+
- Interface to implementation mapping
|
|
159
|
+
- Circular dependency detection
|
|
160
|
+
- Lazy loading support
|
|
161
|
+
- Scoped service support
|
|
162
|
+
- Service disposal lifecycle
|
|
163
|
+
- Named registrations
|
|
164
|
+
- Configuration injection
|
|
96
165
|
"""
|
|
97
|
-
|
|
166
|
+
|
|
98
167
|
def __init__(self):
|
|
99
168
|
"""Initialize the DI container."""
|
|
100
169
|
self._registrations: Dict[Type, ServiceRegistration] = {}
|
|
170
|
+
self._named_registrations: Dict[str, ServiceRegistration] = {}
|
|
171
|
+
self._factories: Dict[Type, Callable] = {}
|
|
101
172
|
self._singletons: Dict[Type, Any] = {}
|
|
173
|
+
self._scopes: List[ServiceScope] = []
|
|
174
|
+
self._initialization_order: List[Type] = []
|
|
175
|
+
self._disposal_handlers: Dict[Type, Callable] = {}
|
|
102
176
|
self._lock = threading.RLock()
|
|
103
177
|
self._resolving: Set[Type] = set()
|
|
104
|
-
|
|
178
|
+
self._current_scope: Optional[ServiceScope] = None
|
|
179
|
+
|
|
105
180
|
def register(
|
|
181
|
+
self, service_type: type, implementation: type, singleton: bool = True
|
|
182
|
+
) -> None:
|
|
183
|
+
"""
|
|
184
|
+
Register a service implementation (IServiceContainer interface method).
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
service_type: The interface/base type to register
|
|
188
|
+
implementation: The concrete implementation class
|
|
189
|
+
singleton: Whether to use singleton lifetime (default True)
|
|
190
|
+
|
|
191
|
+
Examples:
|
|
192
|
+
# Register interface with implementation
|
|
193
|
+
container.register(ILogger, ConsoleLogger)
|
|
194
|
+
|
|
195
|
+
# Register as transient (new instance each time)
|
|
196
|
+
container.register(IService, ServiceImpl, singleton=False)
|
|
197
|
+
"""
|
|
198
|
+
lifetime = ServiceLifetime.SINGLETON if singleton else ServiceLifetime.TRANSIENT
|
|
199
|
+
self._register_internal(
|
|
200
|
+
service_type=service_type, implementation=implementation, lifetime=lifetime
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def _register_internal(
|
|
106
204
|
self,
|
|
107
205
|
service_type: Type[T],
|
|
108
206
|
implementation: Optional[Union[Type[T], Callable[..., T]]] = None,
|
|
109
207
|
lifetime: ServiceLifetime = ServiceLifetime.SINGLETON,
|
|
110
|
-
factory: Optional[Callable[[
|
|
208
|
+
factory: Optional[Callable[["DIContainer"], T]] = None,
|
|
111
209
|
instance: Optional[T] = None,
|
|
112
|
-
dependencies: Optional[Dict[str, Type]] = None
|
|
210
|
+
dependencies: Optional[Dict[str, Type]] = None,
|
|
113
211
|
) -> None:
|
|
114
212
|
"""
|
|
115
|
-
|
|
116
|
-
|
|
213
|
+
Internal registration method with full flexibility.
|
|
214
|
+
|
|
117
215
|
Args:
|
|
118
216
|
service_type: The interface/base type to register
|
|
119
217
|
implementation: The concrete implementation (class or factory)
|
|
@@ -121,19 +219,6 @@ class DIContainer:
|
|
|
121
219
|
factory: Optional factory function
|
|
122
220
|
instance: Pre-created instance (for singleton)
|
|
123
221
|
dependencies: Explicit dependency mapping for constructor params
|
|
124
|
-
|
|
125
|
-
Examples:
|
|
126
|
-
# Register interface with implementation
|
|
127
|
-
container.register(ILogger, ConsoleLogger)
|
|
128
|
-
|
|
129
|
-
# Register with factory
|
|
130
|
-
container.register(IDatabase, factory=lambda c: Database(c.resolve(IConfig)))
|
|
131
|
-
|
|
132
|
-
# Register singleton instance
|
|
133
|
-
container.register(IConfig, instance=Config())
|
|
134
|
-
|
|
135
|
-
# Register with explicit dependencies
|
|
136
|
-
container.register(IService, ServiceImpl, dependencies={'logger': ILogger})
|
|
137
222
|
"""
|
|
138
223
|
with self._lock:
|
|
139
224
|
registration = ServiceRegistration(
|
|
@@ -142,185 +227,642 @@ class DIContainer:
|
|
|
142
227
|
factory=factory,
|
|
143
228
|
instance=instance,
|
|
144
229
|
lifetime=lifetime,
|
|
145
|
-
dependencies=dependencies
|
|
230
|
+
dependencies=dependencies,
|
|
146
231
|
)
|
|
147
232
|
self._registrations[service_type] = registration
|
|
148
|
-
|
|
233
|
+
|
|
149
234
|
# If instance provided, store as singleton
|
|
150
235
|
if instance is not None:
|
|
151
236
|
self._singletons[service_type] = instance
|
|
152
|
-
|
|
237
|
+
|
|
238
|
+
def register_instance(self, service_type: type, instance: Any) -> None:
|
|
239
|
+
"""
|
|
240
|
+
Register a service instance (IServiceContainer interface method).
|
|
241
|
+
|
|
242
|
+
Args:
|
|
243
|
+
service_type: The interface/base type to register
|
|
244
|
+
instance: Pre-created instance to register as singleton
|
|
245
|
+
|
|
246
|
+
Examples:
|
|
247
|
+
# Register a pre-created instance using ConfigLoader
|
|
248
|
+
config_loader = ConfigLoader()
|
|
249
|
+
config = config_loader.load_main_config()
|
|
250
|
+
container.register_instance(IConfig, config)
|
|
251
|
+
"""
|
|
252
|
+
self._register_internal(
|
|
253
|
+
service_type=service_type,
|
|
254
|
+
instance=instance,
|
|
255
|
+
lifetime=ServiceLifetime.SINGLETON,
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
def resolve_all(self, service_type: type) -> List[Any]:
|
|
259
|
+
"""
|
|
260
|
+
Resolve all implementations of a service type (IServiceContainer interface method).
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
service_type: The type to resolve
|
|
264
|
+
|
|
265
|
+
Returns:
|
|
266
|
+
List of all registered implementations for the service type
|
|
267
|
+
|
|
268
|
+
Examples:
|
|
269
|
+
# Register multiple implementations
|
|
270
|
+
container.register(IPlugin, PluginA)
|
|
271
|
+
container.register(IPlugin, PluginB)
|
|
272
|
+
|
|
273
|
+
# Get all implementations
|
|
274
|
+
plugins = container.resolve_all(IPlugin)
|
|
275
|
+
"""
|
|
276
|
+
with self._lock:
|
|
277
|
+
# For now, return a list with the single registered implementation
|
|
278
|
+
# In the future, we could support multiple registrations for the same type
|
|
279
|
+
if service_type in self._registrations:
|
|
280
|
+
return [self._resolve_internal(service_type)]
|
|
281
|
+
return []
|
|
282
|
+
|
|
153
283
|
def register_singleton(
|
|
154
284
|
self,
|
|
155
|
-
|
|
156
|
-
implementation: Optional[Union[Type[T], T]] = None
|
|
285
|
+
interface: Type[T],
|
|
286
|
+
implementation: Optional[Union[Type[T], T]] = None,
|
|
287
|
+
instance: Optional[T] = None,
|
|
288
|
+
name: Optional[str] = None,
|
|
289
|
+
dispose_handler: Optional[Callable[[T], None]] = None,
|
|
157
290
|
) -> None:
|
|
158
291
|
"""
|
|
159
292
|
Register a singleton service.
|
|
160
|
-
|
|
161
|
-
|
|
293
|
+
|
|
294
|
+
Args:
|
|
295
|
+
interface: The interface/base type to register
|
|
296
|
+
implementation: The concrete implementation class
|
|
297
|
+
instance: Pre-created instance (alternative to implementation)
|
|
298
|
+
name: Optional name for named registration
|
|
299
|
+
dispose_handler: Optional handler called when disposing service
|
|
300
|
+
|
|
301
|
+
Examples:
|
|
302
|
+
# Register with implementation class
|
|
303
|
+
container.register_singleton(ILogger, ConsoleLogger)
|
|
304
|
+
|
|
305
|
+
# Register with instance using ConfigLoader
|
|
306
|
+
config_loader = ConfigLoader()
|
|
307
|
+
container.register_singleton(IConfig, instance=config_loader.load_main_config())
|
|
308
|
+
|
|
309
|
+
# Register with disposal handler
|
|
310
|
+
container.register_singleton(
|
|
311
|
+
IDatabase,
|
|
312
|
+
DatabaseConnection,
|
|
313
|
+
dispose_handler=lambda db: db.close()
|
|
314
|
+
)
|
|
162
315
|
"""
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
316
|
+
# For named registrations, create a unique registration
|
|
317
|
+
if name:
|
|
318
|
+
# Create named registration directly
|
|
319
|
+
registration = ServiceRegistration(
|
|
320
|
+
service_type=interface,
|
|
321
|
+
implementation=implementation,
|
|
322
|
+
instance=instance,
|
|
323
|
+
lifetime=ServiceLifetime.SINGLETON,
|
|
324
|
+
)
|
|
325
|
+
self._named_registrations[name] = registration
|
|
326
|
+
|
|
327
|
+
# Also store the instance if provided
|
|
328
|
+
if instance is not None:
|
|
329
|
+
# Store with a composite key for retrieval
|
|
330
|
+
named_key = (interface, name)
|
|
331
|
+
if not hasattr(self, "_named_singletons"):
|
|
332
|
+
self._named_singletons = {}
|
|
333
|
+
self._named_singletons[named_key] = instance
|
|
334
|
+
# Normal registration without name
|
|
335
|
+
elif instance is not None:
|
|
336
|
+
self._register_internal(interface, instance=instance)
|
|
337
|
+
elif implementation is not None and not inspect.isclass(implementation):
|
|
338
|
+
# It's an instance passed as implementation (backward compatibility)
|
|
339
|
+
self._register_internal(interface, instance=implementation)
|
|
166
340
|
else:
|
|
167
|
-
self.
|
|
168
|
-
|
|
169
|
-
|
|
341
|
+
self._register_internal(
|
|
342
|
+
interface, implementation, lifetime=ServiceLifetime.SINGLETON
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
# Handle disposal handler
|
|
346
|
+
if dispose_handler:
|
|
347
|
+
if name:
|
|
348
|
+
# Store with composite key for named services
|
|
349
|
+
if not hasattr(self, "_named_disposal_handlers"):
|
|
350
|
+
self._named_disposal_handlers = {}
|
|
351
|
+
self._named_disposal_handlers[(interface, name)] = dispose_handler
|
|
352
|
+
else:
|
|
353
|
+
self._disposal_handlers[interface] = dispose_handler
|
|
354
|
+
|
|
355
|
+
# Track initialization order for proper disposal
|
|
356
|
+
key = (interface, name) if name else interface
|
|
357
|
+
if key not in self._initialization_order:
|
|
358
|
+
self._initialization_order.append(key)
|
|
359
|
+
|
|
360
|
+
def register_scoped(
|
|
170
361
|
self,
|
|
171
|
-
|
|
172
|
-
implementation: Optional[Type[T]] = None
|
|
362
|
+
interface: Type[T],
|
|
363
|
+
implementation: Optional[Type[T]] = None,
|
|
364
|
+
name: Optional[str] = None,
|
|
365
|
+
) -> None:
|
|
366
|
+
"""
|
|
367
|
+
Register a scoped service.
|
|
368
|
+
|
|
369
|
+
Scoped services are created once per scope and shared within that scope.
|
|
370
|
+
|
|
371
|
+
Args:
|
|
372
|
+
interface: The interface/base type to register
|
|
373
|
+
implementation: The concrete implementation
|
|
374
|
+
name: Optional name for named registration
|
|
375
|
+
|
|
376
|
+
Examples:
|
|
377
|
+
# Register scoped service
|
|
378
|
+
container.register_scoped(IRequestContext, RequestContext)
|
|
379
|
+
|
|
380
|
+
# Use in scope
|
|
381
|
+
with container.create_scope() as scope:
|
|
382
|
+
context = container.get(IRequestContext) # Created
|
|
383
|
+
context2 = container.get(IRequestContext) # Same instance
|
|
384
|
+
"""
|
|
385
|
+
self._register_internal(
|
|
386
|
+
interface, implementation, lifetime=ServiceLifetime.SCOPED
|
|
387
|
+
)
|
|
388
|
+
if name:
|
|
389
|
+
self._named_registrations[name] = self._registrations[interface]
|
|
390
|
+
|
|
391
|
+
def register_transient(
|
|
392
|
+
self, service_type: Type[T], implementation: Optional[Type[T]] = None
|
|
173
393
|
) -> None:
|
|
174
394
|
"""
|
|
175
395
|
Register a transient service.
|
|
176
|
-
|
|
396
|
+
|
|
177
397
|
Convenience method for registering transient services.
|
|
178
398
|
"""
|
|
179
|
-
self.
|
|
180
|
-
|
|
399
|
+
self._register_internal(
|
|
400
|
+
service_type, implementation, lifetime=ServiceLifetime.TRANSIENT
|
|
401
|
+
)
|
|
402
|
+
|
|
181
403
|
def register_factory(
|
|
182
404
|
self,
|
|
183
|
-
|
|
184
|
-
factory: Callable[[
|
|
185
|
-
lifetime: ServiceLifetime = ServiceLifetime.
|
|
405
|
+
interface: Type[T],
|
|
406
|
+
factory: Callable[["DIContainer"], T],
|
|
407
|
+
lifetime: ServiceLifetime = ServiceLifetime.TRANSIENT,
|
|
408
|
+
name: Optional[str] = None,
|
|
186
409
|
) -> None:
|
|
187
410
|
"""
|
|
188
411
|
Register a service with a factory function.
|
|
189
|
-
|
|
412
|
+
|
|
190
413
|
The factory receives the container as parameter for resolving dependencies.
|
|
414
|
+
|
|
415
|
+
Args:
|
|
416
|
+
interface: The interface/base type to register
|
|
417
|
+
factory: Factory function that creates instances
|
|
418
|
+
lifetime: Service lifetime (default: TRANSIENT for factories)
|
|
419
|
+
name: Optional name for named registration
|
|
420
|
+
|
|
421
|
+
Examples:
|
|
422
|
+
# Register with factory
|
|
423
|
+
container.register_factory(
|
|
424
|
+
IService,
|
|
425
|
+
lambda c: Service(c.get(ILogger), c.get(IConfig)),
|
|
426
|
+
lifetime=ServiceLifetime.SINGLETON
|
|
427
|
+
)
|
|
428
|
+
"""
|
|
429
|
+
self._register_internal(interface, factory=factory, lifetime=lifetime)
|
|
430
|
+
self._factories[interface] = factory
|
|
431
|
+
if name:
|
|
432
|
+
self._named_registrations[name] = self._registrations[interface]
|
|
433
|
+
|
|
434
|
+
def get(self, interface: Type[T], name: Optional[str] = None) -> T:
|
|
435
|
+
"""
|
|
436
|
+
Get service instance with dependency resolution.
|
|
437
|
+
|
|
438
|
+
This is the primary method for retrieving services from the container.
|
|
439
|
+
It handles all lifetime management and dependency resolution.
|
|
440
|
+
|
|
441
|
+
Args:
|
|
442
|
+
interface: The type to resolve
|
|
443
|
+
name: Optional name for named registration lookup
|
|
444
|
+
|
|
445
|
+
Returns:
|
|
446
|
+
Instance of the requested service
|
|
447
|
+
|
|
448
|
+
Raises:
|
|
449
|
+
ServiceNotFoundError: If service is not registered
|
|
450
|
+
CircularDependencyError: If circular dependencies detected
|
|
451
|
+
|
|
452
|
+
Examples:
|
|
453
|
+
# Get by interface
|
|
454
|
+
logger = container.get(ILogger)
|
|
455
|
+
|
|
456
|
+
# Get named service
|
|
457
|
+
primary_db = container.get(IDatabase, name="primary")
|
|
191
458
|
"""
|
|
192
|
-
|
|
193
|
-
|
|
459
|
+
if name:
|
|
460
|
+
if name not in self._named_registrations:
|
|
461
|
+
suggestions = self._get_similar_names(name)
|
|
462
|
+
raise ServiceNotFoundError(
|
|
463
|
+
f"Named service '{name}' is not registered. "
|
|
464
|
+
f"Did you mean: {', '.join(suggestions)}?"
|
|
465
|
+
if suggestions
|
|
466
|
+
else ""
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
# Check if we have a pre-stored instance for this named service
|
|
470
|
+
named_key = (interface, name)
|
|
471
|
+
if (
|
|
472
|
+
hasattr(self, "_named_singletons")
|
|
473
|
+
and named_key in self._named_singletons
|
|
474
|
+
):
|
|
475
|
+
return self._named_singletons[named_key]
|
|
476
|
+
|
|
477
|
+
# Otherwise resolve from named registration
|
|
478
|
+
registration = self._named_registrations[name]
|
|
479
|
+
if registration.instance is not None:
|
|
480
|
+
return registration.instance
|
|
481
|
+
if registration.factory:
|
|
482
|
+
return registration.factory(self)
|
|
483
|
+
return self.create_instance(
|
|
484
|
+
registration.implementation, registration.dependencies
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
return self._resolve_internal(interface)
|
|
488
|
+
|
|
194
489
|
def resolve(self, service_type: Type[T]) -> T:
|
|
195
490
|
"""
|
|
196
|
-
Resolve a service from the container.
|
|
197
|
-
|
|
491
|
+
Resolve a service from the container (legacy method).
|
|
492
|
+
|
|
493
|
+
This method is maintained for backward compatibility.
|
|
494
|
+
New code should use get() instead.
|
|
495
|
+
|
|
198
496
|
Args:
|
|
199
497
|
service_type: The type to resolve
|
|
200
|
-
|
|
498
|
+
|
|
201
499
|
Returns:
|
|
202
500
|
Instance of the requested service
|
|
203
|
-
|
|
501
|
+
|
|
204
502
|
Raises:
|
|
205
503
|
ServiceNotFoundError: If service is not registered
|
|
206
504
|
CircularDependencyError: If circular dependencies detected
|
|
207
505
|
"""
|
|
506
|
+
return self.get(service_type)
|
|
507
|
+
|
|
508
|
+
def _resolve_internal(self, service_type: Type[T]) -> T:
|
|
509
|
+
"""
|
|
510
|
+
Internal method to resolve a service.
|
|
511
|
+
|
|
512
|
+
Handles the actual resolution logic with proper locking and lifecycle management.
|
|
513
|
+
"""
|
|
208
514
|
with self._lock:
|
|
209
515
|
# Check for circular dependencies
|
|
210
516
|
if service_type in self._resolving:
|
|
211
|
-
cycle =
|
|
517
|
+
cycle = (
|
|
518
|
+
" -> ".join(str(t.__name__) for t in self._resolving)
|
|
519
|
+
+ f" -> {service_type.__name__}"
|
|
520
|
+
)
|
|
212
521
|
raise CircularDependencyError(f"Circular dependency detected: {cycle}")
|
|
213
|
-
|
|
522
|
+
|
|
214
523
|
# Check if registered
|
|
215
524
|
if service_type not in self._registrations:
|
|
216
|
-
|
|
217
|
-
|
|
525
|
+
suggestions = self._get_similar_types(service_type)
|
|
526
|
+
error_msg = f"Service {service_type.__name__} is not registered."
|
|
527
|
+
if suggestions:
|
|
528
|
+
error_msg += f" Did you mean: {', '.join(suggestions)}?"
|
|
529
|
+
raise ServiceNotFoundError(error_msg)
|
|
530
|
+
|
|
218
531
|
registration = self._registrations[service_type]
|
|
219
|
-
|
|
220
|
-
#
|
|
532
|
+
|
|
533
|
+
# Handle different lifetimes
|
|
221
534
|
if registration.lifetime == ServiceLifetime.SINGLETON:
|
|
535
|
+
# Return existing singleton if available
|
|
222
536
|
if service_type in self._singletons:
|
|
223
537
|
return self._singletons[service_type]
|
|
224
|
-
|
|
538
|
+
|
|
539
|
+
elif registration.lifetime == ServiceLifetime.SCOPED:
|
|
540
|
+
# Check current scope
|
|
541
|
+
if (
|
|
542
|
+
self._current_scope
|
|
543
|
+
and (
|
|
544
|
+
instance := self._current_scope.get_scoped_instance(
|
|
545
|
+
service_type
|
|
546
|
+
)
|
|
547
|
+
)
|
|
548
|
+
is not None
|
|
549
|
+
):
|
|
550
|
+
return instance
|
|
551
|
+
|
|
225
552
|
# Mark as resolving
|
|
226
553
|
self._resolving.add(service_type)
|
|
227
|
-
|
|
554
|
+
|
|
228
555
|
try:
|
|
229
556
|
# Create instance
|
|
230
557
|
instance = registration.create_instance(self)
|
|
231
|
-
|
|
232
|
-
# Store
|
|
558
|
+
|
|
559
|
+
# Store based on lifetime
|
|
233
560
|
if registration.lifetime == ServiceLifetime.SINGLETON:
|
|
234
561
|
self._singletons[service_type] = instance
|
|
235
|
-
|
|
562
|
+
if service_type not in self._initialization_order:
|
|
563
|
+
self._initialization_order.append(service_type)
|
|
564
|
+
|
|
565
|
+
elif registration.lifetime == ServiceLifetime.SCOPED:
|
|
566
|
+
if self._current_scope:
|
|
567
|
+
self._current_scope.set_scoped_instance(service_type, instance)
|
|
568
|
+
|
|
569
|
+
# Call initialization hook if available
|
|
570
|
+
if hasattr(instance, "initialize"):
|
|
571
|
+
try:
|
|
572
|
+
instance.initialize()
|
|
573
|
+
except Exception as e:
|
|
574
|
+
logger.error(
|
|
575
|
+
f"Failed to initialize service {service_type.__name__}: {e}"
|
|
576
|
+
)
|
|
577
|
+
raise
|
|
578
|
+
|
|
236
579
|
return instance
|
|
237
|
-
|
|
580
|
+
|
|
238
581
|
finally:
|
|
239
582
|
self._resolving.remove(service_type)
|
|
240
|
-
|
|
241
|
-
def resolve_optional(
|
|
583
|
+
|
|
584
|
+
def resolve_optional(
|
|
585
|
+
self, service_type: Type[T], default: Optional[T] = None
|
|
586
|
+
) -> Optional[T]:
|
|
242
587
|
"""
|
|
243
588
|
Resolve a service if registered, otherwise return default.
|
|
244
|
-
|
|
589
|
+
|
|
245
590
|
Useful for optional dependencies.
|
|
246
591
|
"""
|
|
247
592
|
try:
|
|
248
593
|
return self.resolve(service_type)
|
|
249
594
|
except ServiceNotFoundError:
|
|
250
595
|
return default
|
|
251
|
-
|
|
252
|
-
def create_instance(
|
|
596
|
+
|
|
597
|
+
def create_instance(
|
|
598
|
+
self, cls: Type[T], explicit_deps: Optional[Dict[str, Type]] = None
|
|
599
|
+
) -> T:
|
|
253
600
|
"""
|
|
254
601
|
Create an instance of a class, resolving constructor dependencies.
|
|
255
|
-
|
|
602
|
+
|
|
256
603
|
Args:
|
|
257
604
|
cls: The class to instantiate
|
|
258
605
|
explicit_deps: Explicit dependency mapping for constructor params
|
|
259
|
-
|
|
606
|
+
|
|
260
607
|
Returns:
|
|
261
608
|
New instance with resolved dependencies
|
|
262
609
|
"""
|
|
263
610
|
# Get constructor signature
|
|
264
611
|
sig = inspect.signature(cls.__init__)
|
|
265
612
|
kwargs = {}
|
|
266
|
-
|
|
613
|
+
|
|
267
614
|
for param_name, param in sig.parameters.items():
|
|
268
|
-
if param_name ==
|
|
615
|
+
if param_name == "self":
|
|
269
616
|
continue
|
|
270
|
-
|
|
617
|
+
|
|
271
618
|
# Check explicit dependencies first
|
|
272
619
|
if explicit_deps and param_name in explicit_deps:
|
|
273
620
|
dep_type = explicit_deps[param_name]
|
|
274
621
|
kwargs[param_name] = self.resolve(dep_type)
|
|
275
622
|
continue
|
|
276
|
-
|
|
623
|
+
|
|
277
624
|
# Try to resolve by type annotation
|
|
278
625
|
if param.annotation != param.empty:
|
|
279
626
|
param_type = param.annotation
|
|
280
|
-
|
|
627
|
+
|
|
628
|
+
# Handle string annotations (forward references)
|
|
629
|
+
if isinstance(param_type, str):
|
|
630
|
+
# Try to resolve forward reference
|
|
631
|
+
try:
|
|
632
|
+
# Get the module where the class is defined
|
|
633
|
+
import sys
|
|
634
|
+
|
|
635
|
+
frame = sys._getframe(1)
|
|
636
|
+
module = frame.f_globals
|
|
637
|
+
if param_type in module:
|
|
638
|
+
param_type = module[param_type]
|
|
639
|
+
else:
|
|
640
|
+
# Try looking in registrations by name
|
|
641
|
+
for reg_type in self._registrations:
|
|
642
|
+
if reg_type.__name__ == param_type:
|
|
643
|
+
param_type = reg_type
|
|
644
|
+
break
|
|
645
|
+
except Exception:
|
|
646
|
+
# If we can't resolve, skip this parameter
|
|
647
|
+
if param.default != param.empty:
|
|
648
|
+
kwargs[param_name] = param.default
|
|
649
|
+
continue
|
|
650
|
+
|
|
281
651
|
# Handle Optional types
|
|
282
|
-
if hasattr(param_type,
|
|
652
|
+
if hasattr(param_type, "__origin__") and param_type.__origin__ is Union:
|
|
283
653
|
# Get the non-None type from Optional
|
|
284
654
|
args = param_type.__args__
|
|
285
|
-
param_type = next(
|
|
286
|
-
|
|
655
|
+
param_type = next(
|
|
656
|
+
(arg for arg in args if arg is not type(None)), None
|
|
657
|
+
)
|
|
658
|
+
|
|
287
659
|
if param_type and param_type in self._registrations:
|
|
660
|
+
# Check for circular dependency
|
|
661
|
+
if param_type in self._resolving:
|
|
662
|
+
# Circular dependency detected
|
|
663
|
+
cycle = (
|
|
664
|
+
" -> ".join(str(t.__name__) for t in self._resolving)
|
|
665
|
+
+ f" -> {param_type.__name__}"
|
|
666
|
+
)
|
|
667
|
+
raise CircularDependencyError(
|
|
668
|
+
f"Circular dependency detected: {cycle}"
|
|
669
|
+
)
|
|
288
670
|
kwargs[param_name] = self.resolve(param_type)
|
|
289
671
|
elif param.default != param.empty:
|
|
290
672
|
# Use default value
|
|
291
673
|
kwargs[param_name] = param.default
|
|
292
|
-
|
|
674
|
+
|
|
293
675
|
return cls(**kwargs)
|
|
294
|
-
|
|
676
|
+
|
|
295
677
|
def is_registered(self, service_type: Type) -> bool:
|
|
296
678
|
"""Check if a service type is registered."""
|
|
297
679
|
return service_type in self._registrations
|
|
298
|
-
|
|
680
|
+
|
|
299
681
|
def get_all_registrations(self) -> Dict[Type, ServiceRegistration]:
|
|
300
682
|
"""Get all service registrations."""
|
|
301
683
|
with self._lock:
|
|
302
684
|
return self._registrations.copy()
|
|
303
|
-
|
|
304
|
-
def
|
|
685
|
+
|
|
686
|
+
def create_scope(self) -> ServiceScope:
|
|
687
|
+
"""
|
|
688
|
+
Create a new service scope.
|
|
689
|
+
|
|
690
|
+
Scoped services will be created once per scope and shared within that scope.
|
|
691
|
+
|
|
692
|
+
Returns:
|
|
693
|
+
New ServiceScope instance
|
|
694
|
+
|
|
695
|
+
Examples:
|
|
696
|
+
# Use scope with context manager
|
|
697
|
+
with container.create_scope() as scope:
|
|
698
|
+
# Services with SCOPED lifetime are shared within this scope
|
|
699
|
+
service1 = container.get(IScopedService)
|
|
700
|
+
service2 = container.get(IScopedService)
|
|
701
|
+
assert service1 is service2 # Same instance
|
|
702
|
+
|
|
703
|
+
# Scope is disposed, scoped instances are cleaned up
|
|
704
|
+
"""
|
|
705
|
+
scope = ServiceScope(self)
|
|
706
|
+
with self._lock:
|
|
707
|
+
self._scopes.append(scope)
|
|
708
|
+
# Set as current scope for resolution
|
|
709
|
+
old_scope = self._current_scope
|
|
710
|
+
self._current_scope = scope
|
|
711
|
+
|
|
712
|
+
# Return a context manager that restores old scope
|
|
713
|
+
class ScopeContext:
|
|
714
|
+
def __init__(self, container, new_scope, old_scope):
|
|
715
|
+
self.container = container
|
|
716
|
+
self.new_scope = new_scope
|
|
717
|
+
self.old_scope = old_scope
|
|
718
|
+
|
|
719
|
+
def __enter__(self):
|
|
720
|
+
return self.new_scope
|
|
721
|
+
|
|
722
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
723
|
+
with self.container._lock:
|
|
724
|
+
self.container._current_scope = self.old_scope
|
|
725
|
+
if self.new_scope in self.container._scopes:
|
|
726
|
+
self.container._scopes.remove(self.new_scope)
|
|
727
|
+
self.new_scope.dispose()
|
|
728
|
+
|
|
729
|
+
return ScopeContext(self, scope, old_scope)
|
|
730
|
+
|
|
731
|
+
def create_child_container(self) -> "DIContainer":
|
|
305
732
|
"""
|
|
306
733
|
Create a child container that inherits registrations.
|
|
307
|
-
|
|
308
|
-
Useful for
|
|
734
|
+
|
|
735
|
+
Useful for isolated scenarios where you want separate singleton instances.
|
|
309
736
|
"""
|
|
310
737
|
child = DIContainer()
|
|
311
738
|
with self._lock:
|
|
312
739
|
# Copy registrations but not singleton instances
|
|
313
740
|
for service_type, registration in self._registrations.items():
|
|
314
741
|
child._registrations[service_type] = registration
|
|
742
|
+
# Copy named registrations
|
|
743
|
+
child._named_registrations = self._named_registrations.copy()
|
|
744
|
+
# Copy factories
|
|
745
|
+
child._factories = self._factories.copy()
|
|
746
|
+
# Copy disposal handlers
|
|
747
|
+
child._disposal_handlers = self._disposal_handlers.copy()
|
|
315
748
|
return child
|
|
316
|
-
|
|
749
|
+
|
|
750
|
+
def dispose(self) -> None:
|
|
751
|
+
"""
|
|
752
|
+
Dispose of the container and all managed services.
|
|
753
|
+
|
|
754
|
+
Calls disposal handlers for singleton services in reverse initialization order.
|
|
755
|
+
Also disposes any active scopes.
|
|
756
|
+
"""
|
|
757
|
+
with self._lock:
|
|
758
|
+
# Dispose scopes first
|
|
759
|
+
for scope in reversed(self._scopes):
|
|
760
|
+
scope.dispose()
|
|
761
|
+
self._scopes.clear()
|
|
762
|
+
|
|
763
|
+
# Dispose singletons in reverse initialization order
|
|
764
|
+
for service_type in reversed(self._initialization_order):
|
|
765
|
+
if service_type in self._singletons:
|
|
766
|
+
instance = self._singletons[service_type]
|
|
767
|
+
|
|
768
|
+
# Call disposal handler if registered
|
|
769
|
+
if service_type in self._disposal_handlers:
|
|
770
|
+
try:
|
|
771
|
+
self._disposal_handlers[service_type](instance)
|
|
772
|
+
except Exception as e:
|
|
773
|
+
logger.error(
|
|
774
|
+
f"Error in disposal handler for {service_type.__name__}: {e}"
|
|
775
|
+
)
|
|
776
|
+
|
|
777
|
+
# Call dispose method if available
|
|
778
|
+
elif hasattr(instance, "dispose"):
|
|
779
|
+
try:
|
|
780
|
+
instance.dispose()
|
|
781
|
+
except Exception as e:
|
|
782
|
+
logger.error(
|
|
783
|
+
f"Error disposing service {service_type.__name__}: {e}"
|
|
784
|
+
)
|
|
785
|
+
|
|
786
|
+
# Clear everything
|
|
787
|
+
self._singletons.clear()
|
|
788
|
+
self._initialization_order.clear()
|
|
789
|
+
self._current_scope = None
|
|
790
|
+
|
|
317
791
|
def clear(self) -> None:
|
|
318
792
|
"""Clear all registrations and instances."""
|
|
793
|
+
self.dispose()
|
|
319
794
|
with self._lock:
|
|
320
795
|
self._registrations.clear()
|
|
321
|
-
self.
|
|
796
|
+
self._named_registrations.clear()
|
|
797
|
+
self._factories.clear()
|
|
798
|
+
self._disposal_handlers.clear()
|
|
322
799
|
self._resolving.clear()
|
|
323
800
|
|
|
801
|
+
def _get_similar_types(self, service_type: Type) -> List[str]:
|
|
802
|
+
"""
|
|
803
|
+
Get similar registered type names for better error messages.
|
|
804
|
+
|
|
805
|
+
Uses simple string similarity to suggest possible alternatives.
|
|
806
|
+
"""
|
|
807
|
+
if not self._registrations:
|
|
808
|
+
return []
|
|
809
|
+
|
|
810
|
+
type_name = service_type.__name__.lower()
|
|
811
|
+
similar = []
|
|
812
|
+
|
|
813
|
+
for registered_type in self._registrations:
|
|
814
|
+
registered_name = registered_type.__name__
|
|
815
|
+
registered_lower = registered_name.lower()
|
|
816
|
+
|
|
817
|
+
# Check for substring match
|
|
818
|
+
if type_name in registered_lower or registered_lower in type_name:
|
|
819
|
+
similar.append(registered_name)
|
|
820
|
+
continue
|
|
821
|
+
|
|
822
|
+
# Check for common prefix
|
|
823
|
+
common_prefix_len = 0
|
|
824
|
+
for i, (a, b) in enumerate(zip(type_name, registered_lower)):
|
|
825
|
+
if a == b:
|
|
826
|
+
common_prefix_len = i + 1
|
|
827
|
+
else:
|
|
828
|
+
break
|
|
829
|
+
|
|
830
|
+
if common_prefix_len >= min(3, len(type_name) // 2):
|
|
831
|
+
similar.append(registered_name)
|
|
832
|
+
|
|
833
|
+
return similar[:3] # Return top 3 suggestions
|
|
834
|
+
|
|
835
|
+
def _get_similar_names(self, name: str) -> List[str]:
|
|
836
|
+
"""
|
|
837
|
+
Get similar registered names for better error messages.
|
|
838
|
+
"""
|
|
839
|
+
if not self._named_registrations:
|
|
840
|
+
return []
|
|
841
|
+
|
|
842
|
+
name_lower = name.lower()
|
|
843
|
+
similar = []
|
|
844
|
+
|
|
845
|
+
for registered_name in self._named_registrations:
|
|
846
|
+
registered_lower = registered_name.lower()
|
|
847
|
+
|
|
848
|
+
# Check for substring match
|
|
849
|
+
if name_lower in registered_lower or registered_lower in name_lower:
|
|
850
|
+
similar.append(registered_name)
|
|
851
|
+
continue
|
|
852
|
+
|
|
853
|
+
# Check for common prefix
|
|
854
|
+
common_prefix_len = 0
|
|
855
|
+
for i, (a, b) in enumerate(zip(name_lower, registered_lower)):
|
|
856
|
+
if a == b:
|
|
857
|
+
common_prefix_len = i + 1
|
|
858
|
+
else:
|
|
859
|
+
break
|
|
860
|
+
|
|
861
|
+
if common_prefix_len >= min(3, len(name_lower) // 2):
|
|
862
|
+
similar.append(registered_name)
|
|
863
|
+
|
|
864
|
+
return similar[:3] # Return top 3 suggestions
|
|
865
|
+
|
|
324
866
|
|
|
325
867
|
# Global container instance (optional, for convenience)
|
|
326
868
|
_global_container: Optional[DIContainer] = None
|
|
@@ -330,7 +872,7 @@ _global_lock = threading.Lock()
|
|
|
330
872
|
def get_container() -> DIContainer:
|
|
331
873
|
"""
|
|
332
874
|
Get the global DI container instance.
|
|
333
|
-
|
|
875
|
+
|
|
334
876
|
Creates one if it doesn't exist.
|
|
335
877
|
"""
|
|
336
878
|
global _global_container
|
|
@@ -344,4 +886,4 @@ def set_container(container: DIContainer) -> None:
|
|
|
344
886
|
"""Set the global DI container instance."""
|
|
345
887
|
global _global_container
|
|
346
888
|
with _global_lock:
|
|
347
|
-
_global_container = container
|
|
889
|
+
_global_container = container
|