claude-mpm 3.4.10__py3-none-any.whl → 5.4.85__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/BUILD_NUMBER +1 -0
- claude_mpm/VERSION +1 -0
- claude_mpm/__init__.py +50 -12
- claude_mpm/__main__.py +7 -2
- claude_mpm/agents/BASE_AGENT.md +164 -0
- claude_mpm/agents/BASE_ENGINEER.md +658 -0
- claude_mpm/agents/CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md +405 -0
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +112 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +186 -0
- claude_mpm/agents/MEMORY.md +72 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +1429 -0
- claude_mpm/agents/WORKFLOW.md +111 -0
- claude_mpm/agents/__init__.py +92 -80
- claude_mpm/agents/agent-template.yaml +83 -0
- claude_mpm/agents/agent_loader.py +560 -745
- claude_mpm/agents/agent_loader_integration.py +53 -55
- claude_mpm/agents/agents_metadata.py +186 -27
- claude_mpm/agents/async_agent_loader.py +436 -0
- claude_mpm/agents/base_agent.json +8 -4
- claude_mpm/agents/frontmatter_validator.py +754 -0
- claude_mpm/agents/system_agent_config.py +222 -155
- claude_mpm/agents/templates/README.md +465 -0
- claude_mpm/agents/templates/__init__.py +17 -13
- claude_mpm/agents/templates/circuit-breakers.md +1391 -0
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/git-file-tracking.md +584 -0
- claude_mpm/agents/templates/pm-examples.md +474 -0
- claude_mpm/agents/templates/pm-red-flags.md +310 -0
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -0
- claude_mpm/agents/templates/response-format.md +583 -0
- claude_mpm/agents/templates/structured-questions-examples.md +615 -0
- claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
- claude_mpm/agents/templates/ticketing-examples.md +277 -0
- claude_mpm/agents/templates/validation-templates.md +312 -0
- claude_mpm/cli/__init__.py +94 -128
- claude_mpm/cli/__main__.py +33 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/__init__.py +36 -12
- claude_mpm/cli/commands/agent_manager.py +1403 -0
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +335 -0
- claude_mpm/cli/commands/agents.py +2501 -168
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/agents_reconcile.py +197 -0
- claude_mpm/cli/commands/aggregate.py +540 -0
- claude_mpm/cli/commands/analyze.py +553 -0
- claude_mpm/cli/commands/analyze_code.py +528 -0
- claude_mpm/cli/commands/auto_configure.py +1053 -0
- claude_mpm/cli/commands/cleanup.py +588 -0
- claude_mpm/cli/commands/cleanup_orphaned_agents.py +150 -0
- claude_mpm/cli/commands/config.py +586 -0
- claude_mpm/cli/commands/configure.py +3253 -0
- claude_mpm/cli/commands/configure_agent_display.py +282 -0
- claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
- claude_mpm/cli/commands/configure_hook_manager.py +225 -0
- claude_mpm/cli/commands/configure_models.py +18 -0
- claude_mpm/cli/commands/configure_navigation.py +184 -0
- claude_mpm/cli/commands/configure_paths.py +104 -0
- claude_mpm/cli/commands/configure_persistence.py +254 -0
- claude_mpm/cli/commands/configure_startup_manager.py +646 -0
- claude_mpm/cli/commands/configure_template_editor.py +497 -0
- claude_mpm/cli/commands/configure_validators.py +73 -0
- claude_mpm/cli/commands/dashboard.py +286 -0
- claude_mpm/cli/commands/debug.py +1386 -0
- claude_mpm/cli/commands/doctor.py +243 -0
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/info.py +195 -74
- claude_mpm/cli/commands/local_deploy.py +534 -0
- claude_mpm/cli/commands/mcp.py +205 -0
- claude_mpm/cli/commands/mcp_command_router.py +161 -0
- claude_mpm/cli/commands/mcp_config.py +154 -0
- claude_mpm/cli/commands/mcp_config_commands.py +20 -0
- claude_mpm/cli/commands/mcp_external_commands.py +249 -0
- claude_mpm/cli/commands/mcp_install_commands.py +346 -0
- claude_mpm/cli/commands/mcp_pipx_config.py +208 -0
- claude_mpm/cli/commands/mcp_server_commands.py +155 -0
- claude_mpm/cli/commands/mcp_setup_external.py +868 -0
- claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
- claude_mpm/cli/commands/memory.py +585 -846
- claude_mpm/cli/commands/monitor.py +228 -310
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +759 -0
- claude_mpm/cli/commands/mpm_init/display.py +341 -0
- claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/modes.py +397 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +722 -0
- claude_mpm/cli/commands/mpm_init_cli.py +396 -0
- claude_mpm/cli/commands/mpm_init_handler.py +195 -0
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/profile.py +276 -0
- claude_mpm/cli/commands/run.py +910 -488
- claude_mpm/cli/commands/search.py +458 -0
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +1398 -0
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/commands/tickets.py +536 -53
- claude_mpm/cli/commands/uninstall.py +176 -0
- claude_mpm/cli/commands/upgrade.py +152 -0
- claude_mpm/cli/commands/verify.py +119 -0
- claude_mpm/cli/executor.py +298 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +31 -0
- claude_mpm/cli/interactive/agent_wizard.py +1927 -0
- claude_mpm/cli/interactive/questionary_styles.py +65 -0
- claude_mpm/cli/interactive/skill_selector.py +481 -0
- claude_mpm/cli/interactive/skills_wizard.py +491 -0
- claude_mpm/cli/parser.py +87 -563
- claude_mpm/cli/parsers/__init__.py +35 -0
- claude_mpm/cli/parsers/agent_manager_parser.py +393 -0
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +575 -0
- claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
- claude_mpm/cli/parsers/analyze_parser.py +135 -0
- claude_mpm/cli/parsers/auto_configure_parser.py +120 -0
- claude_mpm/cli/parsers/base_parser.py +649 -0
- claude_mpm/cli/parsers/config_parser.py +208 -0
- claude_mpm/cli/parsers/configure_parser.py +138 -0
- claude_mpm/cli/parsers/dashboard_parser.py +113 -0
- claude_mpm/cli/parsers/debug_parser.py +319 -0
- claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
- claude_mpm/cli/parsers/mcp_parser.py +195 -0
- claude_mpm/cli/parsers/memory_parser.py +138 -0
- claude_mpm/cli/parsers/monitor_parser.py +142 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
- claude_mpm/cli/parsers/profile_parser.py +147 -0
- claude_mpm/cli/parsers/run_parser.py +157 -0
- claude_mpm/cli/parsers/search_parser.py +245 -0
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +277 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/parsers/tickets_parser.py +203 -0
- claude_mpm/cli/shared/__init__.py +40 -0
- claude_mpm/cli/shared/argument_patterns.py +205 -0
- claude_mpm/cli/shared/base_command.py +242 -0
- claude_mpm/cli/shared/error_handling.py +242 -0
- claude_mpm/cli/shared/output_formatters.py +241 -0
- claude_mpm/cli/startup.py +1578 -0
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/startup_logging.py +839 -0
- claude_mpm/cli/utils.py +136 -47
- claude_mpm/cli_module/__init__.py +6 -6
- claude_mpm/cli_module/args.py +188 -140
- claude_mpm/cli_module/commands.py +79 -70
- claude_mpm/cli_module/migration_example.py +42 -64
- claude_mpm/commands/__init__.py +14 -0
- claude_mpm/commands/mpm-config.md +28 -0
- claude_mpm/commands/mpm-doctor.md +20 -0
- claude_mpm/commands/mpm-help.md +20 -0
- claude_mpm/commands/mpm-init.md +120 -0
- claude_mpm/commands/mpm-monitor.md +31 -0
- claude_mpm/commands/mpm-organize.md +120 -0
- claude_mpm/commands/mpm-postmortem.md +21 -0
- claude_mpm/commands/mpm-session-resume.md +30 -0
- claude_mpm/commands/mpm-status.md +20 -0
- claude_mpm/commands/mpm-ticket-view.md +109 -0
- claude_mpm/commands/mpm-version.md +20 -0
- claude_mpm/commands/mpm.md +31 -0
- claude_mpm/config/__init__.py +42 -2
- claude_mpm/config/agent_config.py +402 -0
- claude_mpm/config/agent_presets.py +488 -0
- claude_mpm/config/agent_sources.py +352 -0
- claude_mpm/config/experimental_features.py +217 -0
- claude_mpm/config/model_config.py +428 -0
- claude_mpm/config/paths.py +258 -0
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/config/socketio_config.py +125 -83
- claude_mpm/constants.py +133 -22
- claude_mpm/core/__init__.py +62 -36
- claude_mpm/core/agent_name_normalizer.py +71 -73
- claude_mpm/core/agent_registry.py +385 -492
- claude_mpm/core/agent_session_manager.py +81 -70
- claude_mpm/core/api_validator.py +330 -0
- claude_mpm/core/base_service.py +159 -122
- claude_mpm/core/cache.py +560 -0
- claude_mpm/core/claude_runner.py +696 -916
- claude_mpm/core/config.py +613 -122
- claude_mpm/core/config_aliases.py +74 -73
- claude_mpm/core/config_constants.py +314 -0
- claude_mpm/core/constants.py +361 -0
- claude_mpm/core/container.py +646 -104
- claude_mpm/core/enums.py +452 -0
- claude_mpm/core/error_handler.py +623 -0
- claude_mpm/core/exceptions.py +536 -0
- claude_mpm/core/factories.py +105 -109
- claude_mpm/core/file_utils.py +764 -0
- claude_mpm/core/framework/__init__.py +25 -0
- claude_mpm/core/framework/formatters/__init__.py +11 -0
- claude_mpm/core/framework/formatters/capability_generator.py +367 -0
- claude_mpm/core/framework/formatters/content_formatter.py +278 -0
- claude_mpm/core/framework/formatters/context_generator.py +185 -0
- claude_mpm/core/framework/loaders/__init__.py +13 -0
- claude_mpm/core/framework/loaders/agent_loader.py +213 -0
- claude_mpm/core/framework/loaders/file_loader.py +176 -0
- claude_mpm/core/framework/loaders/instruction_loader.py +222 -0
- claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
- claude_mpm/core/framework/processors/__init__.py +11 -0
- claude_mpm/core/framework/processors/memory_processor.py +230 -0
- claude_mpm/core/framework/processors/metadata_processor.py +146 -0
- claude_mpm/core/framework/processors/template_processor.py +244 -0
- claude_mpm/core/framework_loader.py +485 -414
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +246 -86
- claude_mpm/core/hook_performance_config.py +147 -0
- claude_mpm/core/injectable_service.py +72 -63
- claude_mpm/core/instruction_reinforcement_hook.py +267 -0
- claude_mpm/core/interactive_session.py +670 -0
- claude_mpm/core/interfaces.py +570 -164
- claude_mpm/core/lazy.py +467 -0
- claude_mpm/core/log_manager.py +707 -0
- claude_mpm/core/logger.py +295 -134
- claude_mpm/core/logging_config.py +474 -0
- claude_mpm/core/logging_utils.py +520 -0
- claude_mpm/core/minimal_framework_loader.py +24 -22
- claude_mpm/core/mixins.py +30 -29
- claude_mpm/core/oneshot_session.py +594 -0
- claude_mpm/core/optimized_agent_loader.py +479 -0
- claude_mpm/core/optimized_startup.py +554 -0
- claude_mpm/core/output_style_manager.py +491 -0
- claude_mpm/core/pm_hook_interceptor.py +197 -82
- claude_mpm/core/protocols/__init__.py +23 -0
- claude_mpm/core/protocols/runner_protocol.py +103 -0
- claude_mpm/core/protocols/session_protocol.py +131 -0
- claude_mpm/core/service_registry.py +153 -116
- claude_mpm/core/session_manager.py +179 -64
- claude_mpm/core/shared/__init__.py +17 -0
- claude_mpm/core/shared/config_loader.py +326 -0
- claude_mpm/core/shared/path_resolver.py +281 -0
- claude_mpm/core/shared/singleton_manager.py +221 -0
- claude_mpm/core/socketio_pool.py +400 -137
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/tool_access_control.py +64 -57
- claude_mpm/core/types.py +307 -0
- claude_mpm/core/typing_utils.py +553 -0
- claude_mpm/core/unified_agent_registry.py +969 -0
- claude_mpm/core/unified_config.py +612 -0
- claude_mpm/core/unified_paths.py +958 -0
- claude_mpm/dashboard/__init__.py +12 -0
- claude_mpm/dashboard/api/simple_directory.py +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
- claude_mpm/experimental/__init__.py +10 -0
- claude_mpm/experimental/cli_enhancements.py +104 -89
- claude_mpm/generators/__init__.py +1 -1
- claude_mpm/generators/agent_profile_generator.py +76 -66
- claude_mpm/hooks/__init__.py +37 -1
- claude_mpm/hooks/base_hook.py +37 -32
- claude_mpm/hooks/claude_hooks/__init__.py +1 -1
- claude_mpm/hooks/claude_hooks/connection_pool.py +250 -0
- claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +888 -0
- claude_mpm/hooks/claude_hooks/hook_handler.py +652 -875
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +10 -7
- claude_mpm/hooks/claude_hooks/installer.py +806 -0
- claude_mpm/hooks/claude_hooks/memory_integration.py +249 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +412 -0
- claude_mpm/hooks/claude_hooks/services/__init__.py +15 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +229 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +254 -0
- claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
- claude_mpm/hooks/claude_hooks/services/state_manager.py +284 -0
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
- claude_mpm/hooks/claude_hooks/tool_analysis.py +224 -0
- claude_mpm/hooks/failure_learning/__init__.py +54 -0
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
- claude_mpm/hooks/instruction_reinforcement.py +301 -0
- claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
- claude_mpm/hooks/kuzu_memory_hook.py +386 -0
- claude_mpm/hooks/kuzu_response_hook.py +179 -0
- claude_mpm/hooks/memory_integration_hook.py +201 -107
- claude_mpm/hooks/session_resume_hook.py +121 -0
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/hooks/tool_call_interceptor.py +92 -76
- claude_mpm/hooks/validation_hooks.py +62 -54
- claude_mpm/init.py +518 -83
- claude_mpm/models/__init__.py +9 -9
- claude_mpm/models/agent_definition.py +40 -23
- claude_mpm/models/agent_session.py +538 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/schemas/__init__.py +12 -0
- claude_mpm/scripts/__init__.py +15 -0
- claude_mpm/scripts/claude-hook-handler.sh +227 -0
- claude_mpm/scripts/launch_monitor.py +165 -0
- claude_mpm/scripts/mpm_doctor.py +322 -0
- claude_mpm/scripts/socketio_daemon.py +189 -200
- claude_mpm/scripts/start_activity_logging.py +91 -0
- claude_mpm/services/__init__.py +208 -39
- claude_mpm/services/agent_capabilities_service.py +266 -0
- claude_mpm/services/agents/__init__.py +89 -0
- claude_mpm/services/agents/agent_builder.py +514 -0
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_recommendation_service.py +278 -0
- claude_mpm/services/agents/agent_review_service.py +280 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -0
- claude_mpm/services/agents/auto_config_manager.py +796 -0
- claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
- claude_mpm/services/agents/cache_git_manager.py +621 -0
- claude_mpm/services/agents/deployment/__init__.py +21 -0
- claude_mpm/services/agents/deployment/agent_config_provider.py +410 -0
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +358 -0
- claude_mpm/services/agents/deployment/agent_definition_factory.py +80 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +1037 -0
- claude_mpm/services/agents/deployment/agent_discovery_service.py +546 -0
- claude_mpm/services/agents/deployment/agent_environment_manager.py +288 -0
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +383 -0
- claude_mpm/services/agents/deployment/agent_format_converter.py +505 -0
- claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +160 -0
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +957 -0
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +273 -0
- claude_mpm/services/agents/deployment/agent_operation_service.py +573 -0
- claude_mpm/services/agents/deployment/agent_record_service.py +418 -0
- claude_mpm/services/agents/deployment/agent_restore_handler.py +84 -0
- claude_mpm/services/agents/deployment/agent_state_service.py +381 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +1377 -0
- claude_mpm/services/agents/deployment/agent_validator.py +376 -0
- claude_mpm/services/agents/deployment/agent_version_manager.py +322 -0
- claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +10 -13
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +149 -0
- claude_mpm/services/agents/deployment/async_agent_deployment.py +768 -0
- claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
- claude_mpm/services/agents/deployment/config/__init__.py +13 -0
- claude_mpm/services/agents/deployment/config/deployment_config.py +181 -0
- claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
- claude_mpm/services/agents/deployment/deployment_config_loader.py +178 -0
- claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
- claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
- claude_mpm/services/agents/deployment/deployment_type_detector.py +120 -0
- claude_mpm/services/agents/deployment/deployment_wrapper.py +129 -0
- claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
- claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
- claude_mpm/services/agents/deployment/facade/deployment_executor.py +70 -0
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +269 -0
- claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
- claude_mpm/services/agents/deployment/interface_adapter.py +226 -0
- claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
- claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
- claude_mpm/services/agents/deployment/local_template_deployment.py +362 -0
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +1478 -0
- claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +162 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
- claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +240 -0
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +110 -0
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +80 -0
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +92 -0
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +101 -0
- claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +102 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
- claude_mpm/services/agents/deployment/processors/agent_processor.py +269 -0
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +311 -0
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +862 -0
- claude_mpm/services/agents/deployment/results/__init__.py +13 -0
- claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
- claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
- claude_mpm/services/agents/deployment/strategies/base_strategy.py +113 -0
- claude_mpm/services/agents/deployment/strategies/project_strategy.py +148 -0
- claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
- claude_mpm/services/agents/deployment/strategies/system_strategy.py +131 -0
- claude_mpm/services/agents/deployment/strategies/user_strategy.py +130 -0
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +228 -0
- claude_mpm/services/agents/deployment/validation/__init__.py +21 -0
- claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
- claude_mpm/services/agents/deployment/validation/template_validator.py +319 -0
- claude_mpm/services/agents/deployment/validation/validation_result.py +214 -0
- claude_mpm/services/agents/git_source_manager.py +682 -0
- claude_mpm/services/agents/loading/__init__.py +11 -0
- claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +306 -228
- claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +106 -91
- claude_mpm/services/agents/loading/framework_agent_loader.py +433 -0
- claude_mpm/services/agents/local_template_manager.py +784 -0
- claude_mpm/services/agents/management/__init__.py +9 -0
- claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +92 -69
- claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +219 -168
- claude_mpm/services/agents/memory/__init__.py +22 -0
- claude_mpm/services/agents/memory/agent_memory_manager.py +784 -0
- claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +20 -18
- claude_mpm/services/agents/memory/content_manager.py +470 -0
- claude_mpm/services/agents/memory/memory_categorization_service.py +167 -0
- claude_mpm/services/agents/memory/memory_file_service.py +129 -0
- claude_mpm/services/agents/memory/memory_format_service.py +201 -0
- claude_mpm/services/agents/memory/memory_limits_service.py +101 -0
- claude_mpm/services/agents/memory/template_generator.py +83 -0
- claude_mpm/services/agents/observers.py +547 -0
- claude_mpm/services/agents/recommender.py +617 -0
- claude_mpm/services/agents/registry/__init__.py +30 -0
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +273 -0
- claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +370 -295
- claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
- claude_mpm/services/agents/sources/__init__.py +13 -0
- claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +1205 -0
- claude_mpm/services/agents/startup_sync.py +262 -0
- claude_mpm/services/agents/toolchain_detector.py +478 -0
- claude_mpm/services/analysis/__init__.py +35 -0
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/async_session_logger.py +665 -0
- claude_mpm/services/claude_session_logger.py +321 -0
- claude_mpm/services/cli/__init__.py +18 -0
- claude_mpm/services/cli/agent_cleanup_service.py +408 -0
- claude_mpm/services/cli/agent_dependency_service.py +395 -0
- claude_mpm/services/cli/agent_listing_service.py +463 -0
- claude_mpm/services/cli/agent_output_formatter.py +605 -0
- claude_mpm/services/cli/agent_validation_service.py +590 -0
- claude_mpm/services/cli/memory_crud_service.py +622 -0
- claude_mpm/services/cli/memory_output_formatter.py +604 -0
- claude_mpm/services/cli/resume_service.py +617 -0
- claude_mpm/services/cli/session_manager.py +604 -0
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +372 -0
- claude_mpm/services/cli/startup_checker.py +362 -0
- claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
- claude_mpm/services/command_deployment_service.py +446 -0
- claude_mpm/services/command_handler_service.py +221 -0
- claude_mpm/services/communication/__init__.py +22 -0
- claude_mpm/services/core/__init__.py +108 -0
- claude_mpm/services/core/base.py +269 -0
- claude_mpm/services/core/cache_manager.py +309 -0
- claude_mpm/services/core/interfaces/__init__.py +273 -0
- claude_mpm/services/core/interfaces/agent.py +514 -0
- claude_mpm/services/core/interfaces/communication.py +316 -0
- claude_mpm/services/core/interfaces/health.py +169 -0
- claude_mpm/services/core/interfaces/infrastructure.py +357 -0
- claude_mpm/services/core/interfaces/model.py +281 -0
- claude_mpm/services/core/interfaces/process.py +372 -0
- claude_mpm/services/core/interfaces/project.py +121 -0
- claude_mpm/services/core/interfaces/restart.py +307 -0
- claude_mpm/services/core/interfaces/service.py +405 -0
- claude_mpm/services/core/interfaces/stability.py +260 -0
- claude_mpm/services/core/interfaces.py +81 -0
- claude_mpm/services/core/memory_manager.py +682 -0
- claude_mpm/services/core/models/__init__.py +70 -0
- claude_mpm/services/core/models/agent_config.py +384 -0
- claude_mpm/services/core/models/health.py +162 -0
- claude_mpm/services/core/models/process.py +239 -0
- claude_mpm/services/core/models/restart.py +302 -0
- claude_mpm/services/core/models/stability.py +264 -0
- claude_mpm/services/core/models/toolchain.py +306 -0
- claude_mpm/services/core/path_resolver.py +517 -0
- claude_mpm/services/core/service_container.py +520 -0
- claude_mpm/services/core/service_interfaces.py +436 -0
- claude_mpm/services/diagnostics/__init__.py +18 -0
- claude_mpm/services/diagnostics/checks/__init__.py +38 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +370 -0
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/base_check.py +60 -0
- claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
- claude_mpm/services/diagnostics/checks/common_issues_check.py +363 -0
- claude_mpm/services/diagnostics/checks/configuration_check.py +306 -0
- claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
- claude_mpm/services/diagnostics/checks/installation_check.py +520 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +415 -0
- claude_mpm/services/diagnostics/checks/mcp_check.py +330 -0
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
- claude_mpm/services/diagnostics/checks/monitor_check.py +281 -0
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/checks/startup_log_check.py +319 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +286 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +578 -0
- claude_mpm/services/diagnostics/models.py +138 -0
- claude_mpm/services/event_aggregator.py +582 -0
- claude_mpm/services/event_bus/__init__.py +18 -0
- claude_mpm/services/event_bus/config.py +186 -0
- claude_mpm/services/event_bus/direct_relay.py +312 -0
- claude_mpm/services/event_bus/event_bus.py +396 -0
- claude_mpm/services/event_bus/relay.py +326 -0
- claude_mpm/services/events/__init__.py +44 -0
- claude_mpm/services/events/consumers/__init__.py +18 -0
- claude_mpm/services/events/consumers/dead_letter.py +306 -0
- claude_mpm/services/events/consumers/logging.py +184 -0
- claude_mpm/services/events/consumers/metrics.py +241 -0
- claude_mpm/services/events/consumers/socketio.py +377 -0
- claude_mpm/services/events/core.py +480 -0
- claude_mpm/services/events/interfaces.py +214 -0
- claude_mpm/services/events/producers/__init__.py +14 -0
- claude_mpm/services/events/producers/hook.py +269 -0
- claude_mpm/services/events/producers/system.py +329 -0
- claude_mpm/services/exceptions.py +433 -353
- claude_mpm/services/framework_claude_md_generator/__init__.py +81 -80
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +74 -67
- claude_mpm/services/framework_claude_md_generator/content_validator.py +66 -62
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +82 -60
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +36 -37
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +41 -40
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +15 -15
- claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +5 -4
- claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
- claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +5 -4
- claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
- claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +26 -30
- claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
- claude_mpm/services/framework_claude_md_generator/version_manager.py +31 -30
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +579 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/hook_installer_service.py +506 -0
- claude_mpm/services/hook_service.py +159 -111
- claude_mpm/services/infrastructure/__init__.py +52 -0
- claude_mpm/services/infrastructure/context_preservation.py +569 -0
- claude_mpm/services/infrastructure/daemon_manager.py +279 -0
- claude_mpm/services/infrastructure/logging.py +209 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +39 -0
- claude_mpm/services/infrastructure/monitoring/aggregator.py +432 -0
- claude_mpm/services/infrastructure/monitoring/base.py +122 -0
- claude_mpm/services/infrastructure/monitoring/legacy.py +203 -0
- claude_mpm/services/infrastructure/monitoring/network.py +219 -0
- claude_mpm/services/infrastructure/monitoring/process.py +343 -0
- claude_mpm/services/infrastructure/monitoring/resources.py +244 -0
- claude_mpm/services/infrastructure/monitoring/service.py +368 -0
- claude_mpm/services/infrastructure/monitoring.py +71 -0
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/instructions/__init__.py +9 -0
- claude_mpm/services/instructions/instruction_cache_service.py +374 -0
- claude_mpm/services/local_ops/__init__.py +155 -0
- claude_mpm/services/local_ops/crash_detector.py +257 -0
- claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
- claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
- claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
- claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
- claude_mpm/services/local_ops/health_manager.py +427 -0
- claude_mpm/services/local_ops/log_monitor.py +396 -0
- claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
- claude_mpm/services/local_ops/process_manager.py +595 -0
- claude_mpm/services/local_ops/resource_monitor.py +331 -0
- claude_mpm/services/local_ops/restart_manager.py +401 -0
- claude_mpm/services/local_ops/restart_policy.py +387 -0
- claude_mpm/services/local_ops/state_manager.py +372 -0
- claude_mpm/services/local_ops/unified_manager.py +600 -0
- claude_mpm/services/mcp_config_manager.py +1542 -0
- claude_mpm/services/mcp_service_verifier.py +732 -0
- claude_mpm/services/memory/__init__.py +19 -0
- claude_mpm/services/{memory_builder.py → memory/builder.py} +465 -373
- claude_mpm/services/memory/cache/__init__.py +14 -0
- claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +237 -200
- claude_mpm/services/memory/cache/simple_cache.py +331 -0
- claude_mpm/services/memory/failure_tracker.py +578 -0
- claude_mpm/services/memory/indexed_memory.py +648 -0
- claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +272 -243
- claude_mpm/services/memory/router.py +951 -0
- claude_mpm/services/memory_hook_service.py +470 -0
- claude_mpm/services/model/__init__.py +147 -0
- claude_mpm/services/model/base_provider.py +365 -0
- claude_mpm/services/model/claude_provider.py +412 -0
- claude_mpm/services/model/model_router.py +452 -0
- claude_mpm/services/model/ollama_provider.py +415 -0
- claude_mpm/services/monitor/__init__.py +20 -0
- claude_mpm/services/monitor/daemon.py +698 -0
- claude_mpm/services/monitor/daemon_manager.py +1076 -0
- claude_mpm/services/monitor/event_emitter.py +350 -0
- claude_mpm/services/monitor/handlers/__init__.py +21 -0
- claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
- claude_mpm/services/monitor/handlers/dashboard.py +299 -0
- claude_mpm/services/monitor/handlers/file.py +264 -0
- claude_mpm/services/monitor/handlers/hooks.py +512 -0
- claude_mpm/services/monitor/management/__init__.py +18 -0
- claude_mpm/services/monitor/management/health.py +124 -0
- claude_mpm/services/monitor/management/lifecycle.py +730 -0
- claude_mpm/services/monitor/server.py +1493 -0
- claude_mpm/services/monitor_build_service.py +349 -0
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/orphan_detection.py +786 -0
- claude_mpm/services/pm_skills_deployer.py +711 -0
- claude_mpm/services/port_manager.py +597 -0
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/profile_manager.py +337 -0
- claude_mpm/services/project/__init__.py +44 -0
- claude_mpm/services/{project_analyzer.py → project/analyzer.py} +541 -291
- claude_mpm/services/project/analyzer_v2.py +566 -0
- claude_mpm/services/project/architecture_analyzer.py +461 -0
- claude_mpm/services/project/archive_manager.py +1045 -0
- claude_mpm/services/project/dependency_analyzer.py +462 -0
- claude_mpm/services/project/detection_strategies.py +719 -0
- claude_mpm/services/project/documentation_manager.py +554 -0
- claude_mpm/services/project/enhanced_analyzer.py +572 -0
- claude_mpm/services/project/language_analyzer.py +265 -0
- claude_mpm/services/project/metrics_collector.py +407 -0
- claude_mpm/services/project/project_organizer.py +1009 -0
- claude_mpm/services/project/registry.py +636 -0
- claude_mpm/services/project/toolchain_analyzer.py +583 -0
- claude_mpm/services/project_port_allocator.py +596 -0
- claude_mpm/services/recovery_manager.py +293 -240
- claude_mpm/services/response_tracker.py +267 -0
- claude_mpm/services/runner_configuration_service.py +605 -0
- claude_mpm/services/self_upgrade_service.py +608 -0
- claude_mpm/services/session_management_service.py +314 -0
- claude_mpm/services/session_manager.py +380 -0
- claude_mpm/services/shared/__init__.py +21 -0
- claude_mpm/services/shared/async_service_base.py +216 -0
- claude_mpm/services/shared/config_service_base.py +301 -0
- claude_mpm/services/shared/lifecycle_service_base.py +308 -0
- claude_mpm/services/shared/manager_base.py +315 -0
- claude_mpm/services/shared/service_factory.py +309 -0
- claude_mpm/services/skills/__init__.py +21 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1340 -0
- claude_mpm/services/skills/selective_skill_deployer.py +743 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +1168 -0
- claude_mpm/services/socketio/__init__.py +25 -0
- claude_mpm/services/socketio/client_proxy.py +229 -0
- claude_mpm/services/socketio/dashboard_server.py +362 -0
- claude_mpm/services/socketio/event_normalizer.py +798 -0
- claude_mpm/services/socketio/handlers/__init__.py +30 -0
- claude_mpm/services/socketio/handlers/base.py +136 -0
- claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
- claude_mpm/services/socketio/handlers/connection.py +643 -0
- claude_mpm/services/socketio/handlers/connection_handler.py +333 -0
- claude_mpm/services/socketio/handlers/file.py +263 -0
- claude_mpm/services/socketio/handlers/git.py +962 -0
- claude_mpm/services/socketio/handlers/hook.py +211 -0
- claude_mpm/services/socketio/handlers/memory.py +26 -0
- claude_mpm/services/socketio/handlers/project.py +24 -0
- claude_mpm/services/socketio/handlers/registry.py +214 -0
- claude_mpm/services/socketio/migration_utils.py +343 -0
- claude_mpm/services/socketio/monitor_client.py +364 -0
- claude_mpm/services/socketio/server/__init__.py +18 -0
- claude_mpm/services/socketio/server/broadcaster.py +569 -0
- claude_mpm/services/socketio/server/connection_manager.py +579 -0
- claude_mpm/services/socketio/server/core.py +1079 -0
- claude_mpm/services/socketio/server/eventbus_integration.py +245 -0
- claude_mpm/services/socketio/server/main.py +501 -0
- claude_mpm/services/socketio_client_manager.py +173 -143
- claude_mpm/services/socketio_server.py +38 -1657
- claude_mpm/services/subprocess_launcher_service.py +322 -0
- claude_mpm/services/system_instructions_service.py +270 -0
- claude_mpm/services/ticket_manager.py +25 -209
- claude_mpm/services/ticket_services/__init__.py +26 -0
- claude_mpm/services/ticket_services/crud_service.py +328 -0
- claude_mpm/services/ticket_services/formatter_service.py +290 -0
- claude_mpm/services/ticket_services/search_service.py +324 -0
- claude_mpm/services/ticket_services/validation_service.py +303 -0
- claude_mpm/services/ticket_services/workflow_service.py +244 -0
- claude_mpm/services/unified/__init__.py +65 -0
- claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
- claude_mpm/services/unified/config_strategies/__init__.py +175 -0
- claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
- claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
- claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
- claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
- claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
- claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
- claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
- claude_mpm/services/unified/deployment_strategies/base.py +553 -0
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
- claude_mpm/services/unified/deployment_strategies/local.py +607 -0
- claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
- claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
- claude_mpm/services/unified/interfaces.py +475 -0
- claude_mpm/services/unified/migration.py +509 -0
- claude_mpm/services/unified/strategies.py +534 -0
- claude_mpm/services/unified/unified_analyzer.py +542 -0
- claude_mpm/services/unified/unified_config.py +691 -0
- claude_mpm/services/unified/unified_deployment.py +466 -0
- claude_mpm/services/utility_service.py +280 -0
- claude_mpm/services/version_control/__init__.py +34 -37
- claude_mpm/services/version_control/branch_strategy.py +26 -17
- claude_mpm/services/version_control/conflict_resolution.py +52 -36
- claude_mpm/services/version_control/git_operations.py +183 -49
- claude_mpm/services/version_control/semantic_versioning.py +172 -61
- claude_mpm/services/version_control/version_parser.py +546 -0
- claude_mpm/services/version_service.py +379 -0
- claude_mpm/services/visualization/__init__.py +15 -0
- claude_mpm/services/visualization/mermaid_generator.py +937 -0
- claude_mpm/skills/__init__.py +42 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
- claude_mpm/skills/bundled/__init__.py +6 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +573 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/pm/pm-bug-reporting/pm-bug-reporting.md +248 -0
- claude_mpm/skills/bundled/pm/pm-delegation-patterns/SKILL.md +167 -0
- claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md +113 -0
- claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md +124 -0
- claude_mpm/skills/bundled/pm/pm-teaching-mode/SKILL.md +657 -0
- claude_mpm/skills/bundled/pm/pm-ticketing-integration/SKILL.md +154 -0
- claude_mpm/skills/bundled/pm/pm-verification-protocols/SKILL.md +198 -0
- claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/security-scanning.md +439 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
- claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
- claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
- claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
- claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
- claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
- claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
- claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
- claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
- claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
- claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +286 -0
- claude_mpm/skills/skill_manager.py +405 -0
- claude_mpm/skills/skills_registry.py +347 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/storage/__init__.py +9 -0
- claude_mpm/storage/state_storage.py +546 -0
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/templates/questions/__init__.py +38 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +311 -0
- claude_mpm/templates/questions/project_init.py +385 -0
- claude_mpm/templates/questions/ticket_mgmt.py +394 -0
- claude_mpm/ticket_wrapper.py +2 -2
- claude_mpm/tools/__init__.py +10 -0
- claude_mpm/tools/__main__.py +208 -0
- claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
- claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
- claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
- claude_mpm/tools/code_tree_analyzer/core.py +380 -0
- claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
- claude_mpm/tools/code_tree_analyzer/events.py +168 -0
- claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
- claude_mpm/tools/code_tree_analyzer/models.py +39 -0
- claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
- claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
- claude_mpm/tools/code_tree_builder.py +631 -0
- claude_mpm/tools/code_tree_events.py +420 -0
- claude_mpm/tools/socketio_debug.py +671 -0
- claude_mpm/utils/__init__.py +8 -8
- claude_mpm/utils/agent_dependency_loader.py +1189 -0
- claude_mpm/utils/agent_filters.py +261 -0
- claude_mpm/utils/common.py +544 -0
- claude_mpm/utils/config_manager.py +168 -126
- claude_mpm/utils/console.py +11 -0
- claude_mpm/utils/database_connector.py +298 -0
- claude_mpm/utils/dependency_cache.py +373 -0
- claude_mpm/utils/dependency_manager.py +60 -59
- claude_mpm/utils/dependency_strategies.py +381 -0
- claude_mpm/utils/display_helper.py +260 -0
- claude_mpm/utils/environment_context.py +313 -0
- claude_mpm/utils/error_handler.py +78 -66
- claude_mpm/utils/file_utils.py +305 -0
- claude_mpm/utils/framework_detection.py +12 -11
- claude_mpm/utils/git_analyzer.py +407 -0
- claude_mpm/utils/gitignore.py +244 -0
- claude_mpm/utils/import_migration_example.py +12 -60
- claude_mpm/utils/imports.py +48 -45
- claude_mpm/utils/log_cleanup.py +627 -0
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/path_operations.py +110 -104
- claude_mpm/utils/progress.py +387 -0
- claude_mpm/utils/robust_installer.py +844 -0
- claude_mpm/utils/session_logging.py +121 -0
- claude_mpm/utils/structured_questions.py +619 -0
- claude_mpm/utils/subprocess_utils.py +343 -0
- claude_mpm/validation/__init__.py +1 -1
- claude_mpm/validation/agent_validator.py +214 -108
- claude_mpm/validation/frontmatter_validator.py +252 -0
- claude_mpm-5.4.85.dist-info/METADATA +1023 -0
- claude_mpm-5.4.85.dist-info/RECORD +980 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/entry_points.txt +1 -3
- claude_mpm-5.4.85.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.85.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -88
- claude_mpm/agents/INSTRUCTIONS.md +0 -352
- claude_mpm/agents/backups/INSTRUCTIONS.md +0 -352
- claude_mpm/agents/base_agent_loader.py +0 -529
- claude_mpm/agents/schema/agent_schema.json +0 -314
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -36
- claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/documentation_agent_20250726_234551.json +0 -45
- claude_mpm/agents/templates/backup/engineer_agent_20250726_234551.json +0 -49
- claude_mpm/agents/templates/backup/ops_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/qa_agent_20250726_234551.json +0 -45
- claude_mpm/agents/templates/backup/research_agent_20250726_234551.json +0 -49
- claude_mpm/agents/templates/backup/security_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/version_control_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/data_engineer.json +0 -110
- claude_mpm/agents/templates/documentation.json +0 -109
- claude_mpm/agents/templates/engineer.json +0 -113
- claude_mpm/agents/templates/ops.json +0 -109
- claude_mpm/agents/templates/pm.json +0 -25
- claude_mpm/agents/templates/qa.json +0 -111
- claude_mpm/agents/templates/research.json +0 -65
- claude_mpm/agents/templates/security.json +0 -113
- claude_mpm/agents/templates/test_integration.json +0 -112
- claude_mpm/agents/templates/version_control.json +0 -107
- claude_mpm/cli/commands/ui.py +0 -57
- claude_mpm/core/simple_runner.py +0 -1046
- claude_mpm/dashboard/open_dashboard.py +0 -34
- claude_mpm/deployment_paths.py +0 -261
- claude_mpm/hooks/builtin/__init__.py +0 -1
- claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
- claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
- claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
- claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
- claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
- claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
- claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
- claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
- claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
- claude_mpm/orchestration/__init__.py +0 -6
- claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
- claude_mpm/orchestration/archive/factory.py +0 -215
- claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
- claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
- claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
- claude_mpm/orchestration/archive/orchestrator.py +0 -501
- claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
- claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
- claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
- claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
- claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
- claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
- claude_mpm/schemas/workflow_validator.py +0 -411
- claude_mpm/services/agent_deployment.py +0 -1534
- claude_mpm/services/agent_lifecycle_manager.py +0 -1169
- claude_mpm/services/agent_memory_manager.py +0 -1415
- claude_mpm/services/agent_registry.py +0 -676
- claude_mpm/services/deployed_agent_discovery.py +0 -226
- claude_mpm/services/framework_agent_loader.py +0 -337
- claude_mpm/services/framework_claude_md_generator.py +0 -621
- claude_mpm/services/health_monitor.py +0 -892
- claude_mpm/services/memory_router.py +0 -538
- claude_mpm/services/parent_directory_manager/__init__.py +0 -577
- claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
- claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
- claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
- claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
- claude_mpm/services/parent_directory_manager/operations.py +0 -186
- claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
- claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
- claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
- claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
- claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
- claude_mpm/services/standalone_socketio_server.py +0 -1300
- claude_mpm/services/ticket_manager_di.py +0 -318
- claude_mpm/services/ticketing_service_original.py +0 -508
- claude_mpm/ui/__init__.py +0 -1
- claude_mpm/ui/rich_terminal_ui.py +0 -295
- claude_mpm/ui/terminal_ui.py +0 -328
- claude_mpm/utils/paths.py +0 -289
- claude_mpm-3.4.10.dist-info/METADATA +0 -183
- claude_mpm-3.4.10.dist-info/RECORD +0 -201
- claude_mpm-3.4.10.dist-info/licenses/LICENSE +0 -21
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/WHEEL +0 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/top_level.txt +0 -0
|
@@ -1,1415 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Agent Memory Manager Service
|
|
4
|
-
===========================
|
|
5
|
-
|
|
6
|
-
Manages agent memory files with size limits and validation.
|
|
7
|
-
|
|
8
|
-
This service provides:
|
|
9
|
-
- Memory file operations (load, save, validate)
|
|
10
|
-
- Size limit enforcement (8KB default)
|
|
11
|
-
- Auto-truncation when limits exceeded
|
|
12
|
-
- Default memory template creation
|
|
13
|
-
- Section management with item limits
|
|
14
|
-
- Timestamp updates
|
|
15
|
-
- Directory initialization with README
|
|
16
|
-
|
|
17
|
-
Memory files are stored in .claude-mpm/memories/ directory
|
|
18
|
-
following the naming convention: {agent_id}_agent.md
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
from pathlib import Path
|
|
22
|
-
from typing import Dict, List, Optional, Any
|
|
23
|
-
from datetime import datetime
|
|
24
|
-
import re
|
|
25
|
-
import logging
|
|
26
|
-
import os
|
|
27
|
-
|
|
28
|
-
from claude_mpm.core.config import Config
|
|
29
|
-
from claude_mpm.core.mixins import LoggerMixin
|
|
30
|
-
from claude_mpm.utils.paths import PathResolver
|
|
31
|
-
from claude_mpm.services.project_analyzer import ProjectAnalyzer
|
|
32
|
-
# Socket.IO notifications are optional - we'll skip them if server is not available
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class AgentMemoryManager:
|
|
36
|
-
"""Manages agent memory files with size limits and validation.
|
|
37
|
-
|
|
38
|
-
WHY: Agents need to accumulate project-specific knowledge over time to become
|
|
39
|
-
more effective. This service manages persistent memory files that agents can
|
|
40
|
-
read before tasks and update with new learnings.
|
|
41
|
-
|
|
42
|
-
DESIGN DECISION: Memory files are stored in .claude-mpm/memories/ (not project root)
|
|
43
|
-
to keep them organized and separate from other project files. Files follow a
|
|
44
|
-
standardized markdown format with enforced size limits to prevent unbounded growth.
|
|
45
|
-
|
|
46
|
-
The 8KB limit (~2000 tokens) balances comprehensive knowledge storage with
|
|
47
|
-
reasonable context size for agent prompts.
|
|
48
|
-
"""
|
|
49
|
-
|
|
50
|
-
# Default limits - will be overridden by configuration
|
|
51
|
-
DEFAULT_MEMORY_LIMITS = {
|
|
52
|
-
'max_file_size_kb': 8,
|
|
53
|
-
'max_sections': 10,
|
|
54
|
-
'max_items_per_section': 15,
|
|
55
|
-
'max_line_length': 120
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
REQUIRED_SECTIONS = [
|
|
59
|
-
'Project Architecture',
|
|
60
|
-
'Implementation Guidelines',
|
|
61
|
-
'Common Mistakes to Avoid',
|
|
62
|
-
'Current Technical Context'
|
|
63
|
-
]
|
|
64
|
-
|
|
65
|
-
def __init__(self, config: Optional[Config] = None, working_directory: Optional[Path] = None):
|
|
66
|
-
"""Initialize the memory manager.
|
|
67
|
-
|
|
68
|
-
Sets up the memories directory and ensures it exists with proper README.
|
|
69
|
-
|
|
70
|
-
Args:
|
|
71
|
-
config: Optional Config object. If not provided, will create default Config.
|
|
72
|
-
working_directory: Optional working directory. If not provided, uses current working directory.
|
|
73
|
-
"""
|
|
74
|
-
# Initialize logger using the same pattern as LoggerMixin
|
|
75
|
-
self._logger_instance = None
|
|
76
|
-
self._logger_name = None
|
|
77
|
-
|
|
78
|
-
self.config = config or Config()
|
|
79
|
-
self.project_root = PathResolver.get_project_root()
|
|
80
|
-
# Use current working directory by default, not project root
|
|
81
|
-
self.working_directory = working_directory or Path(os.getcwd())
|
|
82
|
-
self.memories_dir = self.working_directory / ".claude-mpm" / "memories"
|
|
83
|
-
self._ensure_memories_directory()
|
|
84
|
-
|
|
85
|
-
# Initialize memory limits from configuration
|
|
86
|
-
self._init_memory_limits()
|
|
87
|
-
|
|
88
|
-
# Initialize project analyzer for context-aware memory creation
|
|
89
|
-
self.project_analyzer = ProjectAnalyzer(self.config, self.working_directory)
|
|
90
|
-
|
|
91
|
-
@property
|
|
92
|
-
def logger(self):
|
|
93
|
-
"""Get or create the logger instance (like LoggerMixin)."""
|
|
94
|
-
if self._logger_instance is None:
|
|
95
|
-
if self._logger_name:
|
|
96
|
-
logger_name = self._logger_name
|
|
97
|
-
else:
|
|
98
|
-
module = self.__class__.__module__
|
|
99
|
-
class_name = self.__class__.__name__
|
|
100
|
-
|
|
101
|
-
if module and module != "__main__":
|
|
102
|
-
logger_name = f"{module}.{class_name}"
|
|
103
|
-
else:
|
|
104
|
-
logger_name = class_name
|
|
105
|
-
|
|
106
|
-
self._logger_instance = logging.getLogger(logger_name)
|
|
107
|
-
|
|
108
|
-
return self._logger_instance
|
|
109
|
-
|
|
110
|
-
def _init_memory_limits(self):
|
|
111
|
-
"""Initialize memory limits from configuration.
|
|
112
|
-
|
|
113
|
-
WHY: Allows configuration-driven memory limits instead of hardcoded values.
|
|
114
|
-
Supports agent-specific overrides for different memory requirements.
|
|
115
|
-
"""
|
|
116
|
-
# Check if memory system is enabled
|
|
117
|
-
self.memory_enabled = self.config.get('memory.enabled', True)
|
|
118
|
-
self.auto_learning = self.config.get('memory.auto_learning', True) # Changed default to True
|
|
119
|
-
|
|
120
|
-
# Load default limits from configuration
|
|
121
|
-
config_limits = self.config.get('memory.limits', {})
|
|
122
|
-
self.memory_limits = {
|
|
123
|
-
'max_file_size_kb': config_limits.get('default_size_kb',
|
|
124
|
-
self.DEFAULT_MEMORY_LIMITS['max_file_size_kb']),
|
|
125
|
-
'max_sections': config_limits.get('max_sections',
|
|
126
|
-
self.DEFAULT_MEMORY_LIMITS['max_sections']),
|
|
127
|
-
'max_items_per_section': config_limits.get('max_items_per_section',
|
|
128
|
-
self.DEFAULT_MEMORY_LIMITS['max_items_per_section']),
|
|
129
|
-
'max_line_length': config_limits.get('max_line_length',
|
|
130
|
-
self.DEFAULT_MEMORY_LIMITS['max_line_length'])
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
# Load agent-specific overrides
|
|
134
|
-
self.agent_overrides = self.config.get('memory.agent_overrides', {})
|
|
135
|
-
|
|
136
|
-
def _get_agent_limits(self, agent_id: str) -> Dict[str, Any]:
|
|
137
|
-
"""Get memory limits for specific agent, including overrides.
|
|
138
|
-
|
|
139
|
-
WHY: Different agents may need different memory capacities. Research agents
|
|
140
|
-
might need larger memory for comprehensive findings, while simple agents
|
|
141
|
-
can work with smaller limits.
|
|
142
|
-
|
|
143
|
-
Args:
|
|
144
|
-
agent_id: The agent identifier
|
|
145
|
-
|
|
146
|
-
Returns:
|
|
147
|
-
Dict containing the effective limits for this agent
|
|
148
|
-
"""
|
|
149
|
-
# Start with default limits
|
|
150
|
-
limits = self.memory_limits.copy()
|
|
151
|
-
|
|
152
|
-
# Apply agent-specific overrides if they exist
|
|
153
|
-
if agent_id in self.agent_overrides:
|
|
154
|
-
overrides = self.agent_overrides[agent_id]
|
|
155
|
-
if 'size_kb' in overrides:
|
|
156
|
-
limits['max_file_size_kb'] = overrides['size_kb']
|
|
157
|
-
|
|
158
|
-
return limits
|
|
159
|
-
|
|
160
|
-
def _get_agent_auto_learning(self, agent_id: str) -> bool:
|
|
161
|
-
"""Check if auto-learning is enabled for specific agent.
|
|
162
|
-
|
|
163
|
-
Args:
|
|
164
|
-
agent_id: The agent identifier
|
|
165
|
-
|
|
166
|
-
Returns:
|
|
167
|
-
bool: True if auto-learning is enabled for this agent
|
|
168
|
-
"""
|
|
169
|
-
# Check agent-specific override first
|
|
170
|
-
if agent_id in self.agent_overrides:
|
|
171
|
-
return self.agent_overrides[agent_id].get('auto_learning', self.auto_learning)
|
|
172
|
-
|
|
173
|
-
# Fall back to global setting
|
|
174
|
-
return self.auto_learning
|
|
175
|
-
|
|
176
|
-
def load_agent_memory(self, agent_id: str) -> str:
|
|
177
|
-
"""Load agent memory file content.
|
|
178
|
-
|
|
179
|
-
WHY: Agents need to read their accumulated knowledge before starting tasks
|
|
180
|
-
to apply learned patterns and avoid repeated mistakes.
|
|
181
|
-
|
|
182
|
-
Args:
|
|
183
|
-
agent_id: The agent identifier (e.g., 'research', 'engineer')
|
|
184
|
-
|
|
185
|
-
Returns:
|
|
186
|
-
str: The memory file content, creating default if doesn't exist
|
|
187
|
-
"""
|
|
188
|
-
memory_file = self.memories_dir / f"{agent_id}_agent.md"
|
|
189
|
-
|
|
190
|
-
if not memory_file.exists():
|
|
191
|
-
self.logger.info(f"Creating default memory for agent: {agent_id}")
|
|
192
|
-
return self._create_default_memory(agent_id)
|
|
193
|
-
|
|
194
|
-
try:
|
|
195
|
-
content = memory_file.read_text(encoding='utf-8')
|
|
196
|
-
|
|
197
|
-
# Socket.IO notifications removed - memory manager works independently
|
|
198
|
-
|
|
199
|
-
return self._validate_and_repair(content, agent_id)
|
|
200
|
-
except Exception as e:
|
|
201
|
-
self.logger.error(f"Error reading memory file for {agent_id}: {e}")
|
|
202
|
-
# Return default memory on error - never fail
|
|
203
|
-
return self._create_default_memory(agent_id)
|
|
204
|
-
|
|
205
|
-
def update_agent_memory(self, agent_id: str, section: str, new_item: str) -> bool:
|
|
206
|
-
"""Add new learning item to specified section.
|
|
207
|
-
|
|
208
|
-
WHY: Agents discover new patterns and insights during task execution that
|
|
209
|
-
should be preserved for future tasks. This method adds new learnings while
|
|
210
|
-
enforcing size limits to prevent unbounded growth.
|
|
211
|
-
|
|
212
|
-
Args:
|
|
213
|
-
agent_id: The agent identifier
|
|
214
|
-
section: The section name to add the item to
|
|
215
|
-
new_item: The learning item to add
|
|
216
|
-
|
|
217
|
-
Returns:
|
|
218
|
-
bool: True if update succeeded, False otherwise
|
|
219
|
-
"""
|
|
220
|
-
try:
|
|
221
|
-
current_memory = self.load_agent_memory(agent_id)
|
|
222
|
-
updated_memory = self._add_item_to_section(current_memory, section, new_item)
|
|
223
|
-
|
|
224
|
-
# Enforce limits
|
|
225
|
-
if self._exceeds_limits(updated_memory, agent_id):
|
|
226
|
-
self.logger.debug(f"Memory for {agent_id} exceeds limits, truncating")
|
|
227
|
-
updated_memory = self._truncate_to_limits(updated_memory, agent_id)
|
|
228
|
-
|
|
229
|
-
# Save with timestamp
|
|
230
|
-
return self._save_memory_file(agent_id, updated_memory)
|
|
231
|
-
except Exception as e:
|
|
232
|
-
self.logger.error(f"Error updating memory for {agent_id}: {e}")
|
|
233
|
-
# Never fail on memory errors
|
|
234
|
-
return False
|
|
235
|
-
|
|
236
|
-
def add_learning(self, agent_id: str, learning_type: str, content: str) -> bool:
|
|
237
|
-
"""Add structured learning to appropriate section.
|
|
238
|
-
|
|
239
|
-
WHY: Different types of learnings belong in different sections for better
|
|
240
|
-
organization and retrieval. This method maps learning types to appropriate
|
|
241
|
-
sections automatically.
|
|
242
|
-
|
|
243
|
-
Args:
|
|
244
|
-
agent_id: The agent identifier
|
|
245
|
-
learning_type: Type of learning (pattern, architecture, guideline, etc.)
|
|
246
|
-
content: The learning content
|
|
247
|
-
|
|
248
|
-
Returns:
|
|
249
|
-
bool: True if learning was added successfully
|
|
250
|
-
"""
|
|
251
|
-
section_mapping = {
|
|
252
|
-
'pattern': 'Coding Patterns Learned',
|
|
253
|
-
'architecture': 'Project Architecture',
|
|
254
|
-
'guideline': 'Implementation Guidelines',
|
|
255
|
-
'mistake': 'Common Mistakes to Avoid',
|
|
256
|
-
'strategy': 'Effective Strategies',
|
|
257
|
-
'integration': 'Integration Points',
|
|
258
|
-
'performance': 'Performance Considerations',
|
|
259
|
-
'domain': 'Domain-Specific Knowledge',
|
|
260
|
-
'context': 'Current Technical Context'
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
section = section_mapping.get(learning_type, 'Recent Learnings')
|
|
264
|
-
success = self.update_agent_memory(agent_id, section, content)
|
|
265
|
-
|
|
266
|
-
# Socket.IO notifications removed - memory manager works independently
|
|
267
|
-
|
|
268
|
-
return success
|
|
269
|
-
|
|
270
|
-
def _create_default_memory(self, agent_id: str) -> str:
|
|
271
|
-
"""Create project-specific default memory file for agent.
|
|
272
|
-
|
|
273
|
-
WHY: Instead of generic templates, agents need project-specific knowledge
|
|
274
|
-
from the start. This analyzes the current project and creates contextual
|
|
275
|
-
memories with actual project characteristics.
|
|
276
|
-
|
|
277
|
-
Args:
|
|
278
|
-
agent_id: The agent identifier
|
|
279
|
-
|
|
280
|
-
Returns:
|
|
281
|
-
str: The project-specific memory template content
|
|
282
|
-
"""
|
|
283
|
-
# Convert agent_id to proper name, handling cases like "test_agent" -> "Test"
|
|
284
|
-
agent_name = agent_id.replace('_agent', '').replace('_', ' ').title()
|
|
285
|
-
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
|
286
|
-
|
|
287
|
-
# Get limits for this agent
|
|
288
|
-
limits = self._get_agent_limits(agent_id)
|
|
289
|
-
|
|
290
|
-
# Analyze the project for context-specific content
|
|
291
|
-
try:
|
|
292
|
-
project_characteristics = self.project_analyzer.analyze_project()
|
|
293
|
-
project_context = self.project_analyzer.get_project_context_summary()
|
|
294
|
-
important_files = self.project_analyzer.get_important_files_for_context()
|
|
295
|
-
|
|
296
|
-
self.logger.info(f"Creating project-specific memory for {agent_id} using analyzed project context")
|
|
297
|
-
except Exception as e:
|
|
298
|
-
self.logger.warning(f"Error analyzing project for {agent_id}, falling back to basic template: {e}")
|
|
299
|
-
return self._create_basic_memory_template(agent_id)
|
|
300
|
-
|
|
301
|
-
# Create project-specific sections
|
|
302
|
-
architecture_items = self._generate_architecture_section(project_characteristics)
|
|
303
|
-
coding_patterns = self._generate_coding_patterns_section(project_characteristics)
|
|
304
|
-
implementation_guidelines = self._generate_implementation_guidelines(project_characteristics)
|
|
305
|
-
tech_context = self._generate_technical_context(project_characteristics)
|
|
306
|
-
integration_points = self._generate_integration_points(project_characteristics)
|
|
307
|
-
|
|
308
|
-
template = f"""# {agent_name} Agent Memory - {project_characteristics.project_name}
|
|
309
|
-
|
|
310
|
-
<!-- MEMORY LIMITS: {limits['max_file_size_kb']}KB max | {limits['max_sections']} sections max | {limits['max_items_per_section']} items per section -->
|
|
311
|
-
<!-- Last Updated: {timestamp} | Auto-updated by: {agent_id} -->
|
|
312
|
-
|
|
313
|
-
## Project Context
|
|
314
|
-
{project_context}
|
|
315
|
-
|
|
316
|
-
## Project Architecture
|
|
317
|
-
{self._format_section_items(architecture_items)}
|
|
318
|
-
|
|
319
|
-
## Coding Patterns Learned
|
|
320
|
-
{self._format_section_items(coding_patterns)}
|
|
321
|
-
|
|
322
|
-
## Implementation Guidelines
|
|
323
|
-
{self._format_section_items(implementation_guidelines)}
|
|
324
|
-
|
|
325
|
-
## Domain-Specific Knowledge
|
|
326
|
-
<!-- Agent-specific knowledge for {project_characteristics.project_name} domain -->
|
|
327
|
-
{self._generate_domain_knowledge_starters(project_characteristics, agent_id)}
|
|
328
|
-
|
|
329
|
-
## Effective Strategies
|
|
330
|
-
<!-- Successful approaches discovered through experience -->
|
|
331
|
-
|
|
332
|
-
## Common Mistakes to Avoid
|
|
333
|
-
{self._format_section_items(self._generate_common_mistakes(project_characteristics))}
|
|
334
|
-
|
|
335
|
-
## Integration Points
|
|
336
|
-
{self._format_section_items(integration_points)}
|
|
337
|
-
|
|
338
|
-
## Performance Considerations
|
|
339
|
-
{self._format_section_items(self._generate_performance_considerations(project_characteristics))}
|
|
340
|
-
|
|
341
|
-
## Current Technical Context
|
|
342
|
-
{self._format_section_items(tech_context)}
|
|
343
|
-
|
|
344
|
-
## Recent Learnings
|
|
345
|
-
<!-- Most recent discoveries and insights -->
|
|
346
|
-
"""
|
|
347
|
-
|
|
348
|
-
# Save default file
|
|
349
|
-
try:
|
|
350
|
-
memory_file = self.memories_dir / f"{agent_id}_agent.md"
|
|
351
|
-
memory_file.write_text(template, encoding='utf-8')
|
|
352
|
-
self.logger.info(f"Created project-specific memory file for {agent_id}")
|
|
353
|
-
|
|
354
|
-
except Exception as e:
|
|
355
|
-
self.logger.error(f"Error saving default memory for {agent_id}: {e}")
|
|
356
|
-
|
|
357
|
-
return template
|
|
358
|
-
|
|
359
|
-
def _create_basic_memory_template(self, agent_id: str) -> str:
|
|
360
|
-
"""Create basic memory template when project analysis fails.
|
|
361
|
-
|
|
362
|
-
WHY: Fallback template ensures agents always get some memory structure
|
|
363
|
-
even if project analysis encounters errors.
|
|
364
|
-
|
|
365
|
-
Args:
|
|
366
|
-
agent_id: The agent identifier
|
|
367
|
-
|
|
368
|
-
Returns:
|
|
369
|
-
str: Basic memory template
|
|
370
|
-
"""
|
|
371
|
-
agent_name = agent_id.replace('_agent', '').replace('_', ' ').title()
|
|
372
|
-
project_name = self.project_root.name
|
|
373
|
-
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
|
374
|
-
limits = self._get_agent_limits(agent_id)
|
|
375
|
-
|
|
376
|
-
return f"""# {agent_name} Agent Memory - {project_name}
|
|
377
|
-
|
|
378
|
-
<!-- MEMORY LIMITS: {limits['max_file_size_kb']}KB max | {limits['max_sections']} sections max | {limits['max_items_per_section']} items per section -->
|
|
379
|
-
<!-- Last Updated: {timestamp} | Auto-updated by: {agent_id} -->
|
|
380
|
-
|
|
381
|
-
## Project Context
|
|
382
|
-
{project_name}: Software project requiring analysis
|
|
383
|
-
|
|
384
|
-
## Project Architecture
|
|
385
|
-
- Analyze project structure to understand architecture patterns
|
|
386
|
-
|
|
387
|
-
## Coding Patterns Learned
|
|
388
|
-
- Observe codebase patterns and conventions during tasks
|
|
389
|
-
|
|
390
|
-
## Implementation Guidelines
|
|
391
|
-
- Extract implementation guidelines from project documentation
|
|
392
|
-
|
|
393
|
-
## Domain-Specific Knowledge
|
|
394
|
-
<!-- Agent-specific knowledge accumulates here -->
|
|
395
|
-
|
|
396
|
-
## Effective Strategies
|
|
397
|
-
<!-- Successful approaches discovered through experience -->
|
|
398
|
-
|
|
399
|
-
## Common Mistakes to Avoid
|
|
400
|
-
- Learn from errors encountered during project work
|
|
401
|
-
|
|
402
|
-
## Integration Points
|
|
403
|
-
<!-- Key interfaces and integration patterns -->
|
|
404
|
-
|
|
405
|
-
## Performance Considerations
|
|
406
|
-
<!-- Performance insights and optimization patterns -->
|
|
407
|
-
|
|
408
|
-
## Current Technical Context
|
|
409
|
-
- Project analysis pending - gather context during tasks
|
|
410
|
-
|
|
411
|
-
## Recent Learnings
|
|
412
|
-
<!-- Most recent discoveries and insights -->
|
|
413
|
-
"""
|
|
414
|
-
|
|
415
|
-
def _generate_architecture_section(self, characteristics) -> List[str]:
|
|
416
|
-
"""Generate architecture section items based on project analysis."""
|
|
417
|
-
items = []
|
|
418
|
-
|
|
419
|
-
# Architecture type
|
|
420
|
-
items.append(f"{characteristics.architecture_type} with {characteristics.primary_language or 'mixed'} implementation")
|
|
421
|
-
|
|
422
|
-
# Key directories structure
|
|
423
|
-
if characteristics.key_directories:
|
|
424
|
-
key_dirs = ", ".join(characteristics.key_directories[:5])
|
|
425
|
-
items.append(f"Main directories: {key_dirs}")
|
|
426
|
-
|
|
427
|
-
# Main modules
|
|
428
|
-
if characteristics.main_modules:
|
|
429
|
-
modules = ", ".join(characteristics.main_modules[:4])
|
|
430
|
-
items.append(f"Core modules: {modules}")
|
|
431
|
-
|
|
432
|
-
# Entry points
|
|
433
|
-
if characteristics.entry_points:
|
|
434
|
-
entries = ", ".join(characteristics.entry_points[:3])
|
|
435
|
-
items.append(f"Entry points: {entries}")
|
|
436
|
-
|
|
437
|
-
# Frameworks affecting architecture
|
|
438
|
-
if characteristics.web_frameworks:
|
|
439
|
-
frameworks = ", ".join(characteristics.web_frameworks[:3])
|
|
440
|
-
items.append(f"Web framework stack: {frameworks}")
|
|
441
|
-
|
|
442
|
-
return items[:8] # Limit to prevent overwhelming
|
|
443
|
-
|
|
444
|
-
def _generate_coding_patterns_section(self, characteristics) -> List[str]:
|
|
445
|
-
"""Generate coding patterns section based on project analysis."""
|
|
446
|
-
items = []
|
|
447
|
-
|
|
448
|
-
# Language-specific patterns
|
|
449
|
-
if characteristics.primary_language == 'python':
|
|
450
|
-
items.append("Python project: use type hints, follow PEP 8 conventions")
|
|
451
|
-
if 'django' in [fw.lower() for fw in characteristics.web_frameworks]:
|
|
452
|
-
items.append("Django patterns: models, views, templates separation")
|
|
453
|
-
elif 'flask' in [fw.lower() for fw in characteristics.web_frameworks]:
|
|
454
|
-
items.append("Flask patterns: blueprint organization, app factory pattern")
|
|
455
|
-
elif characteristics.primary_language == 'node_js':
|
|
456
|
-
items.append("Node.js project: use async/await, ES6+ features")
|
|
457
|
-
if 'express' in [fw.lower() for fw in characteristics.web_frameworks]:
|
|
458
|
-
items.append("Express patterns: middleware usage, route organization")
|
|
459
|
-
|
|
460
|
-
# Framework-specific patterns
|
|
461
|
-
for framework in characteristics.frameworks[:3]:
|
|
462
|
-
if 'react' in framework.lower():
|
|
463
|
-
items.append("React patterns: component composition, hooks usage")
|
|
464
|
-
elif 'vue' in framework.lower():
|
|
465
|
-
items.append("Vue patterns: single file components, composition API")
|
|
466
|
-
|
|
467
|
-
# Code conventions found
|
|
468
|
-
for convention in characteristics.code_conventions[:3]:
|
|
469
|
-
items.append(f"Project uses: {convention}")
|
|
470
|
-
|
|
471
|
-
return items[:8]
|
|
472
|
-
|
|
473
|
-
def _generate_implementation_guidelines(self, characteristics) -> List[str]:
|
|
474
|
-
"""Generate implementation guidelines based on project analysis."""
|
|
475
|
-
items = []
|
|
476
|
-
|
|
477
|
-
# Package manager guidance
|
|
478
|
-
if characteristics.package_manager:
|
|
479
|
-
items.append(f"Use {characteristics.package_manager} for dependency management")
|
|
480
|
-
|
|
481
|
-
# Testing guidelines
|
|
482
|
-
if characteristics.testing_framework:
|
|
483
|
-
items.append(f"Write tests using {characteristics.testing_framework}")
|
|
484
|
-
|
|
485
|
-
# Test patterns
|
|
486
|
-
for pattern in characteristics.test_patterns[:2]:
|
|
487
|
-
items.append(f"Follow {pattern.lower()}")
|
|
488
|
-
|
|
489
|
-
# Build tools
|
|
490
|
-
if characteristics.build_tools:
|
|
491
|
-
tools = ", ".join(characteristics.build_tools[:2])
|
|
492
|
-
items.append(f"Use build tools: {tools}")
|
|
493
|
-
|
|
494
|
-
# Configuration patterns
|
|
495
|
-
for config_pattern in characteristics.configuration_patterns[:2]:
|
|
496
|
-
items.append(f"Configuration: {config_pattern}")
|
|
497
|
-
|
|
498
|
-
# Important files to reference
|
|
499
|
-
important_configs = characteristics.important_configs[:3]
|
|
500
|
-
if important_configs:
|
|
501
|
-
configs = ", ".join(important_configs)
|
|
502
|
-
items.append(f"Key config files: {configs}")
|
|
503
|
-
|
|
504
|
-
return items[:8]
|
|
505
|
-
|
|
506
|
-
def _generate_technical_context(self, characteristics) -> List[str]:
|
|
507
|
-
"""Generate current technical context based on project analysis."""
|
|
508
|
-
items = []
|
|
509
|
-
|
|
510
|
-
# Technology stack summary
|
|
511
|
-
tech_stack = []
|
|
512
|
-
if characteristics.primary_language:
|
|
513
|
-
tech_stack.append(characteristics.primary_language)
|
|
514
|
-
tech_stack.extend(characteristics.frameworks[:2])
|
|
515
|
-
if tech_stack:
|
|
516
|
-
items.append(f"Tech stack: {', '.join(tech_stack)}")
|
|
517
|
-
|
|
518
|
-
# Databases in use
|
|
519
|
-
if characteristics.databases:
|
|
520
|
-
dbs = ", ".join(characteristics.databases[:3])
|
|
521
|
-
items.append(f"Data storage: {dbs}")
|
|
522
|
-
|
|
523
|
-
# API patterns
|
|
524
|
-
if characteristics.api_patterns:
|
|
525
|
-
apis = ", ".join(characteristics.api_patterns[:2])
|
|
526
|
-
items.append(f"API patterns: {apis}")
|
|
527
|
-
|
|
528
|
-
# Key dependencies
|
|
529
|
-
if characteristics.key_dependencies:
|
|
530
|
-
deps = ", ".join(characteristics.key_dependencies[:4])
|
|
531
|
-
items.append(f"Key dependencies: {deps}")
|
|
532
|
-
|
|
533
|
-
# Documentation available
|
|
534
|
-
if characteristics.documentation_files:
|
|
535
|
-
docs = ", ".join(characteristics.documentation_files[:3])
|
|
536
|
-
items.append(f"Documentation: {docs}")
|
|
537
|
-
|
|
538
|
-
return items[:8]
|
|
539
|
-
|
|
540
|
-
def _generate_integration_points(self, characteristics) -> List[str]:
|
|
541
|
-
"""Generate integration points based on project analysis."""
|
|
542
|
-
items = []
|
|
543
|
-
|
|
544
|
-
# Database integrations
|
|
545
|
-
for db in characteristics.databases[:3]:
|
|
546
|
-
items.append(f"{db.title()} database integration")
|
|
547
|
-
|
|
548
|
-
# Web framework integrations
|
|
549
|
-
for framework in characteristics.web_frameworks[:2]:
|
|
550
|
-
items.append(f"{framework} web framework integration")
|
|
551
|
-
|
|
552
|
-
# API integrations
|
|
553
|
-
for api_pattern in characteristics.api_patterns[:2]:
|
|
554
|
-
items.append(f"{api_pattern} integration pattern")
|
|
555
|
-
|
|
556
|
-
# Common integration patterns based on dependencies
|
|
557
|
-
integration_deps = [dep for dep in characteristics.key_dependencies
|
|
558
|
-
if any(keyword in dep.lower() for keyword in ['redis', 'rabbit', 'celery', 'kafka', 'docker'])]
|
|
559
|
-
for dep in integration_deps[:3]:
|
|
560
|
-
items.append(f"{dep} integration")
|
|
561
|
-
|
|
562
|
-
return items[:6]
|
|
563
|
-
|
|
564
|
-
def _generate_common_mistakes(self, characteristics) -> List[str]:
|
|
565
|
-
"""Generate common mistakes based on project type and stack."""
|
|
566
|
-
items = []
|
|
567
|
-
|
|
568
|
-
# Language-specific mistakes
|
|
569
|
-
if characteristics.primary_language == 'python':
|
|
570
|
-
items.append("Avoid circular imports - use late imports when needed")
|
|
571
|
-
items.append("Don't ignore virtual environment - always activate before work")
|
|
572
|
-
elif characteristics.primary_language == 'node_js':
|
|
573
|
-
items.append("Avoid callback hell - use async/await consistently")
|
|
574
|
-
items.append("Don't commit node_modules - ensure .gitignore is correct")
|
|
575
|
-
|
|
576
|
-
# Framework-specific mistakes
|
|
577
|
-
if 'django' in [fw.lower() for fw in characteristics.web_frameworks]:
|
|
578
|
-
items.append("Don't skip migrations - always create and apply them")
|
|
579
|
-
elif 'flask' in [fw.lower() for fw in characteristics.web_frameworks]:
|
|
580
|
-
items.append("Avoid app context issues - use proper application factory")
|
|
581
|
-
|
|
582
|
-
# Database-specific mistakes
|
|
583
|
-
if characteristics.databases:
|
|
584
|
-
items.append("Don't ignore database transactions in multi-step operations")
|
|
585
|
-
items.append("Avoid N+1 queries - use proper joins or prefetching")
|
|
586
|
-
|
|
587
|
-
# Testing mistakes
|
|
588
|
-
if characteristics.testing_framework:
|
|
589
|
-
items.append("Don't skip test isolation - ensure tests can run independently")
|
|
590
|
-
|
|
591
|
-
return items[:8]
|
|
592
|
-
|
|
593
|
-
def _generate_performance_considerations(self, characteristics) -> List[str]:
|
|
594
|
-
"""Generate performance considerations based on project stack."""
|
|
595
|
-
items = []
|
|
596
|
-
|
|
597
|
-
# Language-specific performance
|
|
598
|
-
if characteristics.primary_language == 'python':
|
|
599
|
-
items.append("Use list comprehensions over loops where appropriate")
|
|
600
|
-
items.append("Consider caching for expensive operations")
|
|
601
|
-
elif characteristics.primary_language == 'node_js':
|
|
602
|
-
items.append("Leverage event loop - avoid blocking operations")
|
|
603
|
-
items.append("Use streams for large data processing")
|
|
604
|
-
|
|
605
|
-
# Database performance
|
|
606
|
-
if characteristics.databases:
|
|
607
|
-
items.append("Index frequently queried columns")
|
|
608
|
-
items.append("Use connection pooling for database connections")
|
|
609
|
-
|
|
610
|
-
# Web framework performance
|
|
611
|
-
if characteristics.web_frameworks:
|
|
612
|
-
items.append("Implement appropriate caching strategies")
|
|
613
|
-
items.append("Optimize static asset delivery")
|
|
614
|
-
|
|
615
|
-
# Framework-specific performance
|
|
616
|
-
if 'react' in [fw.lower() for fw in characteristics.frameworks]:
|
|
617
|
-
items.append("Use React.memo for expensive component renders")
|
|
618
|
-
|
|
619
|
-
return items[:6]
|
|
620
|
-
|
|
621
|
-
def _generate_domain_knowledge_starters(self, characteristics, agent_id: str) -> str:
|
|
622
|
-
"""Generate domain-specific knowledge starters based on project and agent type."""
|
|
623
|
-
items = []
|
|
624
|
-
|
|
625
|
-
# Project terminology
|
|
626
|
-
if characteristics.project_terminology:
|
|
627
|
-
terms = ", ".join(characteristics.project_terminology[:4])
|
|
628
|
-
items.append(f"- Key project terms: {terms}")
|
|
629
|
-
|
|
630
|
-
# Agent-specific starters
|
|
631
|
-
if 'research' in agent_id.lower():
|
|
632
|
-
items.append("- Focus on code analysis, pattern discovery, and architectural insights")
|
|
633
|
-
if characteristics.documentation_files:
|
|
634
|
-
items.append("- Prioritize documentation analysis for comprehensive understanding")
|
|
635
|
-
elif 'engineer' in agent_id.lower():
|
|
636
|
-
items.append("- Focus on implementation patterns, coding standards, and best practices")
|
|
637
|
-
if characteristics.testing_framework:
|
|
638
|
-
items.append(f"- Ensure test coverage using {characteristics.testing_framework}")
|
|
639
|
-
elif 'pm' in agent_id.lower() or 'manager' in agent_id.lower():
|
|
640
|
-
items.append("- Focus on project coordination, task delegation, and progress tracking")
|
|
641
|
-
items.append("- Monitor integration points and cross-component dependencies")
|
|
642
|
-
|
|
643
|
-
return '\n'.join(items) if items else "<!-- Domain knowledge will accumulate here -->"
|
|
644
|
-
|
|
645
|
-
def _format_section_items(self, items: List[str]) -> str:
|
|
646
|
-
"""Format list of items as markdown bullet points."""
|
|
647
|
-
if not items:
|
|
648
|
-
return "<!-- Items will be added as knowledge accumulates -->"
|
|
649
|
-
|
|
650
|
-
formatted_items = []
|
|
651
|
-
for item in items:
|
|
652
|
-
# Ensure each item starts with a dash and is properly formatted
|
|
653
|
-
if not item.startswith('- '):
|
|
654
|
-
item = f"- {item}"
|
|
655
|
-
formatted_items.append(item)
|
|
656
|
-
|
|
657
|
-
return '\n'.join(formatted_items)
|
|
658
|
-
|
|
659
|
-
def _add_item_to_section(self, content: str, section: str, new_item: str) -> str:
|
|
660
|
-
"""Add item to specified section, respecting limits.
|
|
661
|
-
|
|
662
|
-
WHY: Each section has a maximum item limit to prevent information overload
|
|
663
|
-
and maintain readability. When limits are reached, oldest items are removed
|
|
664
|
-
to make room for new learnings (FIFO strategy).
|
|
665
|
-
|
|
666
|
-
Args:
|
|
667
|
-
content: Current memory file content
|
|
668
|
-
section: Section name to add item to
|
|
669
|
-
new_item: Item to add
|
|
670
|
-
|
|
671
|
-
Returns:
|
|
672
|
-
str: Updated content with new item added
|
|
673
|
-
"""
|
|
674
|
-
lines = content.split('\n')
|
|
675
|
-
section_start = None
|
|
676
|
-
section_end = None
|
|
677
|
-
|
|
678
|
-
# Find section boundaries
|
|
679
|
-
for i, line in enumerate(lines):
|
|
680
|
-
if line.startswith(f'## {section}'):
|
|
681
|
-
section_start = i
|
|
682
|
-
elif section_start is not None and line.startswith('## '):
|
|
683
|
-
section_end = i
|
|
684
|
-
break
|
|
685
|
-
|
|
686
|
-
if section_start is None:
|
|
687
|
-
# Section doesn't exist, add it
|
|
688
|
-
return self._add_new_section(content, section, new_item)
|
|
689
|
-
|
|
690
|
-
if section_end is None:
|
|
691
|
-
section_end = len(lines)
|
|
692
|
-
|
|
693
|
-
# Count existing items in section and find first item index
|
|
694
|
-
item_count = 0
|
|
695
|
-
first_item_index = None
|
|
696
|
-
for i in range(section_start + 1, section_end):
|
|
697
|
-
if lines[i].strip().startswith('- '):
|
|
698
|
-
if first_item_index is None:
|
|
699
|
-
first_item_index = i
|
|
700
|
-
item_count += 1
|
|
701
|
-
|
|
702
|
-
# Check if we can add more items
|
|
703
|
-
if item_count >= self.memory_limits['max_items_per_section']:
|
|
704
|
-
# Remove oldest item (first one) to make room
|
|
705
|
-
if first_item_index is not None:
|
|
706
|
-
lines.pop(first_item_index)
|
|
707
|
-
section_end -= 1 # Adjust section end after removal
|
|
708
|
-
|
|
709
|
-
# Add new item (find insertion point after any comments)
|
|
710
|
-
insert_point = section_start + 1
|
|
711
|
-
while insert_point < section_end and (
|
|
712
|
-
not lines[insert_point].strip() or
|
|
713
|
-
lines[insert_point].strip().startswith('<!--')
|
|
714
|
-
):
|
|
715
|
-
insert_point += 1
|
|
716
|
-
|
|
717
|
-
# Ensure line length limit (account for "- " prefix)
|
|
718
|
-
max_item_length = self.memory_limits['max_line_length'] - 2 # Subtract 2 for "- " prefix
|
|
719
|
-
if len(new_item) > max_item_length:
|
|
720
|
-
new_item = new_item[:max_item_length - 3] + '...'
|
|
721
|
-
|
|
722
|
-
lines.insert(insert_point, f"- {new_item}")
|
|
723
|
-
|
|
724
|
-
# Update timestamp
|
|
725
|
-
updated_content = '\n'.join(lines)
|
|
726
|
-
return self._update_timestamp(updated_content)
|
|
727
|
-
|
|
728
|
-
def _add_new_section(self, content: str, section: str, new_item: str) -> str:
|
|
729
|
-
"""Add a new section with the given item.
|
|
730
|
-
|
|
731
|
-
WHY: When agents discover learnings that don't fit existing sections,
|
|
732
|
-
we need to create new sections dynamically while respecting the maximum
|
|
733
|
-
section limit.
|
|
734
|
-
|
|
735
|
-
Args:
|
|
736
|
-
content: Current memory content
|
|
737
|
-
section: New section name
|
|
738
|
-
new_item: First item for the section
|
|
739
|
-
|
|
740
|
-
Returns:
|
|
741
|
-
str: Updated content with new section
|
|
742
|
-
"""
|
|
743
|
-
lines = content.split('\n')
|
|
744
|
-
|
|
745
|
-
# Count existing sections
|
|
746
|
-
section_count = sum(1 for line in lines if line.startswith('## '))
|
|
747
|
-
|
|
748
|
-
if section_count >= self.memory_limits['max_sections']:
|
|
749
|
-
self.logger.warning(f"Maximum sections reached, cannot add '{section}'")
|
|
750
|
-
# Try to add to Recent Learnings instead
|
|
751
|
-
return self._add_item_to_section(content, 'Recent Learnings', new_item)
|
|
752
|
-
|
|
753
|
-
# Find insertion point (before Recent Learnings or at end)
|
|
754
|
-
insert_point = len(lines)
|
|
755
|
-
for i, line in enumerate(lines):
|
|
756
|
-
if line.startswith('## Recent Learnings'):
|
|
757
|
-
insert_point = i
|
|
758
|
-
break
|
|
759
|
-
|
|
760
|
-
# Insert new section
|
|
761
|
-
new_section = [
|
|
762
|
-
'',
|
|
763
|
-
f'## {section}',
|
|
764
|
-
f'- {new_item}',
|
|
765
|
-
''
|
|
766
|
-
]
|
|
767
|
-
|
|
768
|
-
for j, line in enumerate(new_section):
|
|
769
|
-
lines.insert(insert_point + j, line)
|
|
770
|
-
|
|
771
|
-
return '\n'.join(lines)
|
|
772
|
-
|
|
773
|
-
def _exceeds_limits(self, content: str, agent_id: Optional[str] = None) -> bool:
|
|
774
|
-
"""Check if content exceeds size limits.
|
|
775
|
-
|
|
776
|
-
Args:
|
|
777
|
-
content: Content to check
|
|
778
|
-
agent_id: Optional agent ID for agent-specific limits
|
|
779
|
-
|
|
780
|
-
Returns:
|
|
781
|
-
bool: True if content exceeds limits
|
|
782
|
-
"""
|
|
783
|
-
# Get appropriate limits based on agent
|
|
784
|
-
if agent_id:
|
|
785
|
-
limits = self._get_agent_limits(agent_id)
|
|
786
|
-
else:
|
|
787
|
-
limits = self.memory_limits
|
|
788
|
-
|
|
789
|
-
size_kb = len(content.encode('utf-8')) / 1024
|
|
790
|
-
return size_kb > limits['max_file_size_kb']
|
|
791
|
-
|
|
792
|
-
def _truncate_to_limits(self, content: str, agent_id: Optional[str] = None) -> str:
|
|
793
|
-
"""Truncate content to fit within limits.
|
|
794
|
-
|
|
795
|
-
WHY: When memory files exceed size limits, we need a strategy to reduce
|
|
796
|
-
size while preserving the most important information. This implementation
|
|
797
|
-
removes items from "Recent Learnings" first as they're typically less
|
|
798
|
-
consolidated than other sections.
|
|
799
|
-
|
|
800
|
-
Args:
|
|
801
|
-
content: Content to truncate
|
|
802
|
-
|
|
803
|
-
Returns:
|
|
804
|
-
str: Truncated content within size limits
|
|
805
|
-
"""
|
|
806
|
-
lines = content.split('\n')
|
|
807
|
-
|
|
808
|
-
# Get appropriate limits based on agent
|
|
809
|
-
if agent_id:
|
|
810
|
-
limits = self._get_agent_limits(agent_id)
|
|
811
|
-
else:
|
|
812
|
-
limits = self.memory_limits
|
|
813
|
-
|
|
814
|
-
# Strategy: Remove items from Recent Learnings first
|
|
815
|
-
while self._exceeds_limits('\n'.join(lines), agent_id):
|
|
816
|
-
removed = False
|
|
817
|
-
|
|
818
|
-
# First try Recent Learnings
|
|
819
|
-
for i, line in enumerate(lines):
|
|
820
|
-
if line.startswith('## Recent Learnings'):
|
|
821
|
-
# Find and remove first item in this section
|
|
822
|
-
for j in range(i + 1, len(lines)):
|
|
823
|
-
if lines[j].strip().startswith('- '):
|
|
824
|
-
lines.pop(j)
|
|
825
|
-
removed = True
|
|
826
|
-
break
|
|
827
|
-
elif lines[j].startswith('## '):
|
|
828
|
-
break
|
|
829
|
-
break
|
|
830
|
-
|
|
831
|
-
# If no Recent Learnings items, remove from other sections
|
|
832
|
-
if not removed:
|
|
833
|
-
# Remove from sections in reverse order (bottom up)
|
|
834
|
-
for i in range(len(lines) - 1, -1, -1):
|
|
835
|
-
if lines[i].strip().startswith('- '):
|
|
836
|
-
lines.pop(i)
|
|
837
|
-
removed = True
|
|
838
|
-
break
|
|
839
|
-
|
|
840
|
-
# Safety: If nothing removed, truncate from end
|
|
841
|
-
if not removed:
|
|
842
|
-
lines = lines[:-10]
|
|
843
|
-
|
|
844
|
-
return '\n'.join(lines)
|
|
845
|
-
|
|
846
|
-
def _update_timestamp(self, content: str) -> str:
|
|
847
|
-
"""Update the timestamp in the file header.
|
|
848
|
-
|
|
849
|
-
Args:
|
|
850
|
-
content: Content to update
|
|
851
|
-
|
|
852
|
-
Returns:
|
|
853
|
-
str: Content with updated timestamp
|
|
854
|
-
"""
|
|
855
|
-
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
|
856
|
-
return re.sub(
|
|
857
|
-
r'<!-- Last Updated: .+ \| Auto-updated by: .+ -->',
|
|
858
|
-
f'<!-- Last Updated: {timestamp} | Auto-updated by: system -->',
|
|
859
|
-
content
|
|
860
|
-
)
|
|
861
|
-
|
|
862
|
-
def _validate_and_repair(self, content: str, agent_id: str) -> str:
|
|
863
|
-
"""Validate memory file and repair if needed.
|
|
864
|
-
|
|
865
|
-
WHY: Memory files might be manually edited by developers or corrupted.
|
|
866
|
-
This method ensures the file maintains required structure and sections.
|
|
867
|
-
|
|
868
|
-
Args:
|
|
869
|
-
content: Content to validate
|
|
870
|
-
agent_id: Agent identifier
|
|
871
|
-
|
|
872
|
-
Returns:
|
|
873
|
-
str: Validated and repaired content
|
|
874
|
-
"""
|
|
875
|
-
lines = content.split('\n')
|
|
876
|
-
existing_sections = set()
|
|
877
|
-
|
|
878
|
-
# Find existing sections
|
|
879
|
-
for line in lines:
|
|
880
|
-
if line.startswith('## '):
|
|
881
|
-
section_name = line[3:].split('(')[0].strip()
|
|
882
|
-
existing_sections.add(section_name)
|
|
883
|
-
|
|
884
|
-
# Check for required sections
|
|
885
|
-
missing_sections = []
|
|
886
|
-
for required in self.REQUIRED_SECTIONS:
|
|
887
|
-
if required not in existing_sections:
|
|
888
|
-
missing_sections.append(required)
|
|
889
|
-
|
|
890
|
-
if missing_sections:
|
|
891
|
-
self.logger.info(f"Adding missing sections to {agent_id} memory: {missing_sections}")
|
|
892
|
-
|
|
893
|
-
# Add missing sections before Recent Learnings
|
|
894
|
-
insert_point = len(lines)
|
|
895
|
-
for i, line in enumerate(lines):
|
|
896
|
-
if line.startswith('## Recent Learnings'):
|
|
897
|
-
insert_point = i
|
|
898
|
-
break
|
|
899
|
-
|
|
900
|
-
for section in missing_sections:
|
|
901
|
-
section_content = [
|
|
902
|
-
'',
|
|
903
|
-
f'## {section}',
|
|
904
|
-
'<!-- Section added by repair -->',
|
|
905
|
-
''
|
|
906
|
-
]
|
|
907
|
-
for j, line in enumerate(section_content):
|
|
908
|
-
lines.insert(insert_point + j, line)
|
|
909
|
-
insert_point += len(section_content)
|
|
910
|
-
|
|
911
|
-
return '\n'.join(lines)
|
|
912
|
-
|
|
913
|
-
def _save_memory_file(self, agent_id: str, content: str) -> bool:
|
|
914
|
-
"""Save memory content to file.
|
|
915
|
-
|
|
916
|
-
WHY: Memory updates need to be persisted atomically to prevent corruption
|
|
917
|
-
and ensure learnings are preserved across agent invocations.
|
|
918
|
-
|
|
919
|
-
Args:
|
|
920
|
-
agent_id: Agent identifier
|
|
921
|
-
content: Content to save
|
|
922
|
-
|
|
923
|
-
Returns:
|
|
924
|
-
bool: True if save succeeded
|
|
925
|
-
"""
|
|
926
|
-
try:
|
|
927
|
-
memory_file = self.memories_dir / f"{agent_id}_agent.md"
|
|
928
|
-
memory_file.write_text(content, encoding='utf-8')
|
|
929
|
-
self.logger.debug(f"Saved memory for {agent_id}")
|
|
930
|
-
return True
|
|
931
|
-
except Exception as e:
|
|
932
|
-
self.logger.error(f"Error saving memory for {agent_id}: {e}")
|
|
933
|
-
return False
|
|
934
|
-
|
|
935
|
-
def optimize_memory(self, agent_id: Optional[str] = None) -> Dict[str, Any]:
|
|
936
|
-
"""Optimize agent memory by consolidating/cleaning memories.
|
|
937
|
-
|
|
938
|
-
WHY: Over time, memory files accumulate redundant or outdated information.
|
|
939
|
-
This method delegates to the memory optimizer service to clean up and
|
|
940
|
-
consolidate memories while preserving important information.
|
|
941
|
-
|
|
942
|
-
Args:
|
|
943
|
-
agent_id: Optional specific agent ID. If None, optimizes all agents.
|
|
944
|
-
|
|
945
|
-
Returns:
|
|
946
|
-
Dict containing optimization results and statistics
|
|
947
|
-
"""
|
|
948
|
-
try:
|
|
949
|
-
from claude_mpm.services.memory_optimizer import MemoryOptimizer
|
|
950
|
-
optimizer = MemoryOptimizer(self.config, self.working_directory)
|
|
951
|
-
|
|
952
|
-
if agent_id:
|
|
953
|
-
result = optimizer.optimize_agent_memory(agent_id)
|
|
954
|
-
self.logger.info(f"Optimized memory for agent: {agent_id}")
|
|
955
|
-
else:
|
|
956
|
-
result = optimizer.optimize_all_memories()
|
|
957
|
-
self.logger.info("Optimized all agent memories")
|
|
958
|
-
|
|
959
|
-
return result
|
|
960
|
-
except Exception as e:
|
|
961
|
-
self.logger.error(f"Error optimizing memory: {e}")
|
|
962
|
-
return {"success": False, "error": str(e)}
|
|
963
|
-
|
|
964
|
-
def build_memories_from_docs(self, force_rebuild: bool = False) -> Dict[str, Any]:
|
|
965
|
-
"""Build agent memories from project documentation.
|
|
966
|
-
|
|
967
|
-
WHY: Project documentation contains valuable knowledge that should be
|
|
968
|
-
extracted and assigned to appropriate agents for better context awareness.
|
|
969
|
-
|
|
970
|
-
Args:
|
|
971
|
-
force_rebuild: If True, rebuilds even if docs haven't changed
|
|
972
|
-
|
|
973
|
-
Returns:
|
|
974
|
-
Dict containing build results and statistics
|
|
975
|
-
"""
|
|
976
|
-
try:
|
|
977
|
-
from claude_mpm.services.memory_builder import MemoryBuilder
|
|
978
|
-
builder = MemoryBuilder(self.config, self.working_directory)
|
|
979
|
-
|
|
980
|
-
result = builder.build_from_documentation(force_rebuild)
|
|
981
|
-
self.logger.info("Built memories from documentation")
|
|
982
|
-
|
|
983
|
-
return result
|
|
984
|
-
except Exception as e:
|
|
985
|
-
self.logger.error(f"Error building memories from docs: {e}")
|
|
986
|
-
return {"success": False, "error": str(e)}
|
|
987
|
-
|
|
988
|
-
def route_memory_command(self, content: str, context: Optional[Dict] = None) -> Dict[str, Any]:
|
|
989
|
-
"""Route memory command to appropriate agent via PM delegation.
|
|
990
|
-
|
|
991
|
-
WHY: Memory commands like "remember this for next time" need to be analyzed
|
|
992
|
-
to determine which agent should store the information. This method provides
|
|
993
|
-
routing logic for PM agent delegation.
|
|
994
|
-
|
|
995
|
-
Args:
|
|
996
|
-
content: The content to be remembered
|
|
997
|
-
context: Optional context for routing decisions
|
|
998
|
-
|
|
999
|
-
Returns:
|
|
1000
|
-
Dict containing routing decision and reasoning
|
|
1001
|
-
"""
|
|
1002
|
-
try:
|
|
1003
|
-
from claude_mpm.services.memory_router import MemoryRouter
|
|
1004
|
-
router = MemoryRouter(self.config)
|
|
1005
|
-
|
|
1006
|
-
routing_result = router.analyze_and_route(content, context)
|
|
1007
|
-
self.logger.debug(f"Routed memory command: {routing_result['target_agent']}")
|
|
1008
|
-
|
|
1009
|
-
return routing_result
|
|
1010
|
-
except Exception as e:
|
|
1011
|
-
self.logger.error(f"Error routing memory command: {e}")
|
|
1012
|
-
return {"success": False, "error": str(e)}
|
|
1013
|
-
|
|
1014
|
-
def get_memory_status(self) -> Dict[str, Any]:
|
|
1015
|
-
"""Get comprehensive memory system status.
|
|
1016
|
-
|
|
1017
|
-
WHY: Provides detailed overview of memory system health, file sizes,
|
|
1018
|
-
optimization opportunities, and agent-specific statistics for monitoring
|
|
1019
|
-
and maintenance purposes.
|
|
1020
|
-
|
|
1021
|
-
Returns:
|
|
1022
|
-
Dict containing comprehensive memory system status
|
|
1023
|
-
"""
|
|
1024
|
-
try:
|
|
1025
|
-
status = {
|
|
1026
|
-
"system_enabled": self.memory_enabled,
|
|
1027
|
-
"auto_learning": self.auto_learning,
|
|
1028
|
-
"memory_directory": str(self.memories_dir),
|
|
1029
|
-
"total_agents": 0,
|
|
1030
|
-
"total_size_kb": 0,
|
|
1031
|
-
"agents": {},
|
|
1032
|
-
"optimization_opportunities": [],
|
|
1033
|
-
"system_health": "healthy"
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
if not self.memories_dir.exists():
|
|
1037
|
-
status["system_health"] = "no_memory_dir"
|
|
1038
|
-
return status
|
|
1039
|
-
|
|
1040
|
-
memory_files = list(self.memories_dir.glob("*_agent.md"))
|
|
1041
|
-
status["total_agents"] = len(memory_files)
|
|
1042
|
-
|
|
1043
|
-
total_size = 0
|
|
1044
|
-
for file_path in memory_files:
|
|
1045
|
-
stat = file_path.stat()
|
|
1046
|
-
size_kb = stat.st_size / 1024
|
|
1047
|
-
total_size += stat.st_size
|
|
1048
|
-
|
|
1049
|
-
agent_id = file_path.stem.replace('_agent', '')
|
|
1050
|
-
limits = self._get_agent_limits(agent_id)
|
|
1051
|
-
|
|
1052
|
-
# Analyze file content
|
|
1053
|
-
try:
|
|
1054
|
-
content = file_path.read_text()
|
|
1055
|
-
section_count = len([line for line in content.splitlines() if line.startswith('## ')])
|
|
1056
|
-
learning_count = len([line for line in content.splitlines() if line.strip().startswith('- ')])
|
|
1057
|
-
|
|
1058
|
-
agent_status = {
|
|
1059
|
-
"size_kb": round(size_kb, 2),
|
|
1060
|
-
"size_limit_kb": limits['max_file_size_kb'],
|
|
1061
|
-
"size_utilization": min(100, round((size_kb / limits['max_file_size_kb']) * 100, 1)),
|
|
1062
|
-
"sections": section_count,
|
|
1063
|
-
"items": learning_count,
|
|
1064
|
-
"last_modified": datetime.fromtimestamp(stat.st_mtime).isoformat(),
|
|
1065
|
-
"auto_learning": self._get_agent_auto_learning(agent_id)
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
# Check for optimization opportunities
|
|
1069
|
-
if size_kb > limits['max_file_size_kb'] * 0.8:
|
|
1070
|
-
status["optimization_opportunities"].append(f"{agent_id}: High memory usage ({size_kb:.1f}KB)")
|
|
1071
|
-
|
|
1072
|
-
if section_count > limits['max_sections'] * 0.8:
|
|
1073
|
-
status["optimization_opportunities"].append(f"{agent_id}: Many sections ({section_count})")
|
|
1074
|
-
|
|
1075
|
-
status["agents"][agent_id] = agent_status
|
|
1076
|
-
|
|
1077
|
-
except Exception as e:
|
|
1078
|
-
status["agents"][agent_id] = {"error": str(e)}
|
|
1079
|
-
|
|
1080
|
-
status["total_size_kb"] = round(total_size / 1024, 2)
|
|
1081
|
-
|
|
1082
|
-
# Determine overall system health
|
|
1083
|
-
if len(status["optimization_opportunities"]) > 3:
|
|
1084
|
-
status["system_health"] = "needs_optimization"
|
|
1085
|
-
elif status["total_size_kb"] > 100: # More than 100KB total
|
|
1086
|
-
status["system_health"] = "high_usage"
|
|
1087
|
-
|
|
1088
|
-
return status
|
|
1089
|
-
|
|
1090
|
-
except Exception as e:
|
|
1091
|
-
self.logger.error(f"Error getting memory status: {e}")
|
|
1092
|
-
return {"success": False, "error": str(e)}
|
|
1093
|
-
|
|
1094
|
-
def cross_reference_memories(self, query: Optional[str] = None) -> Dict[str, Any]:
|
|
1095
|
-
"""Find common patterns and cross-references across agent memories.
|
|
1096
|
-
|
|
1097
|
-
WHY: Different agents may have learned similar or related information.
|
|
1098
|
-
Cross-referencing helps identify knowledge gaps, redundancies, and
|
|
1099
|
-
opportunities for knowledge sharing between agents.
|
|
1100
|
-
|
|
1101
|
-
Args:
|
|
1102
|
-
query: Optional query to filter cross-references
|
|
1103
|
-
|
|
1104
|
-
Returns:
|
|
1105
|
-
Dict containing cross-reference analysis results
|
|
1106
|
-
"""
|
|
1107
|
-
try:
|
|
1108
|
-
cross_refs = {
|
|
1109
|
-
"common_patterns": [],
|
|
1110
|
-
"knowledge_gaps": [],
|
|
1111
|
-
"redundancies": [],
|
|
1112
|
-
"agent_correlations": {},
|
|
1113
|
-
"query_matches": [] if query else None
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
if not self.memories_dir.exists():
|
|
1117
|
-
return cross_refs
|
|
1118
|
-
|
|
1119
|
-
memory_files = list(self.memories_dir.glob("*_agent.md"))
|
|
1120
|
-
agent_memories = {}
|
|
1121
|
-
|
|
1122
|
-
# Load all agent memories
|
|
1123
|
-
for file_path in memory_files:
|
|
1124
|
-
agent_id = file_path.stem.replace('_agent', '')
|
|
1125
|
-
try:
|
|
1126
|
-
content = file_path.read_text()
|
|
1127
|
-
agent_memories[agent_id] = content
|
|
1128
|
-
except Exception as e:
|
|
1129
|
-
self.logger.warning(f"Error reading memory for {agent_id}: {e}")
|
|
1130
|
-
continue
|
|
1131
|
-
|
|
1132
|
-
# Find common patterns across agents
|
|
1133
|
-
all_lines = []
|
|
1134
|
-
agent_lines = {}
|
|
1135
|
-
|
|
1136
|
-
for agent_id, content in agent_memories.items():
|
|
1137
|
-
lines = [line.strip() for line in content.splitlines()
|
|
1138
|
-
if line.strip().startswith('- ')]
|
|
1139
|
-
agent_lines[agent_id] = lines
|
|
1140
|
-
all_lines.extend([(line, agent_id) for line in lines])
|
|
1141
|
-
|
|
1142
|
-
# Look for similar content (basic similarity check)
|
|
1143
|
-
line_counts = {}
|
|
1144
|
-
for line, agent_id in all_lines:
|
|
1145
|
-
# Normalize line for comparison
|
|
1146
|
-
normalized = line.lower().replace('- ', '').strip()
|
|
1147
|
-
if len(normalized) > 20: # Only check substantial lines
|
|
1148
|
-
if normalized not in line_counts:
|
|
1149
|
-
line_counts[normalized] = []
|
|
1150
|
-
line_counts[normalized].append(agent_id)
|
|
1151
|
-
|
|
1152
|
-
# Find patterns appearing in multiple agents
|
|
1153
|
-
for line, agents in line_counts.items():
|
|
1154
|
-
if len(set(agents)) > 1: # Appears in multiple agents
|
|
1155
|
-
cross_refs["common_patterns"].append({
|
|
1156
|
-
"pattern": line[:100] + "..." if len(line) > 100 else line,
|
|
1157
|
-
"agents": list(set(agents)),
|
|
1158
|
-
"count": len(agents)
|
|
1159
|
-
})
|
|
1160
|
-
|
|
1161
|
-
# Query-specific matches
|
|
1162
|
-
if query:
|
|
1163
|
-
query_lower = query.lower()
|
|
1164
|
-
for agent_id, content in agent_memories.items():
|
|
1165
|
-
matches = []
|
|
1166
|
-
for line in content.splitlines():
|
|
1167
|
-
if query_lower in line.lower():
|
|
1168
|
-
matches.append(line.strip())
|
|
1169
|
-
|
|
1170
|
-
if matches:
|
|
1171
|
-
cross_refs["query_matches"].append({
|
|
1172
|
-
"agent": agent_id,
|
|
1173
|
-
"matches": matches[:5] # Limit to first 5 matches
|
|
1174
|
-
})
|
|
1175
|
-
|
|
1176
|
-
# Calculate agent correlations (agents with similar knowledge domains)
|
|
1177
|
-
for agent_a in agent_memories:
|
|
1178
|
-
for agent_b in agent_memories:
|
|
1179
|
-
if agent_a < agent_b: # Avoid duplicates
|
|
1180
|
-
common_count = len([
|
|
1181
|
-
line for line in line_counts.values()
|
|
1182
|
-
if agent_a in line and agent_b in line
|
|
1183
|
-
])
|
|
1184
|
-
|
|
1185
|
-
if common_count > 0:
|
|
1186
|
-
correlation_key = f"{agent_a}+{agent_b}"
|
|
1187
|
-
cross_refs["agent_correlations"][correlation_key] = common_count
|
|
1188
|
-
|
|
1189
|
-
return cross_refs
|
|
1190
|
-
|
|
1191
|
-
except Exception as e:
|
|
1192
|
-
self.logger.error(f"Error cross-referencing memories: {e}")
|
|
1193
|
-
return {"success": False, "error": str(e)}
|
|
1194
|
-
|
|
1195
|
-
def get_all_memories_raw(self) -> Dict[str, Any]:
|
|
1196
|
-
"""Get all agent memories in structured JSON format.
|
|
1197
|
-
|
|
1198
|
-
WHY: This provides programmatic access to all agent memories, allowing
|
|
1199
|
-
external tools, scripts, or APIs to retrieve and process the complete
|
|
1200
|
-
memory state of the system.
|
|
1201
|
-
|
|
1202
|
-
DESIGN DECISION: Returns structured data with metadata for each agent
|
|
1203
|
-
including file stats, sections, and parsed content. This enables both
|
|
1204
|
-
content access and system analysis.
|
|
1205
|
-
|
|
1206
|
-
Returns:
|
|
1207
|
-
Dict containing structured memory data for all agents
|
|
1208
|
-
"""
|
|
1209
|
-
try:
|
|
1210
|
-
result = {
|
|
1211
|
-
"success": True,
|
|
1212
|
-
"timestamp": datetime.now().isoformat(),
|
|
1213
|
-
"total_agents": 0,
|
|
1214
|
-
"total_size_bytes": 0,
|
|
1215
|
-
"agents": {}
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
# Ensure directory exists
|
|
1219
|
-
if not self.memories_dir.exists():
|
|
1220
|
-
return {
|
|
1221
|
-
"success": True,
|
|
1222
|
-
"timestamp": datetime.now().isoformat(),
|
|
1223
|
-
"total_agents": 0,
|
|
1224
|
-
"total_size_bytes": 0,
|
|
1225
|
-
"agents": {},
|
|
1226
|
-
"message": "No memory directory found"
|
|
1227
|
-
}
|
|
1228
|
-
|
|
1229
|
-
# Find all agent memory files
|
|
1230
|
-
memory_files = list(self.memories_dir.glob("*_agent.md"))
|
|
1231
|
-
result["total_agents"] = len(memory_files)
|
|
1232
|
-
|
|
1233
|
-
# Process each agent memory file
|
|
1234
|
-
for file_path in sorted(memory_files):
|
|
1235
|
-
agent_id = file_path.stem.replace('_agent', '')
|
|
1236
|
-
|
|
1237
|
-
try:
|
|
1238
|
-
# Get file stats
|
|
1239
|
-
stat = file_path.stat()
|
|
1240
|
-
file_size = stat.st_size
|
|
1241
|
-
result["total_size_bytes"] += file_size
|
|
1242
|
-
|
|
1243
|
-
# Load and parse memory content
|
|
1244
|
-
memory_content = self.load_agent_memory(agent_id)
|
|
1245
|
-
|
|
1246
|
-
if memory_content:
|
|
1247
|
-
sections = self._parse_memory_content_to_dict(memory_content)
|
|
1248
|
-
|
|
1249
|
-
# Count total items across all sections
|
|
1250
|
-
total_items = sum(len(items) for items in sections.values())
|
|
1251
|
-
|
|
1252
|
-
result["agents"][agent_id] = {
|
|
1253
|
-
"agent_id": agent_id,
|
|
1254
|
-
"file_path": str(file_path),
|
|
1255
|
-
"file_size_bytes": file_size,
|
|
1256
|
-
"file_size_kb": round(file_size / 1024, 2),
|
|
1257
|
-
"last_modified": datetime.fromtimestamp(stat.st_mtime).isoformat(),
|
|
1258
|
-
"sections_count": len(sections),
|
|
1259
|
-
"total_items": total_items,
|
|
1260
|
-
"auto_learning": self._get_agent_auto_learning(agent_id),
|
|
1261
|
-
"size_limits": self._get_agent_limits(agent_id),
|
|
1262
|
-
"sections": sections,
|
|
1263
|
-
"raw_content": memory_content
|
|
1264
|
-
}
|
|
1265
|
-
else:
|
|
1266
|
-
result["agents"][agent_id] = {
|
|
1267
|
-
"agent_id": agent_id,
|
|
1268
|
-
"file_path": str(file_path),
|
|
1269
|
-
"file_size_bytes": file_size,
|
|
1270
|
-
"file_size_kb": round(file_size / 1024, 2),
|
|
1271
|
-
"last_modified": datetime.fromtimestamp(stat.st_mtime).isoformat(),
|
|
1272
|
-
"error": "Could not load memory content",
|
|
1273
|
-
"sections": {},
|
|
1274
|
-
"raw_content": ""
|
|
1275
|
-
}
|
|
1276
|
-
|
|
1277
|
-
except Exception as e:
|
|
1278
|
-
self.logger.error(f"Error processing memory for agent {agent_id}: {e}")
|
|
1279
|
-
result["agents"][agent_id] = {
|
|
1280
|
-
"agent_id": agent_id,
|
|
1281
|
-
"file_path": str(file_path),
|
|
1282
|
-
"error": str(e),
|
|
1283
|
-
"sections": {},
|
|
1284
|
-
"raw_content": ""
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
result["total_size_kb"] = round(result["total_size_bytes"] / 1024, 2)
|
|
1288
|
-
return result
|
|
1289
|
-
|
|
1290
|
-
except Exception as e:
|
|
1291
|
-
self.logger.error(f"Error getting all memories raw: {e}")
|
|
1292
|
-
return {
|
|
1293
|
-
"success": False,
|
|
1294
|
-
"error": str(e),
|
|
1295
|
-
"timestamp": datetime.now().isoformat()
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1298
|
-
def _parse_memory_content_to_dict(self, content: str) -> Dict[str, List[str]]:
|
|
1299
|
-
"""Parse memory content into structured dictionary format.
|
|
1300
|
-
|
|
1301
|
-
WHY: Provides consistent parsing of memory content into sections and items
|
|
1302
|
-
for both display and programmatic access. This ensures the same parsing
|
|
1303
|
-
logic is used across the system.
|
|
1304
|
-
|
|
1305
|
-
Args:
|
|
1306
|
-
content: Raw memory file content
|
|
1307
|
-
|
|
1308
|
-
Returns:
|
|
1309
|
-
Dict mapping section names to lists of items
|
|
1310
|
-
"""
|
|
1311
|
-
sections = {}
|
|
1312
|
-
current_section = None
|
|
1313
|
-
current_items = []
|
|
1314
|
-
|
|
1315
|
-
for line in content.split('\n'):
|
|
1316
|
-
line = line.strip()
|
|
1317
|
-
|
|
1318
|
-
# Skip empty lines and header information
|
|
1319
|
-
if not line or line.startswith('#') and 'Memory Usage' in line:
|
|
1320
|
-
continue
|
|
1321
|
-
|
|
1322
|
-
if line.startswith('## ') and not line.startswith('## Memory Usage'):
|
|
1323
|
-
# New section found
|
|
1324
|
-
if current_section and current_items:
|
|
1325
|
-
sections[current_section] = current_items.copy()
|
|
1326
|
-
|
|
1327
|
-
current_section = line[3:].strip()
|
|
1328
|
-
current_items = []
|
|
1329
|
-
|
|
1330
|
-
elif line.startswith('- ') and current_section:
|
|
1331
|
-
# Item in current section
|
|
1332
|
-
item = line[2:].strip()
|
|
1333
|
-
if item and len(item) > 3: # Filter out very short items
|
|
1334
|
-
current_items.append(item)
|
|
1335
|
-
|
|
1336
|
-
# Add final section
|
|
1337
|
-
if current_section and current_items:
|
|
1338
|
-
sections[current_section] = current_items
|
|
1339
|
-
|
|
1340
|
-
return sections
|
|
1341
|
-
|
|
1342
|
-
def _ensure_memories_directory(self):
|
|
1343
|
-
"""Ensure memories directory exists with README.
|
|
1344
|
-
|
|
1345
|
-
WHY: The memories directory needs clear documentation so developers
|
|
1346
|
-
understand the purpose of these files and how to interact with them.
|
|
1347
|
-
"""
|
|
1348
|
-
try:
|
|
1349
|
-
self.memories_dir.mkdir(parents=True, exist_ok=True)
|
|
1350
|
-
self.logger.debug(f"Ensured memories directory exists: {self.memories_dir}")
|
|
1351
|
-
|
|
1352
|
-
readme_path = self.memories_dir / "README.md"
|
|
1353
|
-
if not readme_path.exists():
|
|
1354
|
-
readme_content = """# Agent Memory System
|
|
1355
|
-
|
|
1356
|
-
## Purpose
|
|
1357
|
-
Each agent maintains project-specific knowledge in these files. Agents read their memory file before tasks and update it when they learn something new.
|
|
1358
|
-
|
|
1359
|
-
## Manual Editing
|
|
1360
|
-
Feel free to edit these files to:
|
|
1361
|
-
- Add project-specific guidelines
|
|
1362
|
-
- Remove outdated information
|
|
1363
|
-
- Reorganize for better clarity
|
|
1364
|
-
- Add domain-specific knowledge
|
|
1365
|
-
|
|
1366
|
-
## Memory Limits
|
|
1367
|
-
- Max file size: 8KB (~2000 tokens)
|
|
1368
|
-
- Max sections: 10
|
|
1369
|
-
- Max items per section: 15
|
|
1370
|
-
- Files auto-truncate when limits exceeded
|
|
1371
|
-
|
|
1372
|
-
## File Format
|
|
1373
|
-
Standard markdown with structured sections. Agents expect:
|
|
1374
|
-
- Project Architecture
|
|
1375
|
-
- Implementation Guidelines
|
|
1376
|
-
- Common Mistakes to Avoid
|
|
1377
|
-
- Current Technical Context
|
|
1378
|
-
|
|
1379
|
-
## How It Works
|
|
1380
|
-
1. Agents read their memory file before starting tasks
|
|
1381
|
-
2. Agents add learnings during or after task completion
|
|
1382
|
-
3. Files automatically enforce size limits
|
|
1383
|
-
4. Developers can manually edit for accuracy
|
|
1384
|
-
|
|
1385
|
-
## Memory File Lifecycle
|
|
1386
|
-
- Created automatically when agent first runs
|
|
1387
|
-
- Updated through hook system after delegations
|
|
1388
|
-
- Manually editable by developers
|
|
1389
|
-
- Version controlled with project
|
|
1390
|
-
"""
|
|
1391
|
-
readme_path.write_text(readme_content, encoding='utf-8')
|
|
1392
|
-
self.logger.info("Created README.md in memories directory")
|
|
1393
|
-
|
|
1394
|
-
except Exception as e:
|
|
1395
|
-
self.logger.error(f"Error ensuring memories directory: {e}")
|
|
1396
|
-
# Continue anyway - memory system should not block operations
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
# Convenience functions for external use
|
|
1400
|
-
def get_memory_manager(config: Optional[Config] = None, working_directory: Optional[Path] = None) -> AgentMemoryManager:
|
|
1401
|
-
"""Get a singleton instance of the memory manager.
|
|
1402
|
-
|
|
1403
|
-
WHY: The memory manager should be shared across the application to ensure
|
|
1404
|
-
consistent file access and avoid multiple instances managing the same files.
|
|
1405
|
-
|
|
1406
|
-
Args:
|
|
1407
|
-
config: Optional Config object. Only used on first instantiation.
|
|
1408
|
-
working_directory: Optional working directory. Only used on first instantiation.
|
|
1409
|
-
|
|
1410
|
-
Returns:
|
|
1411
|
-
AgentMemoryManager: The memory manager instance
|
|
1412
|
-
"""
|
|
1413
|
-
if not hasattr(get_memory_manager, '_instance'):
|
|
1414
|
-
get_memory_manager._instance = AgentMemoryManager(config, working_directory)
|
|
1415
|
-
return get_memory_manager._instance
|