claude-mpm 3.4.10__py3-none-any.whl → 5.4.55__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/BUILD_NUMBER +1 -0
- claude_mpm/VERSION +1 -0
- claude_mpm/__init__.py +50 -12
- claude_mpm/__main__.py +7 -2
- claude_mpm/agents/BASE_AGENT.md +164 -0
- claude_mpm/agents/BASE_ENGINEER.md +658 -0
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +290 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
- claude_mpm/agents/MEMORY.md +72 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +1402 -0
- claude_mpm/agents/WORKFLOW.md +111 -0
- claude_mpm/agents/__init__.py +92 -80
- claude_mpm/agents/agent-template.yaml +83 -0
- claude_mpm/agents/agent_loader.py +560 -745
- claude_mpm/agents/agent_loader_integration.py +53 -55
- claude_mpm/agents/agents_metadata.py +186 -27
- claude_mpm/agents/async_agent_loader.py +436 -0
- claude_mpm/agents/base_agent.json +8 -4
- claude_mpm/agents/frontmatter_validator.py +754 -0
- claude_mpm/agents/system_agent_config.py +222 -155
- claude_mpm/agents/templates/README.md +465 -0
- claude_mpm/agents/templates/__init__.py +17 -13
- claude_mpm/agents/templates/circuit-breakers.md +1391 -0
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/git-file-tracking.md +584 -0
- claude_mpm/agents/templates/pm-examples.md +474 -0
- claude_mpm/agents/templates/pm-red-flags.md +310 -0
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -0
- claude_mpm/agents/templates/response-format.md +583 -0
- claude_mpm/agents/templates/structured-questions-examples.md +615 -0
- claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
- claude_mpm/agents/templates/ticketing-examples.md +277 -0
- claude_mpm/agents/templates/validation-templates.md +312 -0
- claude_mpm/cli/__init__.py +90 -128
- claude_mpm/cli/__main__.py +33 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/__init__.py +36 -12
- claude_mpm/cli/commands/agent_manager.py +1403 -0
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +335 -0
- claude_mpm/cli/commands/agents.py +2503 -168
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/aggregate.py +540 -0
- claude_mpm/cli/commands/analyze.py +553 -0
- claude_mpm/cli/commands/analyze_code.py +528 -0
- claude_mpm/cli/commands/auto_configure.py +1053 -0
- claude_mpm/cli/commands/cleanup.py +588 -0
- claude_mpm/cli/commands/cleanup_orphaned_agents.py +150 -0
- claude_mpm/cli/commands/config.py +586 -0
- claude_mpm/cli/commands/configure.py +2654 -0
- claude_mpm/cli/commands/configure_agent_display.py +282 -0
- claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
- claude_mpm/cli/commands/configure_hook_manager.py +225 -0
- claude_mpm/cli/commands/configure_models.py +18 -0
- claude_mpm/cli/commands/configure_navigation.py +184 -0
- claude_mpm/cli/commands/configure_paths.py +104 -0
- claude_mpm/cli/commands/configure_persistence.py +254 -0
- claude_mpm/cli/commands/configure_startup_manager.py +646 -0
- claude_mpm/cli/commands/configure_template_editor.py +497 -0
- claude_mpm/cli/commands/configure_validators.py +73 -0
- claude_mpm/cli/commands/dashboard.py +286 -0
- claude_mpm/cli/commands/debug.py +1386 -0
- claude_mpm/cli/commands/doctor.py +243 -0
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/info.py +195 -74
- claude_mpm/cli/commands/local_deploy.py +534 -0
- claude_mpm/cli/commands/mcp.py +205 -0
- claude_mpm/cli/commands/mcp_command_router.py +161 -0
- claude_mpm/cli/commands/mcp_config.py +154 -0
- claude_mpm/cli/commands/mcp_config_commands.py +20 -0
- claude_mpm/cli/commands/mcp_external_commands.py +249 -0
- claude_mpm/cli/commands/mcp_install_commands.py +346 -0
- claude_mpm/cli/commands/mcp_pipx_config.py +208 -0
- claude_mpm/cli/commands/mcp_server_commands.py +155 -0
- claude_mpm/cli/commands/mcp_setup_external.py +868 -0
- claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
- claude_mpm/cli/commands/memory.py +585 -846
- claude_mpm/cli/commands/monitor.py +228 -310
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +759 -0
- claude_mpm/cli/commands/mpm_init/display.py +341 -0
- claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/modes.py +397 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +722 -0
- claude_mpm/cli/commands/mpm_init_cli.py +396 -0
- claude_mpm/cli/commands/mpm_init_handler.py +195 -0
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/profile.py +276 -0
- claude_mpm/cli/commands/run.py +910 -488
- claude_mpm/cli/commands/search.py +458 -0
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +1246 -0
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/commands/tickets.py +536 -53
- claude_mpm/cli/commands/uninstall.py +176 -0
- claude_mpm/cli/commands/upgrade.py +152 -0
- claude_mpm/cli/commands/verify.py +119 -0
- claude_mpm/cli/executor.py +297 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +21 -0
- claude_mpm/cli/interactive/agent_wizard.py +1947 -0
- claude_mpm/cli/interactive/skills_wizard.py +491 -0
- claude_mpm/cli/parser.py +87 -563
- claude_mpm/cli/parsers/__init__.py +35 -0
- claude_mpm/cli/parsers/agent_manager_parser.py +393 -0
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +575 -0
- claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
- claude_mpm/cli/parsers/analyze_parser.py +135 -0
- claude_mpm/cli/parsers/auto_configure_parser.py +120 -0
- claude_mpm/cli/parsers/base_parser.py +644 -0
- claude_mpm/cli/parsers/config_parser.py +208 -0
- claude_mpm/cli/parsers/configure_parser.py +138 -0
- claude_mpm/cli/parsers/dashboard_parser.py +113 -0
- claude_mpm/cli/parsers/debug_parser.py +319 -0
- claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
- claude_mpm/cli/parsers/mcp_parser.py +195 -0
- claude_mpm/cli/parsers/memory_parser.py +138 -0
- claude_mpm/cli/parsers/monitor_parser.py +142 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
- claude_mpm/cli/parsers/profile_parser.py +147 -0
- claude_mpm/cli/parsers/run_parser.py +157 -0
- claude_mpm/cli/parsers/search_parser.py +245 -0
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +277 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/parsers/tickets_parser.py +203 -0
- claude_mpm/cli/shared/__init__.py +40 -0
- claude_mpm/cli/shared/argument_patterns.py +205 -0
- claude_mpm/cli/shared/base_command.py +242 -0
- claude_mpm/cli/shared/error_handling.py +242 -0
- claude_mpm/cli/shared/output_formatters.py +241 -0
- claude_mpm/cli/startup.py +1743 -0
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/startup_logging.py +839 -0
- claude_mpm/cli/utils.py +136 -47
- claude_mpm/cli_module/__init__.py +6 -6
- claude_mpm/cli_module/args.py +188 -140
- claude_mpm/cli_module/commands.py +79 -70
- claude_mpm/cli_module/migration_example.py +42 -64
- claude_mpm/commands/__init__.py +14 -0
- claude_mpm/commands/mpm-config.md +28 -0
- claude_mpm/commands/mpm-doctor.md +20 -0
- claude_mpm/commands/mpm-help.md +20 -0
- claude_mpm/commands/mpm-init.md +120 -0
- claude_mpm/commands/mpm-monitor.md +31 -0
- claude_mpm/commands/mpm-organize.md +120 -0
- claude_mpm/commands/mpm-postmortem.md +21 -0
- claude_mpm/commands/mpm-session-resume.md +30 -0
- claude_mpm/commands/mpm-status.md +20 -0
- claude_mpm/commands/mpm-ticket-view.md +109 -0
- claude_mpm/commands/mpm-version.md +20 -0
- claude_mpm/commands/mpm.md +31 -0
- claude_mpm/config/__init__.py +42 -2
- claude_mpm/config/agent_config.py +402 -0
- claude_mpm/config/agent_presets.py +488 -0
- claude_mpm/config/agent_sources.py +352 -0
- claude_mpm/config/experimental_features.py +217 -0
- claude_mpm/config/model_config.py +428 -0
- claude_mpm/config/paths.py +258 -0
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/config/socketio_config.py +125 -83
- claude_mpm/constants.py +132 -22
- claude_mpm/core/__init__.py +62 -36
- claude_mpm/core/agent_name_normalizer.py +71 -73
- claude_mpm/core/agent_registry.py +385 -492
- claude_mpm/core/agent_session_manager.py +81 -70
- claude_mpm/core/api_validator.py +330 -0
- claude_mpm/core/base_service.py +159 -122
- claude_mpm/core/cache.py +560 -0
- claude_mpm/core/claude_runner.py +696 -916
- claude_mpm/core/config.py +613 -122
- claude_mpm/core/config_aliases.py +74 -73
- claude_mpm/core/config_constants.py +314 -0
- claude_mpm/core/constants.py +361 -0
- claude_mpm/core/container.py +646 -104
- claude_mpm/core/enums.py +452 -0
- claude_mpm/core/error_handler.py +623 -0
- claude_mpm/core/exceptions.py +536 -0
- claude_mpm/core/factories.py +105 -109
- claude_mpm/core/file_utils.py +764 -0
- claude_mpm/core/framework/__init__.py +25 -0
- claude_mpm/core/framework/formatters/__init__.py +11 -0
- claude_mpm/core/framework/formatters/capability_generator.py +367 -0
- claude_mpm/core/framework/formatters/content_formatter.py +278 -0
- claude_mpm/core/framework/formatters/context_generator.py +185 -0
- claude_mpm/core/framework/loaders/__init__.py +13 -0
- claude_mpm/core/framework/loaders/agent_loader.py +213 -0
- claude_mpm/core/framework/loaders/file_loader.py +176 -0
- claude_mpm/core/framework/loaders/instruction_loader.py +222 -0
- claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
- claude_mpm/core/framework/processors/__init__.py +11 -0
- claude_mpm/core/framework/processors/memory_processor.py +230 -0
- claude_mpm/core/framework/processors/metadata_processor.py +146 -0
- claude_mpm/core/framework/processors/template_processor.py +244 -0
- claude_mpm/core/framework_loader.py +485 -414
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +246 -86
- claude_mpm/core/hook_performance_config.py +147 -0
- claude_mpm/core/injectable_service.py +72 -63
- claude_mpm/core/instruction_reinforcement_hook.py +267 -0
- claude_mpm/core/interactive_session.py +670 -0
- claude_mpm/core/interfaces.py +570 -164
- claude_mpm/core/lazy.py +467 -0
- claude_mpm/core/log_manager.py +707 -0
- claude_mpm/core/logger.py +295 -134
- claude_mpm/core/logging_config.py +474 -0
- claude_mpm/core/logging_utils.py +520 -0
- claude_mpm/core/minimal_framework_loader.py +24 -22
- claude_mpm/core/mixins.py +30 -29
- claude_mpm/core/oneshot_session.py +594 -0
- claude_mpm/core/optimized_agent_loader.py +479 -0
- claude_mpm/core/optimized_startup.py +554 -0
- claude_mpm/core/output_style_manager.py +483 -0
- claude_mpm/core/pm_hook_interceptor.py +197 -82
- claude_mpm/core/protocols/__init__.py +23 -0
- claude_mpm/core/protocols/runner_protocol.py +103 -0
- claude_mpm/core/protocols/session_protocol.py +131 -0
- claude_mpm/core/service_registry.py +153 -116
- claude_mpm/core/session_manager.py +179 -64
- claude_mpm/core/shared/__init__.py +17 -0
- claude_mpm/core/shared/config_loader.py +326 -0
- claude_mpm/core/shared/path_resolver.py +281 -0
- claude_mpm/core/shared/singleton_manager.py +221 -0
- claude_mpm/core/socketio_pool.py +400 -137
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/tool_access_control.py +64 -57
- claude_mpm/core/types.py +307 -0
- claude_mpm/core/typing_utils.py +553 -0
- claude_mpm/core/unified_agent_registry.py +969 -0
- claude_mpm/core/unified_config.py +570 -0
- claude_mpm/core/unified_paths.py +941 -0
- claude_mpm/dashboard/__init__.py +12 -0
- claude_mpm/dashboard/api/simple_directory.py +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
- claude_mpm/experimental/__init__.py +10 -0
- claude_mpm/experimental/cli_enhancements.py +104 -89
- claude_mpm/generators/__init__.py +1 -1
- claude_mpm/generators/agent_profile_generator.py +76 -66
- claude_mpm/hooks/__init__.py +37 -1
- claude_mpm/hooks/base_hook.py +37 -32
- claude_mpm/hooks/claude_hooks/__init__.py +1 -1
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/connection_pool.py +250 -0
- claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +888 -0
- claude_mpm/hooks/claude_hooks/hook_handler.py +652 -875
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +10 -7
- claude_mpm/hooks/claude_hooks/installer.py +806 -0
- claude_mpm/hooks/claude_hooks/memory_integration.py +249 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +412 -0
- claude_mpm/hooks/claude_hooks/services/__init__.py +15 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +229 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +254 -0
- claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
- claude_mpm/hooks/claude_hooks/services/state_manager.py +284 -0
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
- claude_mpm/hooks/claude_hooks/tool_analysis.py +224 -0
- claude_mpm/hooks/failure_learning/__init__.py +54 -0
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
- claude_mpm/hooks/instruction_reinforcement.py +301 -0
- claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
- claude_mpm/hooks/kuzu_memory_hook.py +386 -0
- claude_mpm/hooks/kuzu_response_hook.py +179 -0
- claude_mpm/hooks/memory_integration_hook.py +201 -107
- claude_mpm/hooks/session_resume_hook.py +121 -0
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/hooks/tool_call_interceptor.py +92 -76
- claude_mpm/hooks/validation_hooks.py +62 -54
- claude_mpm/init.py +518 -83
- claude_mpm/models/__init__.py +9 -9
- claude_mpm/models/agent_definition.py +40 -23
- claude_mpm/models/agent_session.py +538 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/schemas/__init__.py +12 -0
- claude_mpm/scripts/__init__.py +15 -0
- claude_mpm/scripts/claude-hook-handler.sh +227 -0
- claude_mpm/scripts/launch_monitor.py +165 -0
- claude_mpm/scripts/mpm_doctor.py +322 -0
- claude_mpm/scripts/socketio_daemon.py +189 -200
- claude_mpm/scripts/start_activity_logging.py +91 -0
- claude_mpm/services/__init__.py +208 -39
- claude_mpm/services/agent_capabilities_service.py +266 -0
- claude_mpm/services/agents/__init__.py +89 -0
- claude_mpm/services/agents/agent_builder.py +514 -0
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_recommendation_service.py +278 -0
- claude_mpm/services/agents/agent_review_service.py +280 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -0
- claude_mpm/services/agents/auto_config_manager.py +796 -0
- claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
- claude_mpm/services/agents/cache_git_manager.py +621 -0
- claude_mpm/services/agents/deployment/__init__.py +21 -0
- claude_mpm/services/agents/deployment/agent_config_provider.py +410 -0
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +358 -0
- claude_mpm/services/agents/deployment/agent_definition_factory.py +80 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +1037 -0
- claude_mpm/services/agents/deployment/agent_discovery_service.py +546 -0
- claude_mpm/services/agents/deployment/agent_environment_manager.py +288 -0
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +383 -0
- claude_mpm/services/agents/deployment/agent_format_converter.py +505 -0
- claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +160 -0
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +957 -0
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +273 -0
- claude_mpm/services/agents/deployment/agent_operation_service.py +573 -0
- claude_mpm/services/agents/deployment/agent_record_service.py +418 -0
- claude_mpm/services/agents/deployment/agent_restore_handler.py +84 -0
- claude_mpm/services/agents/deployment/agent_state_service.py +381 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +1369 -0
- claude_mpm/services/agents/deployment/agent_validator.py +376 -0
- claude_mpm/services/agents/deployment/agent_version_manager.py +322 -0
- claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +10 -13
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +149 -0
- claude_mpm/services/agents/deployment/async_agent_deployment.py +768 -0
- claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
- claude_mpm/services/agents/deployment/config/__init__.py +13 -0
- claude_mpm/services/agents/deployment/config/deployment_config.py +181 -0
- claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
- claude_mpm/services/agents/deployment/deployment_config_loader.py +178 -0
- claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
- claude_mpm/services/agents/deployment/deployment_type_detector.py +120 -0
- claude_mpm/services/agents/deployment/deployment_wrapper.py +129 -0
- claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
- claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
- claude_mpm/services/agents/deployment/facade/deployment_executor.py +70 -0
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +269 -0
- claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
- claude_mpm/services/agents/deployment/interface_adapter.py +226 -0
- claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
- claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
- claude_mpm/services/agents/deployment/local_template_deployment.py +362 -0
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +1478 -0
- claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +162 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
- claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +240 -0
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +110 -0
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +80 -0
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +92 -0
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +101 -0
- claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +102 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
- claude_mpm/services/agents/deployment/processors/agent_processor.py +269 -0
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +311 -0
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +862 -0
- claude_mpm/services/agents/deployment/results/__init__.py +13 -0
- claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
- claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
- claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
- claude_mpm/services/agents/deployment/strategies/base_strategy.py +113 -0
- claude_mpm/services/agents/deployment/strategies/project_strategy.py +148 -0
- claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
- claude_mpm/services/agents/deployment/strategies/system_strategy.py +131 -0
- claude_mpm/services/agents/deployment/strategies/user_strategy.py +130 -0
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +228 -0
- claude_mpm/services/agents/deployment/validation/__init__.py +21 -0
- claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
- claude_mpm/services/agents/deployment/validation/template_validator.py +319 -0
- claude_mpm/services/agents/deployment/validation/validation_result.py +214 -0
- claude_mpm/services/agents/git_source_manager.py +682 -0
- claude_mpm/services/agents/loading/__init__.py +11 -0
- claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +306 -228
- claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +106 -91
- claude_mpm/services/agents/loading/framework_agent_loader.py +433 -0
- claude_mpm/services/agents/local_template_manager.py +784 -0
- claude_mpm/services/agents/management/__init__.py +9 -0
- claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +92 -69
- claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +219 -168
- claude_mpm/services/agents/memory/__init__.py +22 -0
- claude_mpm/services/agents/memory/agent_memory_manager.py +784 -0
- claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +20 -18
- claude_mpm/services/agents/memory/content_manager.py +470 -0
- claude_mpm/services/agents/memory/memory_categorization_service.py +167 -0
- claude_mpm/services/agents/memory/memory_file_service.py +129 -0
- claude_mpm/services/agents/memory/memory_format_service.py +201 -0
- claude_mpm/services/agents/memory/memory_limits_service.py +101 -0
- claude_mpm/services/agents/memory/template_generator.py +83 -0
- claude_mpm/services/agents/observers.py +547 -0
- claude_mpm/services/agents/recommender.py +617 -0
- claude_mpm/services/agents/registry/__init__.py +30 -0
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +273 -0
- claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +370 -295
- claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
- claude_mpm/services/agents/sources/__init__.py +13 -0
- claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +1202 -0
- claude_mpm/services/agents/startup_sync.py +259 -0
- claude_mpm/services/agents/toolchain_detector.py +478 -0
- claude_mpm/services/analysis/__init__.py +35 -0
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/async_session_logger.py +665 -0
- claude_mpm/services/claude_session_logger.py +321 -0
- claude_mpm/services/cli/__init__.py +18 -0
- claude_mpm/services/cli/agent_cleanup_service.py +408 -0
- claude_mpm/services/cli/agent_dependency_service.py +395 -0
- claude_mpm/services/cli/agent_listing_service.py +463 -0
- claude_mpm/services/cli/agent_output_formatter.py +605 -0
- claude_mpm/services/cli/agent_validation_service.py +590 -0
- claude_mpm/services/cli/memory_crud_service.py +622 -0
- claude_mpm/services/cli/memory_output_formatter.py +604 -0
- claude_mpm/services/cli/resume_service.py +617 -0
- claude_mpm/services/cli/session_manager.py +604 -0
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +372 -0
- claude_mpm/services/cli/startup_checker.py +362 -0
- claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
- claude_mpm/services/command_deployment_service.py +446 -0
- claude_mpm/services/command_handler_service.py +221 -0
- claude_mpm/services/communication/__init__.py +22 -0
- claude_mpm/services/core/__init__.py +108 -0
- claude_mpm/services/core/base.py +269 -0
- claude_mpm/services/core/cache_manager.py +309 -0
- claude_mpm/services/core/interfaces/__init__.py +273 -0
- claude_mpm/services/core/interfaces/agent.py +514 -0
- claude_mpm/services/core/interfaces/communication.py +316 -0
- claude_mpm/services/core/interfaces/health.py +169 -0
- claude_mpm/services/core/interfaces/infrastructure.py +357 -0
- claude_mpm/services/core/interfaces/model.py +281 -0
- claude_mpm/services/core/interfaces/process.py +372 -0
- claude_mpm/services/core/interfaces/project.py +121 -0
- claude_mpm/services/core/interfaces/restart.py +307 -0
- claude_mpm/services/core/interfaces/service.py +405 -0
- claude_mpm/services/core/interfaces/stability.py +260 -0
- claude_mpm/services/core/interfaces.py +81 -0
- claude_mpm/services/core/memory_manager.py +682 -0
- claude_mpm/services/core/models/__init__.py +70 -0
- claude_mpm/services/core/models/agent_config.py +384 -0
- claude_mpm/services/core/models/health.py +162 -0
- claude_mpm/services/core/models/process.py +239 -0
- claude_mpm/services/core/models/restart.py +302 -0
- claude_mpm/services/core/models/stability.py +264 -0
- claude_mpm/services/core/models/toolchain.py +306 -0
- claude_mpm/services/core/path_resolver.py +517 -0
- claude_mpm/services/core/service_container.py +520 -0
- claude_mpm/services/core/service_interfaces.py +436 -0
- claude_mpm/services/diagnostics/__init__.py +18 -0
- claude_mpm/services/diagnostics/checks/__init__.py +38 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +370 -0
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/base_check.py +60 -0
- claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
- claude_mpm/services/diagnostics/checks/common_issues_check.py +363 -0
- claude_mpm/services/diagnostics/checks/configuration_check.py +306 -0
- claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
- claude_mpm/services/diagnostics/checks/installation_check.py +520 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +415 -0
- claude_mpm/services/diagnostics/checks/mcp_check.py +330 -0
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
- claude_mpm/services/diagnostics/checks/monitor_check.py +281 -0
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/checks/startup_log_check.py +319 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +286 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +578 -0
- claude_mpm/services/diagnostics/models.py +138 -0
- claude_mpm/services/event_aggregator.py +582 -0
- claude_mpm/services/event_bus/__init__.py +18 -0
- claude_mpm/services/event_bus/config.py +186 -0
- claude_mpm/services/event_bus/direct_relay.py +312 -0
- claude_mpm/services/event_bus/event_bus.py +396 -0
- claude_mpm/services/event_bus/relay.py +326 -0
- claude_mpm/services/events/__init__.py +44 -0
- claude_mpm/services/events/consumers/__init__.py +18 -0
- claude_mpm/services/events/consumers/dead_letter.py +306 -0
- claude_mpm/services/events/consumers/logging.py +184 -0
- claude_mpm/services/events/consumers/metrics.py +241 -0
- claude_mpm/services/events/consumers/socketio.py +377 -0
- claude_mpm/services/events/core.py +480 -0
- claude_mpm/services/events/interfaces.py +214 -0
- claude_mpm/services/events/producers/__init__.py +14 -0
- claude_mpm/services/events/producers/hook.py +269 -0
- claude_mpm/services/events/producers/system.py +329 -0
- claude_mpm/services/exceptions.py +433 -353
- claude_mpm/services/framework_claude_md_generator/__init__.py +81 -80
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +74 -67
- claude_mpm/services/framework_claude_md_generator/content_validator.py +66 -62
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +82 -60
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +36 -37
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +41 -40
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +15 -15
- claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +5 -4
- claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
- claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +5 -4
- claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
- claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +26 -30
- claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
- claude_mpm/services/framework_claude_md_generator/version_manager.py +31 -30
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +579 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/hook_installer_service.py +506 -0
- claude_mpm/services/hook_service.py +159 -111
- claude_mpm/services/infrastructure/__init__.py +52 -0
- claude_mpm/services/infrastructure/context_preservation.py +569 -0
- claude_mpm/services/infrastructure/daemon_manager.py +279 -0
- claude_mpm/services/infrastructure/logging.py +209 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +39 -0
- claude_mpm/services/infrastructure/monitoring/aggregator.py +432 -0
- claude_mpm/services/infrastructure/monitoring/base.py +122 -0
- claude_mpm/services/infrastructure/monitoring/legacy.py +203 -0
- claude_mpm/services/infrastructure/monitoring/network.py +219 -0
- claude_mpm/services/infrastructure/monitoring/process.py +343 -0
- claude_mpm/services/infrastructure/monitoring/resources.py +244 -0
- claude_mpm/services/infrastructure/monitoring/service.py +368 -0
- claude_mpm/services/infrastructure/monitoring.py +71 -0
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/instructions/__init__.py +9 -0
- claude_mpm/services/instructions/instruction_cache_service.py +374 -0
- claude_mpm/services/local_ops/__init__.py +155 -0
- claude_mpm/services/local_ops/crash_detector.py +257 -0
- claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
- claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
- claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
- claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
- claude_mpm/services/local_ops/health_manager.py +427 -0
- claude_mpm/services/local_ops/log_monitor.py +396 -0
- claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
- claude_mpm/services/local_ops/process_manager.py +595 -0
- claude_mpm/services/local_ops/resource_monitor.py +331 -0
- claude_mpm/services/local_ops/restart_manager.py +401 -0
- claude_mpm/services/local_ops/restart_policy.py +387 -0
- claude_mpm/services/local_ops/state_manager.py +372 -0
- claude_mpm/services/local_ops/unified_manager.py +600 -0
- claude_mpm/services/mcp_config_manager.py +1542 -0
- claude_mpm/services/mcp_service_verifier.py +732 -0
- claude_mpm/services/memory/__init__.py +19 -0
- claude_mpm/services/{memory_builder.py → memory/builder.py} +465 -373
- claude_mpm/services/memory/cache/__init__.py +14 -0
- claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +237 -200
- claude_mpm/services/memory/cache/simple_cache.py +331 -0
- claude_mpm/services/memory/failure_tracker.py +578 -0
- claude_mpm/services/memory/indexed_memory.py +648 -0
- claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +272 -243
- claude_mpm/services/memory/router.py +951 -0
- claude_mpm/services/memory_hook_service.py +470 -0
- claude_mpm/services/model/__init__.py +147 -0
- claude_mpm/services/model/base_provider.py +365 -0
- claude_mpm/services/model/claude_provider.py +412 -0
- claude_mpm/services/model/model_router.py +452 -0
- claude_mpm/services/model/ollama_provider.py +415 -0
- claude_mpm/services/monitor/__init__.py +20 -0
- claude_mpm/services/monitor/daemon.py +698 -0
- claude_mpm/services/monitor/daemon_manager.py +1076 -0
- claude_mpm/services/monitor/event_emitter.py +350 -0
- claude_mpm/services/monitor/handlers/__init__.py +21 -0
- claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
- claude_mpm/services/monitor/handlers/dashboard.py +299 -0
- claude_mpm/services/monitor/handlers/file.py +264 -0
- claude_mpm/services/monitor/handlers/hooks.py +512 -0
- claude_mpm/services/monitor/management/__init__.py +18 -0
- claude_mpm/services/monitor/management/health.py +124 -0
- claude_mpm/services/monitor/management/lifecycle.py +730 -0
- claude_mpm/services/monitor/server.py +1493 -0
- claude_mpm/services/monitor_build_service.py +349 -0
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/orphan_detection.py +786 -0
- claude_mpm/services/pm_skills_deployer.py +707 -0
- claude_mpm/services/port_manager.py +597 -0
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/profile_manager.py +337 -0
- claude_mpm/services/project/__init__.py +44 -0
- claude_mpm/services/{project_analyzer.py → project/analyzer.py} +541 -291
- claude_mpm/services/project/analyzer_v2.py +566 -0
- claude_mpm/services/project/architecture_analyzer.py +461 -0
- claude_mpm/services/project/archive_manager.py +1045 -0
- claude_mpm/services/project/dependency_analyzer.py +462 -0
- claude_mpm/services/project/detection_strategies.py +719 -0
- claude_mpm/services/project/documentation_manager.py +554 -0
- claude_mpm/services/project/enhanced_analyzer.py +572 -0
- claude_mpm/services/project/language_analyzer.py +265 -0
- claude_mpm/services/project/metrics_collector.py +407 -0
- claude_mpm/services/project/project_organizer.py +1009 -0
- claude_mpm/services/project/registry.py +636 -0
- claude_mpm/services/project/toolchain_analyzer.py +583 -0
- claude_mpm/services/project_port_allocator.py +596 -0
- claude_mpm/services/recovery_manager.py +293 -240
- claude_mpm/services/response_tracker.py +267 -0
- claude_mpm/services/runner_configuration_service.py +605 -0
- claude_mpm/services/self_upgrade_service.py +608 -0
- claude_mpm/services/session_management_service.py +314 -0
- claude_mpm/services/session_manager.py +380 -0
- claude_mpm/services/shared/__init__.py +21 -0
- claude_mpm/services/shared/async_service_base.py +216 -0
- claude_mpm/services/shared/config_service_base.py +301 -0
- claude_mpm/services/shared/lifecycle_service_base.py +308 -0
- claude_mpm/services/shared/manager_base.py +315 -0
- claude_mpm/services/shared/service_factory.py +309 -0
- claude_mpm/services/skills/__init__.py +21 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1324 -0
- claude_mpm/services/skills/selective_skill_deployer.py +744 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +1168 -0
- claude_mpm/services/socketio/__init__.py +25 -0
- claude_mpm/services/socketio/client_proxy.py +229 -0
- claude_mpm/services/socketio/dashboard_server.py +362 -0
- claude_mpm/services/socketio/event_normalizer.py +798 -0
- claude_mpm/services/socketio/handlers/__init__.py +30 -0
- claude_mpm/services/socketio/handlers/base.py +136 -0
- claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
- claude_mpm/services/socketio/handlers/connection.py +643 -0
- claude_mpm/services/socketio/handlers/connection_handler.py +333 -0
- claude_mpm/services/socketio/handlers/file.py +263 -0
- claude_mpm/services/socketio/handlers/git.py +962 -0
- claude_mpm/services/socketio/handlers/hook.py +211 -0
- claude_mpm/services/socketio/handlers/memory.py +26 -0
- claude_mpm/services/socketio/handlers/project.py +24 -0
- claude_mpm/services/socketio/handlers/registry.py +214 -0
- claude_mpm/services/socketio/migration_utils.py +343 -0
- claude_mpm/services/socketio/monitor_client.py +364 -0
- claude_mpm/services/socketio/server/__init__.py +18 -0
- claude_mpm/services/socketio/server/broadcaster.py +569 -0
- claude_mpm/services/socketio/server/connection_manager.py +579 -0
- claude_mpm/services/socketio/server/core.py +1079 -0
- claude_mpm/services/socketio/server/eventbus_integration.py +245 -0
- claude_mpm/services/socketio/server/main.py +501 -0
- claude_mpm/services/socketio_client_manager.py +173 -143
- claude_mpm/services/socketio_server.py +38 -1657
- claude_mpm/services/subprocess_launcher_service.py +322 -0
- claude_mpm/services/system_instructions_service.py +270 -0
- claude_mpm/services/ticket_manager.py +25 -209
- claude_mpm/services/ticket_services/__init__.py +26 -0
- claude_mpm/services/ticket_services/crud_service.py +328 -0
- claude_mpm/services/ticket_services/formatter_service.py +290 -0
- claude_mpm/services/ticket_services/search_service.py +324 -0
- claude_mpm/services/ticket_services/validation_service.py +303 -0
- claude_mpm/services/ticket_services/workflow_service.py +244 -0
- claude_mpm/services/unified/__init__.py +65 -0
- claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
- claude_mpm/services/unified/config_strategies/__init__.py +175 -0
- claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
- claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
- claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
- claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
- claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
- claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
- claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
- claude_mpm/services/unified/deployment_strategies/base.py +553 -0
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
- claude_mpm/services/unified/deployment_strategies/local.py +607 -0
- claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
- claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
- claude_mpm/services/unified/interfaces.py +475 -0
- claude_mpm/services/unified/migration.py +509 -0
- claude_mpm/services/unified/strategies.py +534 -0
- claude_mpm/services/unified/unified_analyzer.py +542 -0
- claude_mpm/services/unified/unified_config.py +691 -0
- claude_mpm/services/unified/unified_deployment.py +466 -0
- claude_mpm/services/utility_service.py +280 -0
- claude_mpm/services/version_control/__init__.py +34 -37
- claude_mpm/services/version_control/branch_strategy.py +26 -17
- claude_mpm/services/version_control/conflict_resolution.py +52 -36
- claude_mpm/services/version_control/git_operations.py +183 -49
- claude_mpm/services/version_control/semantic_versioning.py +172 -61
- claude_mpm/services/version_control/version_parser.py +546 -0
- claude_mpm/services/version_service.py +379 -0
- claude_mpm/services/visualization/__init__.py +15 -0
- claude_mpm/services/visualization/mermaid_generator.py +937 -0
- claude_mpm/skills/__init__.py +42 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
- claude_mpm/skills/bundled/__init__.py +6 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +573 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/security-scanning.md +439 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +286 -0
- claude_mpm/skills/skill_manager.py +405 -0
- claude_mpm/skills/skills_registry.py +347 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/storage/__init__.py +9 -0
- claude_mpm/storage/state_storage.py +546 -0
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/templates/questions/__init__.py +38 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +311 -0
- claude_mpm/templates/questions/project_init.py +385 -0
- claude_mpm/templates/questions/ticket_mgmt.py +394 -0
- claude_mpm/ticket_wrapper.py +2 -2
- claude_mpm/tools/__init__.py +10 -0
- claude_mpm/tools/__main__.py +208 -0
- claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
- claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
- claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
- claude_mpm/tools/code_tree_analyzer/core.py +380 -0
- claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
- claude_mpm/tools/code_tree_analyzer/events.py +168 -0
- claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
- claude_mpm/tools/code_tree_analyzer/models.py +39 -0
- claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
- claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
- claude_mpm/tools/code_tree_builder.py +631 -0
- claude_mpm/tools/code_tree_events.py +420 -0
- claude_mpm/tools/socketio_debug.py +671 -0
- claude_mpm/utils/__init__.py +8 -8
- claude_mpm/utils/agent_dependency_loader.py +1090 -0
- claude_mpm/utils/agent_filters.py +261 -0
- claude_mpm/utils/common.py +544 -0
- claude_mpm/utils/config_manager.py +168 -126
- claude_mpm/utils/console.py +11 -0
- claude_mpm/utils/database_connector.py +298 -0
- claude_mpm/utils/dependency_cache.py +373 -0
- claude_mpm/utils/dependency_manager.py +60 -59
- claude_mpm/utils/dependency_strategies.py +381 -0
- claude_mpm/utils/display_helper.py +260 -0
- claude_mpm/utils/environment_context.py +313 -0
- claude_mpm/utils/error_handler.py +78 -66
- claude_mpm/utils/file_utils.py +305 -0
- claude_mpm/utils/framework_detection.py +12 -11
- claude_mpm/utils/git_analyzer.py +407 -0
- claude_mpm/utils/gitignore.py +244 -0
- claude_mpm/utils/import_migration_example.py +12 -60
- claude_mpm/utils/imports.py +48 -45
- claude_mpm/utils/log_cleanup.py +627 -0
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/path_operations.py +110 -104
- claude_mpm/utils/progress.py +387 -0
- claude_mpm/utils/robust_installer.py +823 -0
- claude_mpm/utils/session_logging.py +121 -0
- claude_mpm/utils/structured_questions.py +619 -0
- claude_mpm/utils/subprocess_utils.py +343 -0
- claude_mpm/validation/__init__.py +1 -1
- claude_mpm/validation/agent_validator.py +214 -108
- claude_mpm/validation/frontmatter_validator.py +252 -0
- claude_mpm-5.4.55.dist-info/METADATA +999 -0
- claude_mpm-5.4.55.dist-info/RECORD +868 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/entry_points.txt +1 -3
- claude_mpm-5.4.55.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.55.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -88
- claude_mpm/agents/INSTRUCTIONS.md +0 -352
- claude_mpm/agents/backups/INSTRUCTIONS.md +0 -352
- claude_mpm/agents/base_agent_loader.py +0 -529
- claude_mpm/agents/schema/agent_schema.json +0 -314
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -36
- claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/documentation_agent_20250726_234551.json +0 -45
- claude_mpm/agents/templates/backup/engineer_agent_20250726_234551.json +0 -49
- claude_mpm/agents/templates/backup/ops_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/qa_agent_20250726_234551.json +0 -45
- claude_mpm/agents/templates/backup/research_agent_20250726_234551.json +0 -49
- claude_mpm/agents/templates/backup/security_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/version_control_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/data_engineer.json +0 -110
- claude_mpm/agents/templates/documentation.json +0 -109
- claude_mpm/agents/templates/engineer.json +0 -113
- claude_mpm/agents/templates/ops.json +0 -109
- claude_mpm/agents/templates/pm.json +0 -25
- claude_mpm/agents/templates/qa.json +0 -111
- claude_mpm/agents/templates/research.json +0 -65
- claude_mpm/agents/templates/security.json +0 -113
- claude_mpm/agents/templates/test_integration.json +0 -112
- claude_mpm/agents/templates/version_control.json +0 -107
- claude_mpm/cli/commands/ui.py +0 -57
- claude_mpm/core/simple_runner.py +0 -1046
- claude_mpm/dashboard/open_dashboard.py +0 -34
- claude_mpm/deployment_paths.py +0 -261
- claude_mpm/hooks/builtin/__init__.py +0 -1
- claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
- claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
- claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
- claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
- claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
- claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
- claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
- claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
- claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
- claude_mpm/orchestration/__init__.py +0 -6
- claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
- claude_mpm/orchestration/archive/factory.py +0 -215
- claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
- claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
- claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
- claude_mpm/orchestration/archive/orchestrator.py +0 -501
- claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
- claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
- claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
- claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
- claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
- claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
- claude_mpm/schemas/workflow_validator.py +0 -411
- claude_mpm/services/agent_deployment.py +0 -1534
- claude_mpm/services/agent_lifecycle_manager.py +0 -1169
- claude_mpm/services/agent_memory_manager.py +0 -1415
- claude_mpm/services/agent_registry.py +0 -676
- claude_mpm/services/deployed_agent_discovery.py +0 -226
- claude_mpm/services/framework_agent_loader.py +0 -337
- claude_mpm/services/framework_claude_md_generator.py +0 -621
- claude_mpm/services/health_monitor.py +0 -892
- claude_mpm/services/memory_router.py +0 -538
- claude_mpm/services/parent_directory_manager/__init__.py +0 -577
- claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
- claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
- claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
- claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
- claude_mpm/services/parent_directory_manager/operations.py +0 -186
- claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
- claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
- claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
- claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
- claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
- claude_mpm/services/standalone_socketio_server.py +0 -1300
- claude_mpm/services/ticket_manager_di.py +0 -318
- claude_mpm/services/ticketing_service_original.py +0 -508
- claude_mpm/ui/__init__.py +0 -1
- claude_mpm/ui/rich_terminal_ui.py +0 -295
- claude_mpm/ui/terminal_ui.py +0 -328
- claude_mpm/utils/paths.py +0 -289
- claude_mpm-3.4.10.dist-info/METADATA +0 -183
- claude_mpm-3.4.10.dist-info/RECORD +0 -201
- claude_mpm-3.4.10.dist-info/licenses/LICENSE +0 -21
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/WHEEL +0 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Database Connector with Fallback Support
|
|
3
|
+
=========================================
|
|
4
|
+
|
|
5
|
+
WHY: Database connectivity packages often have compilation requirements that
|
|
6
|
+
can fail on certain systems. This module provides intelligent fallback to
|
|
7
|
+
pure Python alternatives when native packages are unavailable.
|
|
8
|
+
|
|
9
|
+
DESIGN DECISION: We prioritize pure Python implementations over native ones
|
|
10
|
+
for better cross-platform compatibility, even if they might be slightly slower.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from typing import Any, ClassVar, Dict, Optional, Tuple
|
|
14
|
+
|
|
15
|
+
from ..core.logger import get_logger
|
|
16
|
+
|
|
17
|
+
logger = get_logger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class DatabaseConnector:
|
|
21
|
+
"""
|
|
22
|
+
Manages database connections with automatic fallback to alternative drivers.
|
|
23
|
+
|
|
24
|
+
WHY: Provides a unified interface for database connections that automatically
|
|
25
|
+
handles missing or failed driver installations by falling back to alternatives.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
# Database drivers in order of preference (first is preferred)
|
|
29
|
+
MYSQL_DRIVERS: ClassVar[list] = [
|
|
30
|
+
("pymysql", "pymysql"), # Pure Python, no compilation required
|
|
31
|
+
("mysqlclient", "MySQLdb"), # Faster but requires MySQL dev headers
|
|
32
|
+
("mysql-connector-python", "mysql.connector"), # Oracle's pure Python driver
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
POSTGRESQL_DRIVERS: ClassVar[list] = [
|
|
36
|
+
("psycopg2-binary", "psycopg2"), # Binary wheel, no compilation
|
|
37
|
+
("psycopg2", "psycopg2"), # Requires PostgreSQL dev headers
|
|
38
|
+
("pg8000", "pg8000"), # Pure Python alternative
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
ORACLE_DRIVERS: ClassVar[list] = [
|
|
42
|
+
("cx_Oracle", "cx_Oracle"), # Requires Oracle client libraries
|
|
43
|
+
("oracledb", "oracledb"), # Pure Python Oracle driver (newer)
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
def __init__(self):
|
|
47
|
+
"""Initialize the database connector."""
|
|
48
|
+
self.available_drivers: Dict[str, Tuple[str, Any]] = {}
|
|
49
|
+
self._scan_available_drivers()
|
|
50
|
+
|
|
51
|
+
def _scan_available_drivers(self) -> None:
|
|
52
|
+
"""
|
|
53
|
+
Scan for available database drivers and cache them.
|
|
54
|
+
|
|
55
|
+
WHY: Pre-scanning allows us to know what's available without
|
|
56
|
+
repeatedly trying imports, improving performance.
|
|
57
|
+
"""
|
|
58
|
+
# Check MySQL drivers
|
|
59
|
+
for package_name, import_name in self.MYSQL_DRIVERS:
|
|
60
|
+
driver = self._try_import(import_name)
|
|
61
|
+
if driver and "mysql" not in self.available_drivers:
|
|
62
|
+
self.available_drivers["mysql"] = (package_name, driver)
|
|
63
|
+
logger.info(f"MySQL driver available: {package_name}")
|
|
64
|
+
|
|
65
|
+
# Check PostgreSQL drivers
|
|
66
|
+
for package_name, import_name in self.POSTGRESQL_DRIVERS:
|
|
67
|
+
driver = self._try_import(import_name)
|
|
68
|
+
if driver and "postgresql" not in self.available_drivers:
|
|
69
|
+
self.available_drivers["postgresql"] = (package_name, driver)
|
|
70
|
+
logger.info(f"PostgreSQL driver available: {package_name}")
|
|
71
|
+
|
|
72
|
+
# Check Oracle drivers
|
|
73
|
+
for package_name, import_name in self.ORACLE_DRIVERS:
|
|
74
|
+
driver = self._try_import(import_name)
|
|
75
|
+
if driver and "oracle" not in self.available_drivers:
|
|
76
|
+
self.available_drivers["oracle"] = (package_name, driver)
|
|
77
|
+
logger.info(f"Oracle driver available: {package_name}")
|
|
78
|
+
|
|
79
|
+
def _try_import(self, module_name: str) -> Optional[Any]:
|
|
80
|
+
"""
|
|
81
|
+
Try to import a module and return it if successful.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
module_name: Name of the module to import
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
The imported module or None if import fails
|
|
88
|
+
"""
|
|
89
|
+
try:
|
|
90
|
+
import importlib
|
|
91
|
+
|
|
92
|
+
return importlib.import_module(module_name)
|
|
93
|
+
except ImportError:
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
def get_mysql_connection_string(
|
|
97
|
+
self, host: str, database: str, user: str, password: str, port: int = 3306
|
|
98
|
+
) -> Optional[str]:
|
|
99
|
+
"""
|
|
100
|
+
Get a SQLAlchemy connection string for MySQL with automatic driver selection.
|
|
101
|
+
|
|
102
|
+
WHY: SQLAlchemy needs different connection string formats depending on the driver.
|
|
103
|
+
This method automatically selects the best available driver.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
host: Database host
|
|
107
|
+
database: Database name
|
|
108
|
+
user: Username
|
|
109
|
+
password: Password
|
|
110
|
+
port: Port number (default 3306)
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
SQLAlchemy connection string or None if no driver available
|
|
114
|
+
"""
|
|
115
|
+
if "mysql" not in self.available_drivers:
|
|
116
|
+
logger.error(
|
|
117
|
+
"No MySQL driver available. Install one of: pymysql, mysqlclient, or mysql-connector-python"
|
|
118
|
+
)
|
|
119
|
+
return None
|
|
120
|
+
|
|
121
|
+
package_name, _ = self.available_drivers["mysql"]
|
|
122
|
+
|
|
123
|
+
# Format connection string based on driver
|
|
124
|
+
if package_name == "pymysql":
|
|
125
|
+
return f"mysql+pymysql://{user}:{password}@{host}:{port}/{database}"
|
|
126
|
+
if package_name == "mysqlclient":
|
|
127
|
+
return f"mysql+mysqldb://{user}:{password}@{host}:{port}/{database}"
|
|
128
|
+
if package_name == "mysql-connector-python":
|
|
129
|
+
return f"mysql+mysqlconnector://{user}:{password}@{host}:{port}/{database}"
|
|
130
|
+
|
|
131
|
+
return None
|
|
132
|
+
|
|
133
|
+
def get_postgresql_connection_string(
|
|
134
|
+
self, host: str, database: str, user: str, password: str, port: int = 5432
|
|
135
|
+
) -> Optional[str]:
|
|
136
|
+
"""
|
|
137
|
+
Get a SQLAlchemy connection string for PostgreSQL with automatic driver selection.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
host: Database host
|
|
141
|
+
database: Database name
|
|
142
|
+
user: Username
|
|
143
|
+
password: Password
|
|
144
|
+
port: Port number (default 5432)
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
SQLAlchemy connection string or None if no driver available
|
|
148
|
+
"""
|
|
149
|
+
if "postgresql" not in self.available_drivers:
|
|
150
|
+
logger.error(
|
|
151
|
+
"No PostgreSQL driver available. Install one of: psycopg2-binary, psycopg2, or pg8000"
|
|
152
|
+
)
|
|
153
|
+
return None
|
|
154
|
+
|
|
155
|
+
package_name, _ = self.available_drivers["postgresql"]
|
|
156
|
+
|
|
157
|
+
# Format connection string based on driver
|
|
158
|
+
if package_name in ["psycopg2-binary", "psycopg2"]:
|
|
159
|
+
return f"postgresql+psycopg2://{user}:{password}@{host}:{port}/{database}"
|
|
160
|
+
if package_name == "pg8000":
|
|
161
|
+
return f"postgresql+pg8000://{user}:{password}@{host}:{port}/{database}"
|
|
162
|
+
|
|
163
|
+
return None
|
|
164
|
+
|
|
165
|
+
def get_oracle_connection_string(
|
|
166
|
+
self, host: str, database: str, user: str, password: str, port: int = 1521
|
|
167
|
+
) -> Optional[str]:
|
|
168
|
+
"""
|
|
169
|
+
Get a SQLAlchemy connection string for Oracle with automatic driver selection.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
host: Database host
|
|
173
|
+
database: Database name/SID
|
|
174
|
+
user: Username
|
|
175
|
+
password: Password
|
|
176
|
+
port: Port number (default 1521)
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
SQLAlchemy connection string or None if no driver available
|
|
180
|
+
"""
|
|
181
|
+
if "oracle" not in self.available_drivers:
|
|
182
|
+
logger.error(
|
|
183
|
+
"No Oracle driver available. Install one of: cx_Oracle or oracledb"
|
|
184
|
+
)
|
|
185
|
+
return None
|
|
186
|
+
|
|
187
|
+
package_name, _ = self.available_drivers["oracle"]
|
|
188
|
+
|
|
189
|
+
# Format connection string based on driver
|
|
190
|
+
if package_name == "cx_Oracle":
|
|
191
|
+
return f"oracle+cx_oracle://{user}:{password}@{host}:{port}/{database}"
|
|
192
|
+
if package_name == "oracledb":
|
|
193
|
+
return f"oracle+oracledb://{user}:{password}@{host}:{port}/{database}"
|
|
194
|
+
|
|
195
|
+
return None
|
|
196
|
+
|
|
197
|
+
def get_available_drivers(self) -> Dict[str, str]:
|
|
198
|
+
"""
|
|
199
|
+
Get a summary of available database drivers.
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
Dictionary mapping database type to driver package name
|
|
203
|
+
"""
|
|
204
|
+
return {
|
|
205
|
+
db_type: driver_info[0]
|
|
206
|
+
for db_type, driver_info in self.available_drivers.items()
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
def suggest_missing_drivers(self) -> Dict[str, str]:
|
|
210
|
+
"""
|
|
211
|
+
Suggest drivers to install for databases without drivers.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
Dictionary mapping database type to recommended package
|
|
215
|
+
"""
|
|
216
|
+
suggestions = {}
|
|
217
|
+
|
|
218
|
+
if "mysql" not in self.available_drivers:
|
|
219
|
+
suggestions["mysql"] = "pymysql" # Pure Python, always works
|
|
220
|
+
|
|
221
|
+
if "postgresql" not in self.available_drivers:
|
|
222
|
+
suggestions["postgresql"] = "psycopg2-binary" # No compilation needed
|
|
223
|
+
|
|
224
|
+
if "oracle" not in self.available_drivers:
|
|
225
|
+
suggestions["oracle"] = "oracledb" # Pure Python, newer
|
|
226
|
+
|
|
227
|
+
return suggestions
|
|
228
|
+
|
|
229
|
+
@staticmethod
|
|
230
|
+
def get_installation_help() -> str:
|
|
231
|
+
"""
|
|
232
|
+
Get helpful installation instructions for database drivers.
|
|
233
|
+
|
|
234
|
+
Returns:
|
|
235
|
+
Formatted help text
|
|
236
|
+
"""
|
|
237
|
+
return """
|
|
238
|
+
Database Driver Installation Help
|
|
239
|
+
=================================
|
|
240
|
+
|
|
241
|
+
For MySQL:
|
|
242
|
+
Recommended: pip install pymysql (pure Python, no compilation)
|
|
243
|
+
Alternative: pip install mysql-connector-python (Oracle's pure Python)
|
|
244
|
+
Fastest (requires MySQL dev headers):
|
|
245
|
+
macOS: brew install mysql && pip install mysqlclient
|
|
246
|
+
Ubuntu: sudo apt-get install libmysqlclient-dev && pip install mysqlclient
|
|
247
|
+
|
|
248
|
+
For PostgreSQL:
|
|
249
|
+
Recommended: pip install psycopg2-binary (pre-compiled, no headers needed)
|
|
250
|
+
Alternative: pip install pg8000 (pure Python, slightly slower)
|
|
251
|
+
Fastest (requires PostgreSQL dev headers):
|
|
252
|
+
macOS: brew install postgresql && pip install psycopg2
|
|
253
|
+
Ubuntu: sudo apt-get install libpq-dev && pip install psycopg2
|
|
254
|
+
|
|
255
|
+
For Oracle:
|
|
256
|
+
Recommended: pip install oracledb (pure Python, no Oracle client needed)
|
|
257
|
+
Alternative (requires Oracle Instant Client):
|
|
258
|
+
1. Download Oracle Instant Client from oracle.com
|
|
259
|
+
2. Set environment variables (LD_LIBRARY_PATH, etc.)
|
|
260
|
+
3. pip install cx_Oracle
|
|
261
|
+
|
|
262
|
+
Note: Pure Python drivers are slightly slower but much easier to install
|
|
263
|
+
and maintain. They're recommended unless you have specific performance needs.
|
|
264
|
+
"""
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def test_database_connectivity() -> None:
|
|
268
|
+
"""
|
|
269
|
+
Test database connectivity and report available drivers.
|
|
270
|
+
|
|
271
|
+
WHY: Helps users understand what database drivers are available and
|
|
272
|
+
what they might need to install.
|
|
273
|
+
"""
|
|
274
|
+
connector = DatabaseConnector()
|
|
275
|
+
|
|
276
|
+
print("Database Driver Status")
|
|
277
|
+
print("=" * 50)
|
|
278
|
+
|
|
279
|
+
available = connector.get_available_drivers()
|
|
280
|
+
if available:
|
|
281
|
+
print("\nAvailable Drivers:")
|
|
282
|
+
for db_type, driver in available.items():
|
|
283
|
+
print(f" {db_type:12} -> {driver}")
|
|
284
|
+
else:
|
|
285
|
+
print("\nNo database drivers found!")
|
|
286
|
+
|
|
287
|
+
suggestions = connector.suggest_missing_drivers()
|
|
288
|
+
if suggestions:
|
|
289
|
+
print("\nRecommended installations for missing drivers:")
|
|
290
|
+
for db_type, package in suggestions.items():
|
|
291
|
+
print(f" {db_type:12} -> pip install {package}")
|
|
292
|
+
|
|
293
|
+
print("\n" + connector.get_installation_help())
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
if __name__ == "__main__":
|
|
297
|
+
# Run connectivity test when module is executed directly
|
|
298
|
+
test_database_connectivity()
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Dependency caching system for smart dependency checking.
|
|
5
|
+
|
|
6
|
+
This module provides caching for dependency check results to avoid
|
|
7
|
+
redundant checks and improve startup performance.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import hashlib
|
|
11
|
+
import json
|
|
12
|
+
import time
|
|
13
|
+
from typing import Dict, Optional, Tuple
|
|
14
|
+
|
|
15
|
+
from ..core.logger import get_logger
|
|
16
|
+
|
|
17
|
+
logger = get_logger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class DependencyCache:
|
|
21
|
+
"""
|
|
22
|
+
Manages caching of dependency check results.
|
|
23
|
+
|
|
24
|
+
WHY: Dependency checking can be slow, especially when checking many packages.
|
|
25
|
+
By caching results keyed by deployment hash, we can skip checks when nothing
|
|
26
|
+
has changed, significantly improving startup time.
|
|
27
|
+
|
|
28
|
+
DESIGN DECISION: We use a file-based cache in .claude/agents/.dependency_cache
|
|
29
|
+
- Simple JSON format for easy debugging
|
|
30
|
+
- TTL-based expiration (24 hours default)
|
|
31
|
+
- Automatic invalidation when agent deployment changes
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
DEFAULT_TTL_SECONDS = 86400 # 24 hours
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self, cache_dir: Optional[Path] = None, ttl_seconds: int = DEFAULT_TTL_SECONDS
|
|
38
|
+
):
|
|
39
|
+
"""
|
|
40
|
+
Initialize the dependency cache.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
cache_dir: Directory for cache files (default: .claude/agents/)
|
|
44
|
+
ttl_seconds: Time-to-live for cache entries in seconds
|
|
45
|
+
"""
|
|
46
|
+
if cache_dir is None:
|
|
47
|
+
cache_dir = Path.cwd() / ".claude" / "agents"
|
|
48
|
+
|
|
49
|
+
self.cache_dir = cache_dir
|
|
50
|
+
self.cache_file = self.cache_dir / ".dependency_cache"
|
|
51
|
+
self.ttl_seconds = ttl_seconds
|
|
52
|
+
self._cache_data: Optional[Dict] = None
|
|
53
|
+
|
|
54
|
+
def _load_cache(self) -> Dict:
|
|
55
|
+
"""
|
|
56
|
+
Load cache data from disk.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
Cache data dictionary or empty dict if not found.
|
|
60
|
+
"""
|
|
61
|
+
if self._cache_data is not None:
|
|
62
|
+
return self._cache_data
|
|
63
|
+
|
|
64
|
+
if not self.cache_file.exists():
|
|
65
|
+
self._cache_data = {}
|
|
66
|
+
return self._cache_data
|
|
67
|
+
|
|
68
|
+
try:
|
|
69
|
+
with self.cache_file.open() as f:
|
|
70
|
+
self._cache_data = json.load(f)
|
|
71
|
+
return self._cache_data
|
|
72
|
+
except Exception as e:
|
|
73
|
+
logger.debug(f"Could not load dependency cache: {e}")
|
|
74
|
+
self._cache_data = {}
|
|
75
|
+
return self._cache_data
|
|
76
|
+
|
|
77
|
+
def _save_cache(self, cache_data: Dict) -> None:
|
|
78
|
+
"""
|
|
79
|
+
Save cache data to disk.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
cache_data: Cache data to save.
|
|
83
|
+
"""
|
|
84
|
+
try:
|
|
85
|
+
# Ensure directory exists
|
|
86
|
+
self.cache_dir.mkdir(parents=True, exist_ok=True)
|
|
87
|
+
|
|
88
|
+
with self.cache_file.open("w") as f:
|
|
89
|
+
json.dump(cache_data, f, indent=2)
|
|
90
|
+
|
|
91
|
+
self._cache_data = cache_data
|
|
92
|
+
except Exception as e:
|
|
93
|
+
logger.debug(f"Could not save dependency cache: {e}")
|
|
94
|
+
|
|
95
|
+
def _generate_cache_key(self, deployment_hash: str, context: Dict) -> str:
|
|
96
|
+
"""
|
|
97
|
+
Generate a cache key for dependency results.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
deployment_hash: Hash of the current agent deployment
|
|
101
|
+
context: Additional context (e.g., Python version, platform)
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
Cache key string.
|
|
105
|
+
|
|
106
|
+
WHY: We include context like Python version because dependency
|
|
107
|
+
availability can vary between Python versions.
|
|
108
|
+
"""
|
|
109
|
+
# Include important context in the cache key
|
|
110
|
+
import platform
|
|
111
|
+
import sys
|
|
112
|
+
|
|
113
|
+
key_parts = [
|
|
114
|
+
deployment_hash,
|
|
115
|
+
f"py{sys.version_info.major}.{sys.version_info.minor}",
|
|
116
|
+
platform.system().lower(),
|
|
117
|
+
platform.machine().lower(),
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
# Add any additional context
|
|
121
|
+
for key, value in sorted(context.items()):
|
|
122
|
+
key_parts.append(f"{key}:{value}")
|
|
123
|
+
|
|
124
|
+
# Create a hash of all parts for a compact key
|
|
125
|
+
key_string = "|".join(key_parts)
|
|
126
|
+
return hashlib.md5(key_string.encode()).hexdigest()
|
|
127
|
+
|
|
128
|
+
def get(
|
|
129
|
+
self, deployment_hash: str, context: Optional[Dict] = None
|
|
130
|
+
) -> Optional[Dict]:
|
|
131
|
+
"""
|
|
132
|
+
Get cached dependency check results.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
deployment_hash: Hash of the current agent deployment
|
|
136
|
+
context: Additional context for cache key
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
Cached results or None if not found/expired.
|
|
140
|
+
"""
|
|
141
|
+
if context is None:
|
|
142
|
+
context = {}
|
|
143
|
+
|
|
144
|
+
cache_data = self._load_cache()
|
|
145
|
+
cache_key = self._generate_cache_key(deployment_hash, context)
|
|
146
|
+
|
|
147
|
+
if cache_key not in cache_data:
|
|
148
|
+
logger.debug(f"Cache miss for key {cache_key}")
|
|
149
|
+
return None
|
|
150
|
+
|
|
151
|
+
entry = cache_data[cache_key]
|
|
152
|
+
|
|
153
|
+
# Check if entry has expired
|
|
154
|
+
current_time = time.time()
|
|
155
|
+
if current_time - entry.get("timestamp", 0) > self.ttl_seconds:
|
|
156
|
+
logger.debug(f"Cache entry expired for key {cache_key}")
|
|
157
|
+
# Remove expired entry
|
|
158
|
+
del cache_data[cache_key]
|
|
159
|
+
self._save_cache(cache_data)
|
|
160
|
+
return None
|
|
161
|
+
|
|
162
|
+
logger.debug(f"Cache hit for key {cache_key}")
|
|
163
|
+
return entry.get("results")
|
|
164
|
+
|
|
165
|
+
def set(
|
|
166
|
+
self, deployment_hash: str, results: Dict, context: Optional[Dict] = None
|
|
167
|
+
) -> None:
|
|
168
|
+
"""
|
|
169
|
+
Cache dependency check results.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
deployment_hash: Hash of the current agent deployment
|
|
173
|
+
results: Dependency check results to cache
|
|
174
|
+
context: Additional context for cache key
|
|
175
|
+
"""
|
|
176
|
+
if context is None:
|
|
177
|
+
context = {}
|
|
178
|
+
|
|
179
|
+
cache_data = self._load_cache()
|
|
180
|
+
cache_key = self._generate_cache_key(deployment_hash, context)
|
|
181
|
+
|
|
182
|
+
# Store with timestamp
|
|
183
|
+
cache_data[cache_key] = {
|
|
184
|
+
"timestamp": time.time(),
|
|
185
|
+
"results": results,
|
|
186
|
+
"deployment_hash": deployment_hash,
|
|
187
|
+
"context": context,
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
# Clean up old entries while we're at it
|
|
191
|
+
self._cleanup_expired_entries(cache_data)
|
|
192
|
+
|
|
193
|
+
self._save_cache(cache_data)
|
|
194
|
+
logger.debug(f"Cached results for key {cache_key}")
|
|
195
|
+
|
|
196
|
+
def invalidate(self, deployment_hash: Optional[str] = None) -> None:
|
|
197
|
+
"""
|
|
198
|
+
Invalidate cache entries.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
deployment_hash: If provided, only invalidate entries for this hash.
|
|
202
|
+
If None, invalidate all entries.
|
|
203
|
+
"""
|
|
204
|
+
if deployment_hash is None:
|
|
205
|
+
# Clear entire cache
|
|
206
|
+
self._cache_data = {}
|
|
207
|
+
self._save_cache({})
|
|
208
|
+
logger.info("Cleared entire dependency cache")
|
|
209
|
+
else:
|
|
210
|
+
# Clear entries for specific deployment
|
|
211
|
+
cache_data = self._load_cache()
|
|
212
|
+
keys_to_remove = []
|
|
213
|
+
|
|
214
|
+
for key, entry in cache_data.items():
|
|
215
|
+
if entry.get("deployment_hash") == deployment_hash:
|
|
216
|
+
keys_to_remove.append(key)
|
|
217
|
+
|
|
218
|
+
for key in keys_to_remove:
|
|
219
|
+
del cache_data[key]
|
|
220
|
+
|
|
221
|
+
if keys_to_remove:
|
|
222
|
+
self._save_cache(cache_data)
|
|
223
|
+
logger.info(
|
|
224
|
+
f"Invalidated {len(keys_to_remove)} cache entries for deployment {deployment_hash[:8]}..."
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
def _cleanup_expired_entries(self, cache_data: Dict) -> None:
|
|
228
|
+
"""
|
|
229
|
+
Remove expired entries from cache data.
|
|
230
|
+
|
|
231
|
+
Args:
|
|
232
|
+
cache_data: Cache data dictionary to clean.
|
|
233
|
+
|
|
234
|
+
WHY: We clean up expired entries periodically to prevent the cache
|
|
235
|
+
from growing indefinitely.
|
|
236
|
+
"""
|
|
237
|
+
current_time = time.time()
|
|
238
|
+
keys_to_remove = []
|
|
239
|
+
|
|
240
|
+
for key, entry in cache_data.items():
|
|
241
|
+
if current_time - entry.get("timestamp", 0) > self.ttl_seconds:
|
|
242
|
+
keys_to_remove.append(key)
|
|
243
|
+
|
|
244
|
+
for key in keys_to_remove:
|
|
245
|
+
del cache_data[key]
|
|
246
|
+
|
|
247
|
+
if keys_to_remove:
|
|
248
|
+
logger.debug(f"Cleaned up {len(keys_to_remove)} expired cache entries")
|
|
249
|
+
|
|
250
|
+
def get_cache_stats(self) -> Dict:
|
|
251
|
+
"""
|
|
252
|
+
Get statistics about the cache.
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
Dictionary with cache statistics.
|
|
256
|
+
"""
|
|
257
|
+
cache_data = self._load_cache()
|
|
258
|
+
current_time = time.time()
|
|
259
|
+
|
|
260
|
+
total_entries = len(cache_data)
|
|
261
|
+
expired_entries = 0
|
|
262
|
+
valid_entries = 0
|
|
263
|
+
|
|
264
|
+
for entry in cache_data.values():
|
|
265
|
+
if current_time - entry.get("timestamp", 0) > self.ttl_seconds:
|
|
266
|
+
expired_entries += 1
|
|
267
|
+
else:
|
|
268
|
+
valid_entries += 1
|
|
269
|
+
|
|
270
|
+
return {
|
|
271
|
+
"total_entries": total_entries,
|
|
272
|
+
"valid_entries": valid_entries,
|
|
273
|
+
"expired_entries": expired_entries,
|
|
274
|
+
"cache_file": str(self.cache_file),
|
|
275
|
+
"ttl_seconds": self.ttl_seconds,
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
def clear(self) -> None:
|
|
279
|
+
"""
|
|
280
|
+
Clear all cache entries.
|
|
281
|
+
"""
|
|
282
|
+
self.invalidate(None)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
class SmartDependencyChecker:
|
|
286
|
+
"""
|
|
287
|
+
Combines caching with agent dependency checking for smart, efficient checks.
|
|
288
|
+
|
|
289
|
+
WHY: This class orchestrates the smart dependency checking by combining:
|
|
290
|
+
- Change detection (only check when agents change)
|
|
291
|
+
- Caching (reuse results when nothing has changed)
|
|
292
|
+
- Environment awareness (only prompt in appropriate contexts)
|
|
293
|
+
"""
|
|
294
|
+
|
|
295
|
+
def __init__(self, cache_ttl_seconds: int = DependencyCache.DEFAULT_TTL_SECONDS):
|
|
296
|
+
"""
|
|
297
|
+
Initialize the smart dependency checker.
|
|
298
|
+
|
|
299
|
+
Args:
|
|
300
|
+
cache_ttl_seconds: TTL for cache entries.
|
|
301
|
+
"""
|
|
302
|
+
self.cache = DependencyCache(ttl_seconds=cache_ttl_seconds)
|
|
303
|
+
self._last_check_time = 0
|
|
304
|
+
self._min_check_interval = 60 # Don't check more than once per minute
|
|
305
|
+
|
|
306
|
+
def should_check_dependencies(
|
|
307
|
+
self, force_check: bool = False, deployment_hash: Optional[str] = None
|
|
308
|
+
) -> Tuple[bool, str]:
|
|
309
|
+
"""
|
|
310
|
+
Determine if dependency checking should be performed.
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
force_check: Force checking regardless of cache/changes
|
|
314
|
+
deployment_hash: Current deployment hash
|
|
315
|
+
|
|
316
|
+
Returns:
|
|
317
|
+
Tuple of (should_check, reason)
|
|
318
|
+
"""
|
|
319
|
+
if force_check:
|
|
320
|
+
return True, "Forced check requested"
|
|
321
|
+
|
|
322
|
+
# Rate limiting - don't check too frequently
|
|
323
|
+
current_time = time.time()
|
|
324
|
+
if current_time - self._last_check_time < self._min_check_interval:
|
|
325
|
+
return False, f"Checked recently (within {self._min_check_interval}s)"
|
|
326
|
+
|
|
327
|
+
# Check if we have valid cached results
|
|
328
|
+
if deployment_hash:
|
|
329
|
+
cached_results = self.cache.get(deployment_hash)
|
|
330
|
+
if cached_results:
|
|
331
|
+
return False, "Valid cached results available"
|
|
332
|
+
|
|
333
|
+
return True, "No valid cache, checking needed"
|
|
334
|
+
|
|
335
|
+
def get_or_check_dependencies(
|
|
336
|
+
self,
|
|
337
|
+
loader,
|
|
338
|
+
force_check: bool = False, # AgentDependencyLoader instance
|
|
339
|
+
) -> Tuple[Dict, bool]:
|
|
340
|
+
"""
|
|
341
|
+
Get dependency results from cache or perform check.
|
|
342
|
+
|
|
343
|
+
Args:
|
|
344
|
+
loader: AgentDependencyLoader instance
|
|
345
|
+
force_check: Force checking even if cached
|
|
346
|
+
|
|
347
|
+
Returns:
|
|
348
|
+
Tuple of (results, was_cached)
|
|
349
|
+
"""
|
|
350
|
+
# Check if agents have changed
|
|
351
|
+
has_changed, deployment_hash = loader.has_agents_changed()
|
|
352
|
+
|
|
353
|
+
# Try to get cached results first
|
|
354
|
+
if not force_check and not has_changed:
|
|
355
|
+
cached_results = self.cache.get(deployment_hash)
|
|
356
|
+
if cached_results:
|
|
357
|
+
logger.info("Using cached dependency check results")
|
|
358
|
+
return cached_results, True
|
|
359
|
+
|
|
360
|
+
# Perform actual dependency check
|
|
361
|
+
logger.info("Performing dependency check...")
|
|
362
|
+
results = loader.load_and_check()
|
|
363
|
+
|
|
364
|
+
# Cache the results
|
|
365
|
+
self.cache.set(deployment_hash, results)
|
|
366
|
+
|
|
367
|
+
# Mark deployment as checked
|
|
368
|
+
loader.mark_deployment_checked(deployment_hash, results)
|
|
369
|
+
|
|
370
|
+
# Update last check time
|
|
371
|
+
self._last_check_time = time.time()
|
|
372
|
+
|
|
373
|
+
return results, False
|