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
claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py}
RENAMED
|
@@ -23,33 +23,35 @@ combining all functionality into a single module for better maintainability.
|
|
|
23
23
|
import asyncio
|
|
24
24
|
import hashlib
|
|
25
25
|
import json
|
|
26
|
-
import logging
|
|
27
|
-
import os
|
|
28
26
|
import shutil
|
|
29
27
|
import time
|
|
30
28
|
import uuid
|
|
31
|
-
from dataclasses import dataclass, field
|
|
32
|
-
from datetime import datetime
|
|
29
|
+
from dataclasses import asdict, dataclass, field
|
|
30
|
+
from datetime import datetime, timezone
|
|
33
31
|
from enum import Enum
|
|
34
32
|
from pathlib import Path
|
|
35
|
-
from typing import Dict, List, Optional,
|
|
33
|
+
from typing import Any, Callable, Dict, List, Optional, Set, Tuple
|
|
36
34
|
|
|
35
|
+
from watchdog.events import FileSystemEvent, FileSystemEventHandler
|
|
37
36
|
from watchdog.observers import Observer
|
|
38
|
-
from watchdog.events import FileSystemEventHandler, FileSystemEvent
|
|
39
37
|
|
|
40
38
|
from claude_mpm.core.base_service import BaseService
|
|
41
|
-
from claude_mpm.
|
|
42
|
-
from claude_mpm.
|
|
43
|
-
from claude_mpm.
|
|
44
|
-
from claude_mpm.
|
|
39
|
+
from claude_mpm.core.enums import OperationResult
|
|
40
|
+
from claude_mpm.core.logging_utils import get_logger
|
|
41
|
+
from claude_mpm.core.unified_agent_registry import UnifiedAgentRegistry as AgentRegistry
|
|
42
|
+
from claude_mpm.core.unified_paths import get_path_manager
|
|
43
|
+
from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCache
|
|
45
44
|
|
|
45
|
+
logger = get_logger(__name__)
|
|
46
46
|
|
|
47
47
|
# ============================================================================
|
|
48
48
|
# Data Models
|
|
49
49
|
# ============================================================================
|
|
50
50
|
|
|
51
|
+
|
|
51
52
|
class ModificationType(Enum):
|
|
52
53
|
"""Types of agent modifications."""
|
|
54
|
+
|
|
53
55
|
CREATE = "create"
|
|
54
56
|
MODIFY = "modify"
|
|
55
57
|
DELETE = "delete"
|
|
@@ -59,6 +61,7 @@ class ModificationType(Enum):
|
|
|
59
61
|
|
|
60
62
|
class ModificationTier(Enum):
|
|
61
63
|
"""Agent hierarchy tiers for modification tracking."""
|
|
64
|
+
|
|
62
65
|
PROJECT = "project"
|
|
63
66
|
USER = "user"
|
|
64
67
|
SYSTEM = "system"
|
|
@@ -67,7 +70,7 @@ class ModificationTier(Enum):
|
|
|
67
70
|
@dataclass
|
|
68
71
|
class AgentModification:
|
|
69
72
|
"""Agent modification record with comprehensive metadata."""
|
|
70
|
-
|
|
73
|
+
|
|
71
74
|
modification_id: str
|
|
72
75
|
agent_name: str
|
|
73
76
|
modification_type: ModificationType
|
|
@@ -85,58 +88,60 @@ class AgentModification:
|
|
|
85
88
|
validation_errors: List[str] = field(default_factory=list)
|
|
86
89
|
related_modifications: List[str] = field(default_factory=list)
|
|
87
90
|
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
88
|
-
|
|
91
|
+
|
|
89
92
|
@property
|
|
90
93
|
def modification_datetime(self) -> datetime:
|
|
91
94
|
"""Get modification timestamp as datetime."""
|
|
92
|
-
return datetime.fromtimestamp(self.timestamp)
|
|
93
|
-
|
|
95
|
+
return datetime.fromtimestamp(self.timestamp, tz=timezone.utc)
|
|
96
|
+
|
|
94
97
|
@property
|
|
95
98
|
def age_seconds(self) -> float:
|
|
96
99
|
"""Get age of modification in seconds."""
|
|
97
100
|
return time.time() - self.timestamp
|
|
98
|
-
|
|
101
|
+
|
|
99
102
|
def to_dict(self) -> Dict[str, Any]:
|
|
100
103
|
"""Convert to dictionary for serialization."""
|
|
101
104
|
data = asdict(self)
|
|
102
|
-
data[
|
|
103
|
-
data[
|
|
105
|
+
data["modification_type"] = self.modification_type.value
|
|
106
|
+
data["tier"] = self.tier.value
|
|
104
107
|
return data
|
|
105
|
-
|
|
108
|
+
|
|
106
109
|
@classmethod
|
|
107
|
-
def from_dict(cls, data: Dict[str, Any]) ->
|
|
110
|
+
def from_dict(cls, data: Dict[str, Any]) -> "AgentModification":
|
|
108
111
|
"""Create from dictionary."""
|
|
109
|
-
data[
|
|
110
|
-
data[
|
|
112
|
+
data["modification_type"] = ModificationType(data["modification_type"])
|
|
113
|
+
data["tier"] = ModificationTier(data["tier"])
|
|
111
114
|
return cls(**data)
|
|
112
115
|
|
|
113
116
|
|
|
114
117
|
@dataclass
|
|
115
118
|
class ModificationHistory:
|
|
116
119
|
"""Complete modification history for an agent."""
|
|
117
|
-
|
|
120
|
+
|
|
118
121
|
agent_name: str
|
|
119
122
|
modifications: List[AgentModification] = field(default_factory=list)
|
|
120
123
|
current_version: Optional[str] = None
|
|
121
124
|
total_modifications: int = 0
|
|
122
125
|
first_seen: Optional[float] = None
|
|
123
126
|
last_modified: Optional[float] = None
|
|
124
|
-
|
|
127
|
+
|
|
125
128
|
def add_modification(self, modification: AgentModification) -> None:
|
|
126
129
|
"""Add a modification to history."""
|
|
127
130
|
self.modifications.append(modification)
|
|
128
131
|
self.total_modifications += 1
|
|
129
132
|
self.last_modified = modification.timestamp
|
|
130
|
-
|
|
133
|
+
|
|
131
134
|
if self.first_seen is None:
|
|
132
135
|
self.first_seen = modification.timestamp
|
|
133
|
-
|
|
136
|
+
|
|
134
137
|
def get_recent_modifications(self, hours: int = 24) -> List[AgentModification]:
|
|
135
138
|
"""Get modifications within specified hours."""
|
|
136
139
|
cutoff = time.time() - (hours * 3600)
|
|
137
140
|
return [mod for mod in self.modifications if mod.timestamp >= cutoff]
|
|
138
|
-
|
|
139
|
-
def get_modifications_by_type(
|
|
141
|
+
|
|
142
|
+
def get_modifications_by_type(
|
|
143
|
+
self, mod_type: ModificationType
|
|
144
|
+
) -> List[AgentModification]:
|
|
140
145
|
"""Get modifications by type."""
|
|
141
146
|
return [mod for mod in self.modifications if mod.modification_type == mod_type]
|
|
142
147
|
|
|
@@ -145,38 +150,59 @@ class ModificationHistory:
|
|
|
145
150
|
# File System Monitoring
|
|
146
151
|
# ============================================================================
|
|
147
152
|
|
|
153
|
+
|
|
148
154
|
class AgentFileSystemHandler(FileSystemEventHandler):
|
|
149
155
|
"""Handles file system events for agent files."""
|
|
150
|
-
|
|
151
|
-
def __init__(self, tracker:
|
|
156
|
+
|
|
157
|
+
def __init__(self, tracker: "AgentModificationTracker"):
|
|
152
158
|
self.tracker = tracker
|
|
153
|
-
|
|
154
|
-
|
|
159
|
+
|
|
160
|
+
def _create_tracked_task(self, coro):
|
|
161
|
+
"""Create a task with automatic tracking and cleanup."""
|
|
162
|
+
task = asyncio.create_task(coro)
|
|
163
|
+
self.tracker._file_event_tasks.add(task)
|
|
164
|
+
task.add_done_callback(self.tracker._file_event_tasks.discard)
|
|
165
|
+
return task
|
|
166
|
+
|
|
155
167
|
def on_created(self, event: FileSystemEvent) -> None:
|
|
156
168
|
"""Handle file creation events."""
|
|
157
|
-
if not event.is_directory and event.src_path.endswith(
|
|
158
|
-
|
|
159
|
-
|
|
169
|
+
if not event.is_directory and event.src_path.endswith(
|
|
170
|
+
(".md", ".json", ".yaml")
|
|
171
|
+
):
|
|
172
|
+
self._create_tracked_task(
|
|
173
|
+
self.tracker._handle_file_modification(
|
|
174
|
+
event.src_path, ModificationType.CREATE
|
|
175
|
+
)
|
|
160
176
|
)
|
|
161
|
-
|
|
177
|
+
|
|
162
178
|
def on_modified(self, event: FileSystemEvent) -> None:
|
|
163
179
|
"""Handle file modification events."""
|
|
164
|
-
if not event.is_directory and event.src_path.endswith(
|
|
165
|
-
|
|
166
|
-
|
|
180
|
+
if not event.is_directory and event.src_path.endswith(
|
|
181
|
+
(".md", ".json", ".yaml")
|
|
182
|
+
):
|
|
183
|
+
self._create_tracked_task(
|
|
184
|
+
self.tracker._handle_file_modification(
|
|
185
|
+
event.src_path, ModificationType.MODIFY
|
|
186
|
+
)
|
|
167
187
|
)
|
|
168
|
-
|
|
188
|
+
|
|
169
189
|
def on_deleted(self, event: FileSystemEvent) -> None:
|
|
170
190
|
"""Handle file deletion events."""
|
|
171
|
-
if not event.is_directory and event.src_path.endswith(
|
|
172
|
-
|
|
173
|
-
|
|
191
|
+
if not event.is_directory and event.src_path.endswith(
|
|
192
|
+
(".md", ".json", ".yaml")
|
|
193
|
+
):
|
|
194
|
+
self._create_tracked_task(
|
|
195
|
+
self.tracker._handle_file_modification(
|
|
196
|
+
event.src_path, ModificationType.DELETE
|
|
197
|
+
)
|
|
174
198
|
)
|
|
175
|
-
|
|
199
|
+
|
|
176
200
|
def on_moved(self, event: FileSystemEvent) -> None:
|
|
177
201
|
"""Handle file move events."""
|
|
178
|
-
if not event.is_directory and event.src_path.endswith(
|
|
179
|
-
|
|
202
|
+
if not event.is_directory and event.src_path.endswith(
|
|
203
|
+
(".md", ".json", ".yaml")
|
|
204
|
+
):
|
|
205
|
+
self._create_tracked_task(
|
|
180
206
|
self.tracker._handle_file_move(event.src_path, event.dest_path)
|
|
181
207
|
)
|
|
182
208
|
|
|
@@ -185,170 +211,184 @@ class AgentFileSystemHandler(FileSystemEventHandler):
|
|
|
185
211
|
# Main Service Class
|
|
186
212
|
# ============================================================================
|
|
187
213
|
|
|
214
|
+
|
|
188
215
|
class AgentModificationTracker(BaseService):
|
|
189
216
|
"""
|
|
190
217
|
Agent Modification Tracker - Comprehensive modification tracking and persistence system.
|
|
191
|
-
|
|
218
|
+
|
|
192
219
|
This consolidated service combines all functionality from the previous multi-file
|
|
193
220
|
implementation into a single, maintainable module.
|
|
194
221
|
"""
|
|
195
|
-
|
|
222
|
+
|
|
196
223
|
def __init__(self, config: Optional[Dict[str, Any]] = None):
|
|
197
224
|
"""Initialize the agent modification tracker."""
|
|
198
225
|
super().__init__("agent_modification_tracker", config)
|
|
199
|
-
|
|
226
|
+
|
|
200
227
|
# Configuration
|
|
201
228
|
self.enable_monitoring = self.get_config("enable_monitoring", True)
|
|
202
229
|
self.backup_enabled = self.get_config("backup_enabled", True)
|
|
203
230
|
self.max_history_days = self.get_config("max_history_days", 30)
|
|
204
231
|
self.validation_enabled = self.get_config("validation_enabled", True)
|
|
205
232
|
self.persistence_interval = self.get_config("persistence_interval", 300)
|
|
206
|
-
|
|
233
|
+
|
|
207
234
|
# Core components
|
|
208
235
|
self.shared_cache: Optional[SharedPromptCache] = None
|
|
209
236
|
self.agent_registry: Optional[AgentRegistry] = None
|
|
210
|
-
|
|
237
|
+
|
|
211
238
|
# Tracking data structures
|
|
212
239
|
self.modification_history: Dict[str, ModificationHistory] = {}
|
|
213
240
|
self.active_modifications: Dict[str, AgentModification] = {}
|
|
214
|
-
|
|
241
|
+
|
|
215
242
|
# File monitoring
|
|
216
243
|
self.file_observer: Optional[Observer] = None
|
|
217
244
|
self.watched_paths: Set[Path] = set()
|
|
218
|
-
|
|
245
|
+
|
|
219
246
|
# Persistence paths
|
|
220
|
-
self.persistence_root =
|
|
221
|
-
self.backup_root = self.persistence_root /
|
|
222
|
-
self.history_root = self.persistence_root /
|
|
223
|
-
|
|
247
|
+
self.persistence_root = get_path_manager().get_tracking_dir()
|
|
248
|
+
self.backup_root = self.persistence_root / "backups"
|
|
249
|
+
self.history_root = self.persistence_root / "history"
|
|
250
|
+
|
|
224
251
|
# Create directories
|
|
225
252
|
self.persistence_root.mkdir(parents=True, exist_ok=True)
|
|
226
253
|
self.backup_root.mkdir(parents=True, exist_ok=True)
|
|
227
254
|
self.history_root.mkdir(parents=True, exist_ok=True)
|
|
228
|
-
|
|
255
|
+
|
|
229
256
|
# Background tasks
|
|
230
257
|
self._persistence_task: Optional[asyncio.Task] = None
|
|
231
258
|
self._cleanup_task: Optional[asyncio.Task] = None
|
|
232
|
-
|
|
259
|
+
self._file_event_tasks: Set[asyncio.Task] = set() # Track file event tasks
|
|
260
|
+
|
|
233
261
|
# Callbacks
|
|
234
262
|
self.modification_callbacks: List[Callable[[AgentModification], None]] = []
|
|
235
|
-
|
|
263
|
+
|
|
236
264
|
self.logger.info(
|
|
237
265
|
f"AgentModificationTracker initialized with monitoring="
|
|
238
266
|
f"{'enabled' if self.enable_monitoring else 'disabled'}"
|
|
239
267
|
)
|
|
240
|
-
|
|
268
|
+
|
|
241
269
|
async def _initialize(self) -> None:
|
|
242
270
|
"""Initialize the modification tracker service."""
|
|
243
271
|
self.logger.info("Initializing AgentModificationTracker service...")
|
|
244
|
-
|
|
272
|
+
|
|
245
273
|
# Initialize cache and registry integration
|
|
246
274
|
await self._initialize_integrations()
|
|
247
|
-
|
|
275
|
+
|
|
248
276
|
# Load existing modification history
|
|
249
277
|
await self._load_modification_history()
|
|
250
|
-
|
|
278
|
+
|
|
251
279
|
# Set up file system monitoring
|
|
252
280
|
if self.enable_monitoring:
|
|
253
281
|
await self._setup_file_monitoring()
|
|
254
|
-
|
|
282
|
+
|
|
255
283
|
# Start background tasks
|
|
256
284
|
self._persistence_task = asyncio.create_task(self._persistence_loop())
|
|
257
285
|
self._cleanup_task = asyncio.create_task(self._cleanup_loop())
|
|
258
|
-
|
|
286
|
+
|
|
259
287
|
self.logger.info("AgentModificationTracker service initialized successfully")
|
|
260
|
-
|
|
288
|
+
|
|
261
289
|
async def _cleanup(self) -> None:
|
|
262
290
|
"""Cleanup modification tracker resources."""
|
|
263
291
|
self.logger.info("Cleaning up AgentModificationTracker service...")
|
|
264
|
-
|
|
292
|
+
|
|
265
293
|
# Stop file system monitoring
|
|
266
294
|
if self.enable_monitoring and self.file_observer:
|
|
267
295
|
self.file_observer.stop()
|
|
268
296
|
self.file_observer.join()
|
|
269
|
-
|
|
297
|
+
|
|
270
298
|
# Cancel background tasks
|
|
271
299
|
if self._persistence_task:
|
|
272
300
|
self._persistence_task.cancel()
|
|
273
301
|
if self._cleanup_task:
|
|
274
302
|
self._cleanup_task.cancel()
|
|
275
|
-
|
|
303
|
+
|
|
276
304
|
# Save final state
|
|
277
305
|
await self._save_modification_history()
|
|
278
|
-
|
|
306
|
+
|
|
279
307
|
self.logger.info("AgentModificationTracker service cleaned up")
|
|
280
|
-
|
|
308
|
+
|
|
281
309
|
async def _health_check(self) -> Dict[str, bool]:
|
|
282
310
|
"""Perform modification tracker health checks."""
|
|
283
311
|
checks = {}
|
|
284
|
-
|
|
312
|
+
|
|
285
313
|
try:
|
|
286
314
|
# Check persistence directories
|
|
287
|
-
checks["persistence_directories"] = all(
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
315
|
+
checks["persistence_directories"] = all(
|
|
316
|
+
[
|
|
317
|
+
self.persistence_root.exists(),
|
|
318
|
+
self.backup_root.exists(),
|
|
319
|
+
self.history_root.exists(),
|
|
320
|
+
]
|
|
321
|
+
)
|
|
322
|
+
|
|
293
323
|
# Check file system monitoring
|
|
294
324
|
checks["file_monitoring"] = (
|
|
295
|
-
self.file_observer is not None and
|
|
296
|
-
self.
|
|
297
|
-
|
|
298
|
-
|
|
325
|
+
(self.file_observer is not None and self.file_observer.is_alive())
|
|
326
|
+
if self.enable_monitoring
|
|
327
|
+
else True
|
|
328
|
+
)
|
|
329
|
+
|
|
299
330
|
# Check integration components
|
|
300
331
|
checks["cache_integration"] = self.shared_cache is not None
|
|
301
332
|
checks["registry_integration"] = self.agent_registry is not None
|
|
302
|
-
|
|
333
|
+
|
|
303
334
|
# Check background tasks
|
|
304
335
|
checks["persistence_task"] = (
|
|
305
|
-
self._persistence_task is not None and
|
|
306
|
-
not self._persistence_task.done()
|
|
336
|
+
self._persistence_task is not None and not self._persistence_task.done()
|
|
307
337
|
)
|
|
308
338
|
checks["cleanup_task"] = (
|
|
309
|
-
self._cleanup_task is not None and
|
|
310
|
-
not self._cleanup_task.done()
|
|
339
|
+
self._cleanup_task is not None and not self._cleanup_task.done()
|
|
311
340
|
)
|
|
312
|
-
|
|
341
|
+
|
|
313
342
|
checks["modification_tracking"] = True
|
|
314
|
-
|
|
343
|
+
|
|
315
344
|
except Exception as e:
|
|
316
345
|
self.logger.error(f"Modification tracker health check failed: {e}")
|
|
317
346
|
checks["health_check_error"] = False
|
|
318
|
-
|
|
347
|
+
|
|
319
348
|
return checks
|
|
320
|
-
|
|
349
|
+
|
|
321
350
|
# ========================================================================
|
|
322
351
|
# Core Functionality
|
|
323
352
|
# ========================================================================
|
|
324
|
-
|
|
325
|
-
async def track_modification(
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
353
|
+
|
|
354
|
+
async def track_modification(
|
|
355
|
+
self,
|
|
356
|
+
agent_name: str,
|
|
357
|
+
modification_type: ModificationType,
|
|
358
|
+
file_path: str,
|
|
359
|
+
tier: ModificationTier,
|
|
360
|
+
**kwargs,
|
|
361
|
+
) -> AgentModification:
|
|
331
362
|
"""Track an agent modification with comprehensive metadata collection."""
|
|
332
363
|
# Generate modification ID
|
|
333
|
-
modification_id =
|
|
334
|
-
|
|
364
|
+
modification_id = (
|
|
365
|
+
f"{agent_name}_{modification_type.value}_{uuid.uuid4().hex[:8]}"
|
|
366
|
+
)
|
|
367
|
+
|
|
335
368
|
# Collect file metadata
|
|
336
369
|
file_metadata = await self._collect_file_metadata(file_path, modification_type)
|
|
337
|
-
|
|
370
|
+
|
|
338
371
|
# Create backup if enabled
|
|
339
372
|
backup_path = None
|
|
340
|
-
if self.backup_enabled and modification_type in [
|
|
373
|
+
if self.backup_enabled and modification_type in [
|
|
374
|
+
ModificationType.MODIFY,
|
|
375
|
+
ModificationType.DELETE,
|
|
376
|
+
]:
|
|
341
377
|
backup_path = await self._create_backup(file_path, modification_id)
|
|
342
|
-
|
|
378
|
+
|
|
343
379
|
# Create modification record
|
|
344
380
|
# Only include valid AgentModification fields from file_metadata
|
|
345
|
-
valid_metadata_fields = {
|
|
346
|
-
filtered_metadata = {
|
|
347
|
-
|
|
381
|
+
valid_metadata_fields = {"file_hash_after", "file_size_after"}
|
|
382
|
+
filtered_metadata = {
|
|
383
|
+
k: v for k, v in file_metadata.items() if k in valid_metadata_fields
|
|
384
|
+
}
|
|
385
|
+
|
|
348
386
|
# Add other metadata to the metadata field
|
|
349
|
-
extra_metadata = {
|
|
387
|
+
extra_metadata = {
|
|
388
|
+
k: v for k, v in file_metadata.items() if k not in valid_metadata_fields
|
|
389
|
+
}
|
|
350
390
|
extra_metadata.update(kwargs)
|
|
351
|
-
|
|
391
|
+
|
|
352
392
|
modification = AgentModification(
|
|
353
393
|
modification_id=modification_id,
|
|
354
394
|
agent_name=agent_name,
|
|
@@ -358,39 +398,41 @@ class AgentModificationTracker(BaseService):
|
|
|
358
398
|
timestamp=time.time(),
|
|
359
399
|
backup_path=backup_path,
|
|
360
400
|
metadata=extra_metadata,
|
|
361
|
-
**filtered_metadata
|
|
401
|
+
**filtered_metadata,
|
|
362
402
|
)
|
|
363
|
-
|
|
403
|
+
|
|
364
404
|
# Validate modification if enabled
|
|
365
405
|
if self.validation_enabled:
|
|
366
406
|
await self._validate_modification(modification)
|
|
367
|
-
|
|
407
|
+
|
|
368
408
|
# Store in active modifications
|
|
369
409
|
self.active_modifications[modification_id] = modification
|
|
370
|
-
|
|
410
|
+
|
|
371
411
|
# Add to history
|
|
372
412
|
if agent_name not in self.modification_history:
|
|
373
|
-
self.modification_history[agent_name] = ModificationHistory(
|
|
374
|
-
|
|
413
|
+
self.modification_history[agent_name] = ModificationHistory(
|
|
414
|
+
agent_name=agent_name
|
|
415
|
+
)
|
|
416
|
+
|
|
375
417
|
self.modification_history[agent_name].add_modification(modification)
|
|
376
|
-
|
|
418
|
+
|
|
377
419
|
# Invalidate cache
|
|
378
420
|
if self.shared_cache:
|
|
379
421
|
await self._invalidate_agent_cache(agent_name)
|
|
380
|
-
|
|
422
|
+
|
|
381
423
|
# Trigger callbacks
|
|
382
424
|
await self._trigger_modification_callbacks(modification)
|
|
383
|
-
|
|
425
|
+
|
|
384
426
|
self.logger.info(
|
|
385
427
|
f"Tracked {modification_type.value} modification for agent '{agent_name}': {modification_id}"
|
|
386
428
|
)
|
|
387
|
-
|
|
429
|
+
|
|
388
430
|
return modification
|
|
389
|
-
|
|
431
|
+
|
|
390
432
|
# ========================================================================
|
|
391
433
|
# Helper Methods
|
|
392
434
|
# ========================================================================
|
|
393
|
-
|
|
435
|
+
|
|
394
436
|
async def _initialize_integrations(self) -> None:
|
|
395
437
|
"""Initialize cache and registry integrations."""
|
|
396
438
|
try:
|
|
@@ -399,115 +441,127 @@ class AgentModificationTracker(BaseService):
|
|
|
399
441
|
self.logger.info("Successfully initialized cache and registry integrations")
|
|
400
442
|
except Exception as e:
|
|
401
443
|
self.logger.warning(f"Failed to initialize integrations: {e}")
|
|
402
|
-
|
|
444
|
+
|
|
403
445
|
async def _setup_file_monitoring(self) -> None:
|
|
404
446
|
"""Set up file system monitoring for agent files."""
|
|
405
447
|
try:
|
|
406
448
|
self.file_observer = Observer()
|
|
407
449
|
event_handler = AgentFileSystemHandler(self)
|
|
408
|
-
|
|
450
|
+
|
|
409
451
|
# Monitor standard agent directories
|
|
410
452
|
agent_dirs = [
|
|
411
453
|
Path("agents"),
|
|
412
454
|
Path("src/claude_mpm/agents"),
|
|
413
|
-
|
|
455
|
+
get_path_manager().get_user_agents_dir(),
|
|
414
456
|
]
|
|
415
|
-
|
|
457
|
+
|
|
416
458
|
for agent_dir in agent_dirs:
|
|
417
459
|
if agent_dir.exists():
|
|
418
|
-
self.file_observer.schedule(
|
|
460
|
+
self.file_observer.schedule(
|
|
461
|
+
event_handler, str(agent_dir), recursive=True
|
|
462
|
+
)
|
|
419
463
|
self.watched_paths.add(agent_dir)
|
|
420
464
|
self.logger.info(f"Monitoring agent directory: {agent_dir}")
|
|
421
|
-
|
|
465
|
+
|
|
422
466
|
self.file_observer.start()
|
|
423
|
-
|
|
467
|
+
|
|
424
468
|
except Exception as e:
|
|
425
469
|
self.logger.error(f"Failed to setup file monitoring: {e}")
|
|
426
|
-
|
|
427
|
-
async def _collect_file_metadata(
|
|
470
|
+
|
|
471
|
+
async def _collect_file_metadata(
|
|
472
|
+
self, file_path: str, modification_type: ModificationType
|
|
473
|
+
) -> Dict[str, Any]:
|
|
428
474
|
"""Collect comprehensive file metadata."""
|
|
429
475
|
metadata = {}
|
|
430
|
-
|
|
476
|
+
|
|
431
477
|
try:
|
|
432
478
|
path = Path(file_path)
|
|
433
|
-
|
|
479
|
+
|
|
434
480
|
if path.exists() and modification_type != ModificationType.DELETE:
|
|
435
481
|
# File size
|
|
436
|
-
metadata[
|
|
437
|
-
|
|
482
|
+
metadata["file_size_after"] = path.stat().st_size
|
|
483
|
+
|
|
438
484
|
# File hash
|
|
439
|
-
with open(
|
|
440
|
-
metadata[
|
|
441
|
-
|
|
485
|
+
with path.open("rb") as f:
|
|
486
|
+
metadata["file_hash_after"] = hashlib.sha256(f.read()).hexdigest()
|
|
487
|
+
|
|
442
488
|
# File type
|
|
443
|
-
metadata[
|
|
444
|
-
|
|
489
|
+
metadata["file_type"] = path.suffix
|
|
490
|
+
|
|
445
491
|
# Modification time
|
|
446
|
-
metadata[
|
|
447
|
-
|
|
492
|
+
metadata["mtime"] = path.stat().st_mtime
|
|
493
|
+
|
|
448
494
|
except Exception as e:
|
|
449
495
|
self.logger.error(f"Error collecting file metadata: {e}")
|
|
450
|
-
|
|
496
|
+
|
|
451
497
|
return metadata
|
|
452
|
-
|
|
453
|
-
async def _create_backup(
|
|
498
|
+
|
|
499
|
+
async def _create_backup(
|
|
500
|
+
self, file_path: str, modification_id: str
|
|
501
|
+
) -> Optional[str]:
|
|
454
502
|
"""Create backup of agent file."""
|
|
455
503
|
try:
|
|
456
504
|
source = Path(file_path)
|
|
457
505
|
if not source.exists():
|
|
458
506
|
return None
|
|
459
|
-
|
|
507
|
+
|
|
460
508
|
# Create backup directory for this modification
|
|
461
509
|
backup_dir = self.backup_root / modification_id
|
|
462
510
|
backup_dir.mkdir(parents=True, exist_ok=True)
|
|
463
|
-
|
|
511
|
+
|
|
464
512
|
# Create backup file
|
|
465
513
|
backup_path = backup_dir / source.name
|
|
466
514
|
shutil.copy2(source, backup_path)
|
|
467
|
-
|
|
515
|
+
|
|
468
516
|
# Save backup metadata
|
|
469
517
|
metadata = {
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
518
|
+
"original_path": str(file_path),
|
|
519
|
+
"backup_time": time.time(),
|
|
520
|
+
"modification_id": modification_id,
|
|
473
521
|
}
|
|
474
|
-
|
|
475
|
-
metadata_path = backup_dir /
|
|
476
|
-
with open(
|
|
522
|
+
|
|
523
|
+
metadata_path = backup_dir / "metadata.json"
|
|
524
|
+
with metadata_path.open("w") as f:
|
|
477
525
|
json.dump(metadata, f, indent=2)
|
|
478
|
-
|
|
526
|
+
|
|
479
527
|
return str(backup_path)
|
|
480
|
-
|
|
528
|
+
|
|
481
529
|
except Exception as e:
|
|
482
530
|
self.logger.error(f"Failed to create backup: {e}")
|
|
483
531
|
return None
|
|
484
|
-
|
|
532
|
+
|
|
485
533
|
async def _validate_modification(self, modification: AgentModification) -> None:
|
|
486
534
|
"""Validate agent modification."""
|
|
487
535
|
errors = []
|
|
488
|
-
|
|
536
|
+
|
|
489
537
|
try:
|
|
490
538
|
# Check for conflicts
|
|
491
539
|
for mod_id, active_mod in self.active_modifications.items():
|
|
492
|
-
if (
|
|
493
|
-
active_mod.
|
|
494
|
-
active_mod.
|
|
495
|
-
|
|
496
|
-
|
|
540
|
+
if (
|
|
541
|
+
active_mod.agent_name == modification.agent_name
|
|
542
|
+
and active_mod.modification_id != modification.modification_id
|
|
543
|
+
and active_mod.age_seconds < 60
|
|
544
|
+
): # Recent modification
|
|
545
|
+
errors.append(
|
|
546
|
+
f"Potential conflict with recent modification: {mod_id}"
|
|
547
|
+
)
|
|
548
|
+
|
|
497
549
|
# Validate file path
|
|
498
550
|
if modification.modification_type != ModificationType.DELETE:
|
|
499
551
|
if not Path(modification.file_path).exists():
|
|
500
552
|
errors.append(f"File does not exist: {modification.file_path}")
|
|
501
|
-
|
|
553
|
+
|
|
502
554
|
# Update validation status
|
|
503
|
-
modification.validation_status =
|
|
555
|
+
modification.validation_status = (
|
|
556
|
+
OperationResult.FAILED if errors else OperationResult.SUCCESS
|
|
557
|
+
)
|
|
504
558
|
modification.validation_errors = errors
|
|
505
|
-
|
|
559
|
+
|
|
506
560
|
except Exception as e:
|
|
507
561
|
self.logger.error(f"Validation error: {e}")
|
|
508
|
-
modification.validation_status =
|
|
562
|
+
modification.validation_status = OperationResult.ERROR
|
|
509
563
|
modification.validation_errors.append(str(e))
|
|
510
|
-
|
|
564
|
+
|
|
511
565
|
async def _invalidate_agent_cache(self, agent_name: str) -> None:
|
|
512
566
|
"""Invalidate cache entries for modified agent."""
|
|
513
567
|
if self.shared_cache:
|
|
@@ -517,34 +571,36 @@ class AgentModificationTracker(BaseService):
|
|
|
517
571
|
self.logger.debug(f"Invalidated cache for agent: {agent_name}")
|
|
518
572
|
except Exception as e:
|
|
519
573
|
self.logger.error(f"Failed to invalidate cache: {e}")
|
|
520
|
-
|
|
521
|
-
async def _handle_file_modification(
|
|
574
|
+
|
|
575
|
+
async def _handle_file_modification(
|
|
576
|
+
self, file_path: str, modification_type: ModificationType
|
|
577
|
+
) -> None:
|
|
522
578
|
"""Handle file system modification events."""
|
|
523
579
|
try:
|
|
524
580
|
# Extract agent information from path
|
|
525
581
|
agent_info = self._extract_agent_info_from_path(file_path)
|
|
526
582
|
if not agent_info:
|
|
527
583
|
return
|
|
528
|
-
|
|
584
|
+
|
|
529
585
|
agent_name, tier = agent_info
|
|
530
|
-
|
|
586
|
+
|
|
531
587
|
# Track the modification
|
|
532
588
|
await self.track_modification(
|
|
533
589
|
agent_name=agent_name,
|
|
534
590
|
modification_type=modification_type,
|
|
535
591
|
file_path=file_path,
|
|
536
592
|
tier=tier,
|
|
537
|
-
source="file_system_monitor"
|
|
593
|
+
source="file_system_monitor",
|
|
538
594
|
)
|
|
539
|
-
|
|
595
|
+
|
|
540
596
|
except Exception as e:
|
|
541
597
|
self.logger.error(f"Error handling file modification {file_path}: {e}")
|
|
542
|
-
|
|
598
|
+
|
|
543
599
|
async def _handle_file_move(self, src_path: str, dest_path: str) -> None:
|
|
544
600
|
"""Handle file move events."""
|
|
545
601
|
try:
|
|
546
602
|
src_info = self._extract_agent_info_from_path(src_path)
|
|
547
|
-
|
|
603
|
+
|
|
548
604
|
if src_info:
|
|
549
605
|
agent_name, tier = src_info
|
|
550
606
|
await self.track_modification(
|
|
@@ -554,39 +610,48 @@ class AgentModificationTracker(BaseService):
|
|
|
554
610
|
tier=tier,
|
|
555
611
|
source="file_system_monitor",
|
|
556
612
|
move_source=src_path,
|
|
557
|
-
move_destination=dest_path
|
|
613
|
+
move_destination=dest_path,
|
|
558
614
|
)
|
|
559
|
-
|
|
615
|
+
|
|
560
616
|
except Exception as e:
|
|
561
|
-
self.logger.error(
|
|
562
|
-
|
|
563
|
-
|
|
617
|
+
self.logger.error(
|
|
618
|
+
f"Error handling file move {src_path} -> {dest_path}: {e}"
|
|
619
|
+
)
|
|
620
|
+
|
|
621
|
+
def _extract_agent_info_from_path(
|
|
622
|
+
self, file_path: str
|
|
623
|
+
) -> Optional[Tuple[str, ModificationTier]]:
|
|
564
624
|
"""Extract agent name and tier from file path."""
|
|
565
625
|
try:
|
|
566
626
|
path = Path(file_path)
|
|
567
|
-
|
|
627
|
+
|
|
568
628
|
# Extract agent name from filename
|
|
569
629
|
agent_name = path.stem
|
|
570
|
-
if agent_name.endswith(
|
|
630
|
+
if agent_name.endswith("_agent"):
|
|
571
631
|
agent_name = agent_name[:-6] # Remove _agent suffix
|
|
572
|
-
elif agent_name.endswith(
|
|
632
|
+
elif agent_name.endswith("-agent"):
|
|
573
633
|
agent_name = agent_name[:-6] # Remove -agent suffix
|
|
574
|
-
|
|
634
|
+
|
|
575
635
|
# Determine tier based on path
|
|
576
636
|
path_str = str(path).lower()
|
|
577
|
-
if
|
|
637
|
+
if "system" in path_str or "/claude_mpm/agents/" in path_str:
|
|
578
638
|
tier = ModificationTier.SYSTEM
|
|
579
|
-
elif
|
|
639
|
+
elif (
|
|
640
|
+
get_path_manager().CONFIG_DIR.lower() in path_str
|
|
641
|
+
or str(Path.home()) in path_str
|
|
642
|
+
):
|
|
580
643
|
tier = ModificationTier.USER
|
|
581
644
|
else:
|
|
582
645
|
tier = ModificationTier.PROJECT
|
|
583
|
-
|
|
646
|
+
|
|
584
647
|
return agent_name, tier
|
|
585
|
-
|
|
648
|
+
|
|
586
649
|
except Exception:
|
|
587
650
|
return None
|
|
588
|
-
|
|
589
|
-
async def _trigger_modification_callbacks(
|
|
651
|
+
|
|
652
|
+
async def _trigger_modification_callbacks(
|
|
653
|
+
self, modification: AgentModification
|
|
654
|
+
) -> None:
|
|
590
655
|
"""Trigger registered modification callbacks."""
|
|
591
656
|
for callback in self.modification_callbacks:
|
|
592
657
|
try:
|
|
@@ -596,78 +661,78 @@ class AgentModificationTracker(BaseService):
|
|
|
596
661
|
callback(modification)
|
|
597
662
|
except Exception as e:
|
|
598
663
|
self.logger.error(f"Modification callback failed: {e}")
|
|
599
|
-
|
|
664
|
+
|
|
600
665
|
# ========================================================================
|
|
601
666
|
# Persistence Methods
|
|
602
667
|
# ========================================================================
|
|
603
|
-
|
|
668
|
+
|
|
604
669
|
async def _load_modification_history(self) -> None:
|
|
605
670
|
"""Load modification history from disk."""
|
|
606
671
|
try:
|
|
607
672
|
# Load active modifications
|
|
608
|
-
active_path = self.persistence_root /
|
|
673
|
+
active_path = self.persistence_root / "active_modifications.json"
|
|
609
674
|
if active_path.exists():
|
|
610
|
-
with open(
|
|
675
|
+
with active_path.open() as f:
|
|
611
676
|
data = json.load(f)
|
|
612
677
|
self.active_modifications = {
|
|
613
678
|
k: AgentModification.from_dict(v) for k, v in data.items()
|
|
614
679
|
}
|
|
615
|
-
|
|
680
|
+
|
|
616
681
|
# Load modification history
|
|
617
|
-
for history_file in self.history_root.glob(
|
|
618
|
-
with open(
|
|
682
|
+
for history_file in self.history_root.glob("*.json"):
|
|
683
|
+
with history_file.open() as f:
|
|
619
684
|
data = json.load(f)
|
|
620
|
-
agent_name = data[
|
|
685
|
+
agent_name = data["agent_name"]
|
|
621
686
|
history = ModificationHistory(agent_name=agent_name)
|
|
622
|
-
|
|
687
|
+
|
|
623
688
|
# Recreate modifications
|
|
624
|
-
for mod_data in data.get(
|
|
689
|
+
for mod_data in data.get("modifications", []):
|
|
625
690
|
history.add_modification(AgentModification.from_dict(mod_data))
|
|
626
|
-
|
|
627
|
-
history.current_version = data.get(
|
|
628
|
-
history.first_seen = data.get(
|
|
629
|
-
history.last_modified = data.get(
|
|
630
|
-
|
|
691
|
+
|
|
692
|
+
history.current_version = data.get("current_version")
|
|
693
|
+
history.first_seen = data.get("first_seen")
|
|
694
|
+
history.last_modified = data.get("last_modified")
|
|
695
|
+
|
|
631
696
|
self.modification_history[agent_name] = history
|
|
632
|
-
|
|
697
|
+
|
|
633
698
|
self.logger.info(
|
|
634
699
|
f"Loaded {len(self.active_modifications)} active modifications and "
|
|
635
700
|
f"{len(self.modification_history)} agent histories"
|
|
636
701
|
)
|
|
637
|
-
|
|
702
|
+
|
|
638
703
|
except Exception as e:
|
|
639
704
|
self.logger.error(f"Failed to load modification history: {e}")
|
|
640
|
-
|
|
705
|
+
|
|
641
706
|
async def _save_modification_history(self) -> None:
|
|
642
707
|
"""Save modification history to disk."""
|
|
643
708
|
try:
|
|
644
709
|
# Save active modifications
|
|
645
710
|
active_data = {k: v.to_dict() for k, v in self.active_modifications.items()}
|
|
646
|
-
active_path = self.persistence_root /
|
|
647
|
-
|
|
648
|
-
with open(
|
|
711
|
+
active_path = self.persistence_root / "active_modifications.json"
|
|
712
|
+
|
|
713
|
+
with active_path.open("w") as f:
|
|
649
714
|
json.dump(active_data, f, indent=2)
|
|
650
|
-
|
|
715
|
+
|
|
651
716
|
# Save modification history
|
|
652
717
|
for agent_name, history in self.modification_history.items():
|
|
653
718
|
history_data = {
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
719
|
+
"agent_name": history.agent_name,
|
|
720
|
+
"modifications": [mod.to_dict() for mod in history.modifications],
|
|
721
|
+
"current_version": history.current_version,
|
|
722
|
+
"total_modifications": history.total_modifications,
|
|
723
|
+
"first_seen": history.first_seen,
|
|
724
|
+
"last_modified": history.last_modified,
|
|
660
725
|
}
|
|
661
|
-
|
|
726
|
+
|
|
662
727
|
history_path = self.history_root / f"{agent_name}_history.json"
|
|
663
|
-
with open(
|
|
728
|
+
with history_path.open("w") as f:
|
|
664
729
|
json.dump(history_data, f, indent=2)
|
|
665
|
-
|
|
730
|
+
|
|
666
731
|
self.logger.debug("Saved modification history to disk")
|
|
667
|
-
|
|
732
|
+
|
|
668
733
|
except Exception as e:
|
|
669
734
|
self.logger.error(f"Failed to save modification history: {e}")
|
|
670
|
-
|
|
735
|
+
|
|
671
736
|
async def _persistence_loop(self) -> None:
|
|
672
737
|
"""Background task to persist modification history."""
|
|
673
738
|
while not self._stop_event.is_set():
|
|
@@ -679,7 +744,7 @@ class AgentModificationTracker(BaseService):
|
|
|
679
744
|
except Exception as e:
|
|
680
745
|
self.logger.error(f"Persistence loop error: {e}")
|
|
681
746
|
await asyncio.sleep(self.persistence_interval)
|
|
682
|
-
|
|
747
|
+
|
|
683
748
|
async def _cleanup_loop(self) -> None:
|
|
684
749
|
"""Background task to cleanup old modifications and backups."""
|
|
685
750
|
while not self._stop_event.is_set():
|
|
@@ -691,159 +756,169 @@ class AgentModificationTracker(BaseService):
|
|
|
691
756
|
except Exception as e:
|
|
692
757
|
self.logger.error(f"Cleanup loop error: {e}")
|
|
693
758
|
await asyncio.sleep(3600)
|
|
694
|
-
|
|
759
|
+
|
|
695
760
|
async def _cleanup_old_data(self) -> None:
|
|
696
761
|
"""Clean up old modifications and backups."""
|
|
697
762
|
try:
|
|
698
763
|
cutoff_time = time.time() - (self.max_history_days * 24 * 3600)
|
|
699
|
-
|
|
764
|
+
|
|
700
765
|
# Clean up old modifications from active list
|
|
701
766
|
old_active = [
|
|
702
|
-
mod_id
|
|
767
|
+
mod_id
|
|
768
|
+
for mod_id, mod in self.active_modifications.items()
|
|
703
769
|
if mod.timestamp < cutoff_time
|
|
704
770
|
]
|
|
705
|
-
|
|
771
|
+
|
|
706
772
|
for mod_id in old_active:
|
|
707
773
|
del self.active_modifications[mod_id]
|
|
708
|
-
|
|
774
|
+
|
|
709
775
|
# Clean up old backups
|
|
710
776
|
backup_count = 0
|
|
711
777
|
for backup_dir in self.backup_root.iterdir():
|
|
712
778
|
if backup_dir.is_dir():
|
|
713
|
-
metadata_path = backup_dir /
|
|
779
|
+
metadata_path = backup_dir / "metadata.json"
|
|
714
780
|
if metadata_path.exists():
|
|
715
|
-
with open(
|
|
781
|
+
with metadata_path.open() as f:
|
|
716
782
|
metadata = json.load(f)
|
|
717
|
-
if metadata.get(
|
|
783
|
+
if metadata.get("backup_time", 0) < cutoff_time:
|
|
718
784
|
shutil.rmtree(backup_dir)
|
|
719
785
|
backup_count += 1
|
|
720
|
-
|
|
786
|
+
|
|
721
787
|
if old_active or backup_count > 0:
|
|
722
788
|
self.logger.info(
|
|
723
789
|
f"Cleaned up {len(old_active)} old modifications and {backup_count} old backups"
|
|
724
790
|
)
|
|
725
|
-
|
|
791
|
+
|
|
726
792
|
except Exception as e:
|
|
727
793
|
self.logger.error(f"Failed to cleanup old data: {e}")
|
|
728
|
-
|
|
794
|
+
|
|
729
795
|
# ========================================================================
|
|
730
796
|
# Public API Methods
|
|
731
797
|
# ========================================================================
|
|
732
|
-
|
|
733
|
-
async def get_modification_history(
|
|
798
|
+
|
|
799
|
+
async def get_modification_history(
|
|
800
|
+
self, agent_name: str
|
|
801
|
+
) -> Optional[ModificationHistory]:
|
|
734
802
|
"""Get modification history for specific agent."""
|
|
735
803
|
return self.modification_history.get(agent_name)
|
|
736
|
-
|
|
737
|
-
async def get_recent_modifications(
|
|
804
|
+
|
|
805
|
+
async def get_recent_modifications(
|
|
806
|
+
self, hours: int = 24
|
|
807
|
+
) -> List[AgentModification]:
|
|
738
808
|
"""Get all recent modifications across all agents."""
|
|
739
809
|
cutoff = time.time() - (hours * 3600)
|
|
740
810
|
recent = []
|
|
741
|
-
|
|
811
|
+
|
|
742
812
|
for history in self.modification_history.values():
|
|
743
|
-
recent.extend(
|
|
744
|
-
mod for mod in history.modifications
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
813
|
+
recent.extend(
|
|
814
|
+
[mod for mod in history.modifications if mod.timestamp >= cutoff]
|
|
815
|
+
)
|
|
816
|
+
|
|
748
817
|
return sorted(recent, key=lambda x: x.timestamp, reverse=True)
|
|
749
|
-
|
|
818
|
+
|
|
750
819
|
async def restore_agent_backup(self, modification_id: str) -> bool:
|
|
751
820
|
"""Restore agent from backup."""
|
|
752
821
|
try:
|
|
753
822
|
modification = self.active_modifications.get(modification_id)
|
|
754
823
|
if not modification or not modification.backup_path:
|
|
755
824
|
return False
|
|
756
|
-
|
|
825
|
+
|
|
757
826
|
# Restore from backup
|
|
758
827
|
backup_path = Path(modification.backup_path)
|
|
759
828
|
if not backup_path.exists():
|
|
760
829
|
return False
|
|
761
|
-
|
|
830
|
+
|
|
762
831
|
original_path = Path(modification.file_path)
|
|
763
832
|
shutil.copy2(backup_path, original_path)
|
|
764
|
-
|
|
833
|
+
|
|
765
834
|
# Track restore operation
|
|
766
835
|
await self.track_modification(
|
|
767
836
|
agent_name=modification.agent_name,
|
|
768
837
|
modification_type=ModificationType.RESTORE,
|
|
769
838
|
file_path=modification.file_path,
|
|
770
839
|
tier=modification.tier,
|
|
771
|
-
restored_from=modification_id
|
|
840
|
+
restored_from=modification_id,
|
|
772
841
|
)
|
|
773
|
-
|
|
842
|
+
|
|
774
843
|
return True
|
|
775
|
-
|
|
844
|
+
|
|
776
845
|
except Exception as e:
|
|
777
846
|
self.logger.error(f"Failed to restore agent backup: {e}")
|
|
778
847
|
return False
|
|
779
|
-
|
|
848
|
+
|
|
780
849
|
async def get_modification_stats(self) -> Dict[str, Any]:
|
|
781
850
|
"""Get comprehensive modification statistics."""
|
|
782
851
|
stats = {
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
852
|
+
"total_agents_tracked": len(self.modification_history),
|
|
853
|
+
"total_modifications": sum(
|
|
854
|
+
h.total_modifications for h in self.modification_history.values()
|
|
855
|
+
),
|
|
856
|
+
"active_modifications": len(self.active_modifications),
|
|
857
|
+
"watched_paths": len(self.watched_paths),
|
|
858
|
+
"monitoring_enabled": self.enable_monitoring,
|
|
859
|
+
"backup_enabled": self.backup_enabled,
|
|
860
|
+
"validation_enabled": self.validation_enabled,
|
|
790
861
|
}
|
|
791
|
-
|
|
862
|
+
|
|
792
863
|
# Modification type breakdown
|
|
793
864
|
type_counts = {}
|
|
794
865
|
for history in self.modification_history.values():
|
|
795
866
|
for mod in history.modifications:
|
|
796
|
-
type_counts[mod.modification_type.value] =
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
867
|
+
type_counts[mod.modification_type.value] = (
|
|
868
|
+
type_counts.get(mod.modification_type.value, 0) + 1
|
|
869
|
+
)
|
|
870
|
+
|
|
871
|
+
stats["modifications_by_type"] = type_counts
|
|
872
|
+
|
|
800
873
|
# Tier breakdown
|
|
801
874
|
tier_counts = {}
|
|
802
875
|
for history in self.modification_history.values():
|
|
803
876
|
for mod in history.modifications:
|
|
804
877
|
tier_counts[mod.tier.value] = tier_counts.get(mod.tier.value, 0) + 1
|
|
805
|
-
|
|
806
|
-
stats[
|
|
807
|
-
|
|
878
|
+
|
|
879
|
+
stats["modifications_by_tier"] = tier_counts
|
|
880
|
+
|
|
808
881
|
# Recent activity
|
|
809
882
|
recent_24h = await self.get_recent_modifications(24)
|
|
810
883
|
recent_7d = await self.get_recent_modifications(24 * 7)
|
|
811
|
-
|
|
812
|
-
stats[
|
|
813
|
-
|
|
814
|
-
|
|
884
|
+
|
|
885
|
+
stats["recent_activity"] = {
|
|
886
|
+
"last_24_hours": len(recent_24h),
|
|
887
|
+
"last_7_days": len(recent_7d),
|
|
815
888
|
}
|
|
816
|
-
|
|
889
|
+
|
|
817
890
|
# Validation stats
|
|
818
|
-
validation_stats = {
|
|
819
|
-
|
|
820
|
-
'failed': 0,
|
|
821
|
-
'pending': 0,
|
|
822
|
-
'error': 0
|
|
823
|
-
}
|
|
824
|
-
|
|
891
|
+
validation_stats = {"passed": 0, "failed": 0, "pending": 0, "error": 0}
|
|
892
|
+
|
|
825
893
|
for mod in self.active_modifications.values():
|
|
826
|
-
validation_stats[mod.validation_status] =
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
894
|
+
validation_stats[mod.validation_status] = (
|
|
895
|
+
validation_stats.get(mod.validation_status, 0) + 1
|
|
896
|
+
)
|
|
897
|
+
|
|
898
|
+
stats["validation_stats"] = validation_stats
|
|
899
|
+
|
|
830
900
|
# Backup stats
|
|
831
901
|
backup_stats = {
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
f.stat().st_size for f in self.backup_root.rglob(
|
|
835
|
-
)
|
|
902
|
+
"total_backups": len(list(self.backup_root.iterdir())),
|
|
903
|
+
"backup_size_mb": sum(
|
|
904
|
+
f.stat().st_size for f in self.backup_root.rglob("*") if f.is_file()
|
|
905
|
+
)
|
|
906
|
+
/ (1024 * 1024),
|
|
836
907
|
}
|
|
837
|
-
|
|
838
|
-
stats[
|
|
839
|
-
|
|
908
|
+
|
|
909
|
+
stats["backup_stats"] = backup_stats
|
|
910
|
+
|
|
840
911
|
return stats
|
|
841
|
-
|
|
842
|
-
def register_modification_callback(
|
|
912
|
+
|
|
913
|
+
def register_modification_callback(
|
|
914
|
+
self, callback: Callable[[AgentModification], None]
|
|
915
|
+
) -> None:
|
|
843
916
|
"""Register callback for modification events."""
|
|
844
917
|
self.modification_callbacks.append(callback)
|
|
845
|
-
|
|
846
|
-
def unregister_modification_callback(
|
|
918
|
+
|
|
919
|
+
def unregister_modification_callback(
|
|
920
|
+
self, callback: Callable[[AgentModification], None]
|
|
921
|
+
) -> None:
|
|
847
922
|
"""Unregister modification callback."""
|
|
848
923
|
if callback in self.modification_callbacks:
|
|
849
|
-
self.modification_callbacks.remove(callback)
|
|
924
|
+
self.modification_callbacks.remove(callback)
|