claude-mpm 3.4.10__py3-none-any.whl → 5.4.55__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/BUILD_NUMBER +1 -0
- claude_mpm/VERSION +1 -0
- claude_mpm/__init__.py +50 -12
- claude_mpm/__main__.py +7 -2
- claude_mpm/agents/BASE_AGENT.md +164 -0
- claude_mpm/agents/BASE_ENGINEER.md +658 -0
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +290 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
- claude_mpm/agents/MEMORY.md +72 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +1402 -0
- claude_mpm/agents/WORKFLOW.md +111 -0
- claude_mpm/agents/__init__.py +92 -80
- claude_mpm/agents/agent-template.yaml +83 -0
- claude_mpm/agents/agent_loader.py +560 -745
- claude_mpm/agents/agent_loader_integration.py +53 -55
- claude_mpm/agents/agents_metadata.py +186 -27
- claude_mpm/agents/async_agent_loader.py +436 -0
- claude_mpm/agents/base_agent.json +8 -4
- claude_mpm/agents/frontmatter_validator.py +754 -0
- claude_mpm/agents/system_agent_config.py +222 -155
- claude_mpm/agents/templates/README.md +465 -0
- claude_mpm/agents/templates/__init__.py +17 -13
- claude_mpm/agents/templates/circuit-breakers.md +1391 -0
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/git-file-tracking.md +584 -0
- claude_mpm/agents/templates/pm-examples.md +474 -0
- claude_mpm/agents/templates/pm-red-flags.md +310 -0
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -0
- claude_mpm/agents/templates/response-format.md +583 -0
- claude_mpm/agents/templates/structured-questions-examples.md +615 -0
- claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
- claude_mpm/agents/templates/ticketing-examples.md +277 -0
- claude_mpm/agents/templates/validation-templates.md +312 -0
- claude_mpm/cli/__init__.py +90 -128
- claude_mpm/cli/__main__.py +33 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/__init__.py +36 -12
- claude_mpm/cli/commands/agent_manager.py +1403 -0
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +335 -0
- claude_mpm/cli/commands/agents.py +2503 -168
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/aggregate.py +540 -0
- claude_mpm/cli/commands/analyze.py +553 -0
- claude_mpm/cli/commands/analyze_code.py +528 -0
- claude_mpm/cli/commands/auto_configure.py +1053 -0
- claude_mpm/cli/commands/cleanup.py +588 -0
- claude_mpm/cli/commands/cleanup_orphaned_agents.py +150 -0
- claude_mpm/cli/commands/config.py +586 -0
- claude_mpm/cli/commands/configure.py +2654 -0
- claude_mpm/cli/commands/configure_agent_display.py +282 -0
- claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
- claude_mpm/cli/commands/configure_hook_manager.py +225 -0
- claude_mpm/cli/commands/configure_models.py +18 -0
- claude_mpm/cli/commands/configure_navigation.py +184 -0
- claude_mpm/cli/commands/configure_paths.py +104 -0
- claude_mpm/cli/commands/configure_persistence.py +254 -0
- claude_mpm/cli/commands/configure_startup_manager.py +646 -0
- claude_mpm/cli/commands/configure_template_editor.py +497 -0
- claude_mpm/cli/commands/configure_validators.py +73 -0
- claude_mpm/cli/commands/dashboard.py +286 -0
- claude_mpm/cli/commands/debug.py +1386 -0
- claude_mpm/cli/commands/doctor.py +243 -0
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/info.py +195 -74
- claude_mpm/cli/commands/local_deploy.py +534 -0
- claude_mpm/cli/commands/mcp.py +205 -0
- claude_mpm/cli/commands/mcp_command_router.py +161 -0
- claude_mpm/cli/commands/mcp_config.py +154 -0
- claude_mpm/cli/commands/mcp_config_commands.py +20 -0
- claude_mpm/cli/commands/mcp_external_commands.py +249 -0
- claude_mpm/cli/commands/mcp_install_commands.py +346 -0
- claude_mpm/cli/commands/mcp_pipx_config.py +208 -0
- claude_mpm/cli/commands/mcp_server_commands.py +155 -0
- claude_mpm/cli/commands/mcp_setup_external.py +868 -0
- claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
- claude_mpm/cli/commands/memory.py +585 -846
- claude_mpm/cli/commands/monitor.py +228 -310
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +759 -0
- claude_mpm/cli/commands/mpm_init/display.py +341 -0
- claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/modes.py +397 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +722 -0
- claude_mpm/cli/commands/mpm_init_cli.py +396 -0
- claude_mpm/cli/commands/mpm_init_handler.py +195 -0
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/profile.py +276 -0
- claude_mpm/cli/commands/run.py +910 -488
- claude_mpm/cli/commands/search.py +458 -0
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +1246 -0
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/commands/tickets.py +536 -53
- claude_mpm/cli/commands/uninstall.py +176 -0
- claude_mpm/cli/commands/upgrade.py +152 -0
- claude_mpm/cli/commands/verify.py +119 -0
- claude_mpm/cli/executor.py +297 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +21 -0
- claude_mpm/cli/interactive/agent_wizard.py +1947 -0
- claude_mpm/cli/interactive/skills_wizard.py +491 -0
- claude_mpm/cli/parser.py +87 -563
- claude_mpm/cli/parsers/__init__.py +35 -0
- claude_mpm/cli/parsers/agent_manager_parser.py +393 -0
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +575 -0
- claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
- claude_mpm/cli/parsers/analyze_parser.py +135 -0
- claude_mpm/cli/parsers/auto_configure_parser.py +120 -0
- claude_mpm/cli/parsers/base_parser.py +644 -0
- claude_mpm/cli/parsers/config_parser.py +208 -0
- claude_mpm/cli/parsers/configure_parser.py +138 -0
- claude_mpm/cli/parsers/dashboard_parser.py +113 -0
- claude_mpm/cli/parsers/debug_parser.py +319 -0
- claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
- claude_mpm/cli/parsers/mcp_parser.py +195 -0
- claude_mpm/cli/parsers/memory_parser.py +138 -0
- claude_mpm/cli/parsers/monitor_parser.py +142 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
- claude_mpm/cli/parsers/profile_parser.py +147 -0
- claude_mpm/cli/parsers/run_parser.py +157 -0
- claude_mpm/cli/parsers/search_parser.py +245 -0
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +277 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/parsers/tickets_parser.py +203 -0
- claude_mpm/cli/shared/__init__.py +40 -0
- claude_mpm/cli/shared/argument_patterns.py +205 -0
- claude_mpm/cli/shared/base_command.py +242 -0
- claude_mpm/cli/shared/error_handling.py +242 -0
- claude_mpm/cli/shared/output_formatters.py +241 -0
- claude_mpm/cli/startup.py +1743 -0
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/startup_logging.py +839 -0
- claude_mpm/cli/utils.py +136 -47
- claude_mpm/cli_module/__init__.py +6 -6
- claude_mpm/cli_module/args.py +188 -140
- claude_mpm/cli_module/commands.py +79 -70
- claude_mpm/cli_module/migration_example.py +42 -64
- claude_mpm/commands/__init__.py +14 -0
- claude_mpm/commands/mpm-config.md +28 -0
- claude_mpm/commands/mpm-doctor.md +20 -0
- claude_mpm/commands/mpm-help.md +20 -0
- claude_mpm/commands/mpm-init.md +120 -0
- claude_mpm/commands/mpm-monitor.md +31 -0
- claude_mpm/commands/mpm-organize.md +120 -0
- claude_mpm/commands/mpm-postmortem.md +21 -0
- claude_mpm/commands/mpm-session-resume.md +30 -0
- claude_mpm/commands/mpm-status.md +20 -0
- claude_mpm/commands/mpm-ticket-view.md +109 -0
- claude_mpm/commands/mpm-version.md +20 -0
- claude_mpm/commands/mpm.md +31 -0
- claude_mpm/config/__init__.py +42 -2
- claude_mpm/config/agent_config.py +402 -0
- claude_mpm/config/agent_presets.py +488 -0
- claude_mpm/config/agent_sources.py +352 -0
- claude_mpm/config/experimental_features.py +217 -0
- claude_mpm/config/model_config.py +428 -0
- claude_mpm/config/paths.py +258 -0
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/config/socketio_config.py +125 -83
- claude_mpm/constants.py +132 -22
- claude_mpm/core/__init__.py +62 -36
- claude_mpm/core/agent_name_normalizer.py +71 -73
- claude_mpm/core/agent_registry.py +385 -492
- claude_mpm/core/agent_session_manager.py +81 -70
- claude_mpm/core/api_validator.py +330 -0
- claude_mpm/core/base_service.py +159 -122
- claude_mpm/core/cache.py +560 -0
- claude_mpm/core/claude_runner.py +696 -916
- claude_mpm/core/config.py +613 -122
- claude_mpm/core/config_aliases.py +74 -73
- claude_mpm/core/config_constants.py +314 -0
- claude_mpm/core/constants.py +361 -0
- claude_mpm/core/container.py +646 -104
- claude_mpm/core/enums.py +452 -0
- claude_mpm/core/error_handler.py +623 -0
- claude_mpm/core/exceptions.py +536 -0
- claude_mpm/core/factories.py +105 -109
- claude_mpm/core/file_utils.py +764 -0
- claude_mpm/core/framework/__init__.py +25 -0
- claude_mpm/core/framework/formatters/__init__.py +11 -0
- claude_mpm/core/framework/formatters/capability_generator.py +367 -0
- claude_mpm/core/framework/formatters/content_formatter.py +278 -0
- claude_mpm/core/framework/formatters/context_generator.py +185 -0
- claude_mpm/core/framework/loaders/__init__.py +13 -0
- claude_mpm/core/framework/loaders/agent_loader.py +213 -0
- claude_mpm/core/framework/loaders/file_loader.py +176 -0
- claude_mpm/core/framework/loaders/instruction_loader.py +222 -0
- claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
- claude_mpm/core/framework/processors/__init__.py +11 -0
- claude_mpm/core/framework/processors/memory_processor.py +230 -0
- claude_mpm/core/framework/processors/metadata_processor.py +146 -0
- claude_mpm/core/framework/processors/template_processor.py +244 -0
- claude_mpm/core/framework_loader.py +485 -414
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +246 -86
- claude_mpm/core/hook_performance_config.py +147 -0
- claude_mpm/core/injectable_service.py +72 -63
- claude_mpm/core/instruction_reinforcement_hook.py +267 -0
- claude_mpm/core/interactive_session.py +670 -0
- claude_mpm/core/interfaces.py +570 -164
- claude_mpm/core/lazy.py +467 -0
- claude_mpm/core/log_manager.py +707 -0
- claude_mpm/core/logger.py +295 -134
- claude_mpm/core/logging_config.py +474 -0
- claude_mpm/core/logging_utils.py +520 -0
- claude_mpm/core/minimal_framework_loader.py +24 -22
- claude_mpm/core/mixins.py +30 -29
- claude_mpm/core/oneshot_session.py +594 -0
- claude_mpm/core/optimized_agent_loader.py +479 -0
- claude_mpm/core/optimized_startup.py +554 -0
- claude_mpm/core/output_style_manager.py +483 -0
- claude_mpm/core/pm_hook_interceptor.py +197 -82
- claude_mpm/core/protocols/__init__.py +23 -0
- claude_mpm/core/protocols/runner_protocol.py +103 -0
- claude_mpm/core/protocols/session_protocol.py +131 -0
- claude_mpm/core/service_registry.py +153 -116
- claude_mpm/core/session_manager.py +179 -64
- claude_mpm/core/shared/__init__.py +17 -0
- claude_mpm/core/shared/config_loader.py +326 -0
- claude_mpm/core/shared/path_resolver.py +281 -0
- claude_mpm/core/shared/singleton_manager.py +221 -0
- claude_mpm/core/socketio_pool.py +400 -137
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/tool_access_control.py +64 -57
- claude_mpm/core/types.py +307 -0
- claude_mpm/core/typing_utils.py +553 -0
- claude_mpm/core/unified_agent_registry.py +969 -0
- claude_mpm/core/unified_config.py +570 -0
- claude_mpm/core/unified_paths.py +941 -0
- claude_mpm/dashboard/__init__.py +12 -0
- claude_mpm/dashboard/api/simple_directory.py +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
- claude_mpm/experimental/__init__.py +10 -0
- claude_mpm/experimental/cli_enhancements.py +104 -89
- claude_mpm/generators/__init__.py +1 -1
- claude_mpm/generators/agent_profile_generator.py +76 -66
- claude_mpm/hooks/__init__.py +37 -1
- claude_mpm/hooks/base_hook.py +37 -32
- claude_mpm/hooks/claude_hooks/__init__.py +1 -1
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/connection_pool.py +250 -0
- claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +888 -0
- claude_mpm/hooks/claude_hooks/hook_handler.py +652 -875
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +10 -7
- claude_mpm/hooks/claude_hooks/installer.py +806 -0
- claude_mpm/hooks/claude_hooks/memory_integration.py +249 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +412 -0
- claude_mpm/hooks/claude_hooks/services/__init__.py +15 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +229 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +254 -0
- claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
- claude_mpm/hooks/claude_hooks/services/state_manager.py +284 -0
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
- claude_mpm/hooks/claude_hooks/tool_analysis.py +224 -0
- claude_mpm/hooks/failure_learning/__init__.py +54 -0
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
- claude_mpm/hooks/instruction_reinforcement.py +301 -0
- claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
- claude_mpm/hooks/kuzu_memory_hook.py +386 -0
- claude_mpm/hooks/kuzu_response_hook.py +179 -0
- claude_mpm/hooks/memory_integration_hook.py +201 -107
- claude_mpm/hooks/session_resume_hook.py +121 -0
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/hooks/tool_call_interceptor.py +92 -76
- claude_mpm/hooks/validation_hooks.py +62 -54
- claude_mpm/init.py +518 -83
- claude_mpm/models/__init__.py +9 -9
- claude_mpm/models/agent_definition.py +40 -23
- claude_mpm/models/agent_session.py +538 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/schemas/__init__.py +12 -0
- claude_mpm/scripts/__init__.py +15 -0
- claude_mpm/scripts/claude-hook-handler.sh +227 -0
- claude_mpm/scripts/launch_monitor.py +165 -0
- claude_mpm/scripts/mpm_doctor.py +322 -0
- claude_mpm/scripts/socketio_daemon.py +189 -200
- claude_mpm/scripts/start_activity_logging.py +91 -0
- claude_mpm/services/__init__.py +208 -39
- claude_mpm/services/agent_capabilities_service.py +266 -0
- claude_mpm/services/agents/__init__.py +89 -0
- claude_mpm/services/agents/agent_builder.py +514 -0
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_recommendation_service.py +278 -0
- claude_mpm/services/agents/agent_review_service.py +280 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -0
- claude_mpm/services/agents/auto_config_manager.py +796 -0
- claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
- claude_mpm/services/agents/cache_git_manager.py +621 -0
- claude_mpm/services/agents/deployment/__init__.py +21 -0
- claude_mpm/services/agents/deployment/agent_config_provider.py +410 -0
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +358 -0
- claude_mpm/services/agents/deployment/agent_definition_factory.py +80 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +1037 -0
- claude_mpm/services/agents/deployment/agent_discovery_service.py +546 -0
- claude_mpm/services/agents/deployment/agent_environment_manager.py +288 -0
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +383 -0
- claude_mpm/services/agents/deployment/agent_format_converter.py +505 -0
- claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +160 -0
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +957 -0
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +273 -0
- claude_mpm/services/agents/deployment/agent_operation_service.py +573 -0
- claude_mpm/services/agents/deployment/agent_record_service.py +418 -0
- claude_mpm/services/agents/deployment/agent_restore_handler.py +84 -0
- claude_mpm/services/agents/deployment/agent_state_service.py +381 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +1369 -0
- claude_mpm/services/agents/deployment/agent_validator.py +376 -0
- claude_mpm/services/agents/deployment/agent_version_manager.py +322 -0
- claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +10 -13
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +149 -0
- claude_mpm/services/agents/deployment/async_agent_deployment.py +768 -0
- claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
- claude_mpm/services/agents/deployment/config/__init__.py +13 -0
- claude_mpm/services/agents/deployment/config/deployment_config.py +181 -0
- claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
- claude_mpm/services/agents/deployment/deployment_config_loader.py +178 -0
- claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
- claude_mpm/services/agents/deployment/deployment_type_detector.py +120 -0
- claude_mpm/services/agents/deployment/deployment_wrapper.py +129 -0
- claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
- claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
- claude_mpm/services/agents/deployment/facade/deployment_executor.py +70 -0
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +269 -0
- claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
- claude_mpm/services/agents/deployment/interface_adapter.py +226 -0
- claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
- claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
- claude_mpm/services/agents/deployment/local_template_deployment.py +362 -0
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +1478 -0
- claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +162 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
- claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +240 -0
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +110 -0
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +80 -0
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +92 -0
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +101 -0
- claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +102 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
- claude_mpm/services/agents/deployment/processors/agent_processor.py +269 -0
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +311 -0
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +862 -0
- claude_mpm/services/agents/deployment/results/__init__.py +13 -0
- claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
- claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
- claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
- claude_mpm/services/agents/deployment/strategies/base_strategy.py +113 -0
- claude_mpm/services/agents/deployment/strategies/project_strategy.py +148 -0
- claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
- claude_mpm/services/agents/deployment/strategies/system_strategy.py +131 -0
- claude_mpm/services/agents/deployment/strategies/user_strategy.py +130 -0
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +228 -0
- claude_mpm/services/agents/deployment/validation/__init__.py +21 -0
- claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
- claude_mpm/services/agents/deployment/validation/template_validator.py +319 -0
- claude_mpm/services/agents/deployment/validation/validation_result.py +214 -0
- claude_mpm/services/agents/git_source_manager.py +682 -0
- claude_mpm/services/agents/loading/__init__.py +11 -0
- claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +306 -228
- claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +106 -91
- claude_mpm/services/agents/loading/framework_agent_loader.py +433 -0
- claude_mpm/services/agents/local_template_manager.py +784 -0
- claude_mpm/services/agents/management/__init__.py +9 -0
- claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +92 -69
- claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +219 -168
- claude_mpm/services/agents/memory/__init__.py +22 -0
- claude_mpm/services/agents/memory/agent_memory_manager.py +784 -0
- claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +20 -18
- claude_mpm/services/agents/memory/content_manager.py +470 -0
- claude_mpm/services/agents/memory/memory_categorization_service.py +167 -0
- claude_mpm/services/agents/memory/memory_file_service.py +129 -0
- claude_mpm/services/agents/memory/memory_format_service.py +201 -0
- claude_mpm/services/agents/memory/memory_limits_service.py +101 -0
- claude_mpm/services/agents/memory/template_generator.py +83 -0
- claude_mpm/services/agents/observers.py +547 -0
- claude_mpm/services/agents/recommender.py +617 -0
- claude_mpm/services/agents/registry/__init__.py +30 -0
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +273 -0
- claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +370 -295
- claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
- claude_mpm/services/agents/sources/__init__.py +13 -0
- claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +1202 -0
- claude_mpm/services/agents/startup_sync.py +259 -0
- claude_mpm/services/agents/toolchain_detector.py +478 -0
- claude_mpm/services/analysis/__init__.py +35 -0
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/async_session_logger.py +665 -0
- claude_mpm/services/claude_session_logger.py +321 -0
- claude_mpm/services/cli/__init__.py +18 -0
- claude_mpm/services/cli/agent_cleanup_service.py +408 -0
- claude_mpm/services/cli/agent_dependency_service.py +395 -0
- claude_mpm/services/cli/agent_listing_service.py +463 -0
- claude_mpm/services/cli/agent_output_formatter.py +605 -0
- claude_mpm/services/cli/agent_validation_service.py +590 -0
- claude_mpm/services/cli/memory_crud_service.py +622 -0
- claude_mpm/services/cli/memory_output_formatter.py +604 -0
- claude_mpm/services/cli/resume_service.py +617 -0
- claude_mpm/services/cli/session_manager.py +604 -0
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +372 -0
- claude_mpm/services/cli/startup_checker.py +362 -0
- claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
- claude_mpm/services/command_deployment_service.py +446 -0
- claude_mpm/services/command_handler_service.py +221 -0
- claude_mpm/services/communication/__init__.py +22 -0
- claude_mpm/services/core/__init__.py +108 -0
- claude_mpm/services/core/base.py +269 -0
- claude_mpm/services/core/cache_manager.py +309 -0
- claude_mpm/services/core/interfaces/__init__.py +273 -0
- claude_mpm/services/core/interfaces/agent.py +514 -0
- claude_mpm/services/core/interfaces/communication.py +316 -0
- claude_mpm/services/core/interfaces/health.py +169 -0
- claude_mpm/services/core/interfaces/infrastructure.py +357 -0
- claude_mpm/services/core/interfaces/model.py +281 -0
- claude_mpm/services/core/interfaces/process.py +372 -0
- claude_mpm/services/core/interfaces/project.py +121 -0
- claude_mpm/services/core/interfaces/restart.py +307 -0
- claude_mpm/services/core/interfaces/service.py +405 -0
- claude_mpm/services/core/interfaces/stability.py +260 -0
- claude_mpm/services/core/interfaces.py +81 -0
- claude_mpm/services/core/memory_manager.py +682 -0
- claude_mpm/services/core/models/__init__.py +70 -0
- claude_mpm/services/core/models/agent_config.py +384 -0
- claude_mpm/services/core/models/health.py +162 -0
- claude_mpm/services/core/models/process.py +239 -0
- claude_mpm/services/core/models/restart.py +302 -0
- claude_mpm/services/core/models/stability.py +264 -0
- claude_mpm/services/core/models/toolchain.py +306 -0
- claude_mpm/services/core/path_resolver.py +517 -0
- claude_mpm/services/core/service_container.py +520 -0
- claude_mpm/services/core/service_interfaces.py +436 -0
- claude_mpm/services/diagnostics/__init__.py +18 -0
- claude_mpm/services/diagnostics/checks/__init__.py +38 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +370 -0
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/base_check.py +60 -0
- claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
- claude_mpm/services/diagnostics/checks/common_issues_check.py +363 -0
- claude_mpm/services/diagnostics/checks/configuration_check.py +306 -0
- claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
- claude_mpm/services/diagnostics/checks/installation_check.py +520 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +415 -0
- claude_mpm/services/diagnostics/checks/mcp_check.py +330 -0
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
- claude_mpm/services/diagnostics/checks/monitor_check.py +281 -0
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/checks/startup_log_check.py +319 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +286 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +578 -0
- claude_mpm/services/diagnostics/models.py +138 -0
- claude_mpm/services/event_aggregator.py +582 -0
- claude_mpm/services/event_bus/__init__.py +18 -0
- claude_mpm/services/event_bus/config.py +186 -0
- claude_mpm/services/event_bus/direct_relay.py +312 -0
- claude_mpm/services/event_bus/event_bus.py +396 -0
- claude_mpm/services/event_bus/relay.py +326 -0
- claude_mpm/services/events/__init__.py +44 -0
- claude_mpm/services/events/consumers/__init__.py +18 -0
- claude_mpm/services/events/consumers/dead_letter.py +306 -0
- claude_mpm/services/events/consumers/logging.py +184 -0
- claude_mpm/services/events/consumers/metrics.py +241 -0
- claude_mpm/services/events/consumers/socketio.py +377 -0
- claude_mpm/services/events/core.py +480 -0
- claude_mpm/services/events/interfaces.py +214 -0
- claude_mpm/services/events/producers/__init__.py +14 -0
- claude_mpm/services/events/producers/hook.py +269 -0
- claude_mpm/services/events/producers/system.py +329 -0
- claude_mpm/services/exceptions.py +433 -353
- claude_mpm/services/framework_claude_md_generator/__init__.py +81 -80
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +74 -67
- claude_mpm/services/framework_claude_md_generator/content_validator.py +66 -62
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +82 -60
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +36 -37
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +41 -40
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +15 -15
- claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +5 -4
- claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
- claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +5 -4
- claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
- claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +26 -30
- claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
- claude_mpm/services/framework_claude_md_generator/version_manager.py +31 -30
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +579 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/hook_installer_service.py +506 -0
- claude_mpm/services/hook_service.py +159 -111
- claude_mpm/services/infrastructure/__init__.py +52 -0
- claude_mpm/services/infrastructure/context_preservation.py +569 -0
- claude_mpm/services/infrastructure/daemon_manager.py +279 -0
- claude_mpm/services/infrastructure/logging.py +209 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +39 -0
- claude_mpm/services/infrastructure/monitoring/aggregator.py +432 -0
- claude_mpm/services/infrastructure/monitoring/base.py +122 -0
- claude_mpm/services/infrastructure/monitoring/legacy.py +203 -0
- claude_mpm/services/infrastructure/monitoring/network.py +219 -0
- claude_mpm/services/infrastructure/monitoring/process.py +343 -0
- claude_mpm/services/infrastructure/monitoring/resources.py +244 -0
- claude_mpm/services/infrastructure/monitoring/service.py +368 -0
- claude_mpm/services/infrastructure/monitoring.py +71 -0
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/instructions/__init__.py +9 -0
- claude_mpm/services/instructions/instruction_cache_service.py +374 -0
- claude_mpm/services/local_ops/__init__.py +155 -0
- claude_mpm/services/local_ops/crash_detector.py +257 -0
- claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
- claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
- claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
- claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
- claude_mpm/services/local_ops/health_manager.py +427 -0
- claude_mpm/services/local_ops/log_monitor.py +396 -0
- claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
- claude_mpm/services/local_ops/process_manager.py +595 -0
- claude_mpm/services/local_ops/resource_monitor.py +331 -0
- claude_mpm/services/local_ops/restart_manager.py +401 -0
- claude_mpm/services/local_ops/restart_policy.py +387 -0
- claude_mpm/services/local_ops/state_manager.py +372 -0
- claude_mpm/services/local_ops/unified_manager.py +600 -0
- claude_mpm/services/mcp_config_manager.py +1542 -0
- claude_mpm/services/mcp_service_verifier.py +732 -0
- claude_mpm/services/memory/__init__.py +19 -0
- claude_mpm/services/{memory_builder.py → memory/builder.py} +465 -373
- claude_mpm/services/memory/cache/__init__.py +14 -0
- claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +237 -200
- claude_mpm/services/memory/cache/simple_cache.py +331 -0
- claude_mpm/services/memory/failure_tracker.py +578 -0
- claude_mpm/services/memory/indexed_memory.py +648 -0
- claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +272 -243
- claude_mpm/services/memory/router.py +951 -0
- claude_mpm/services/memory_hook_service.py +470 -0
- claude_mpm/services/model/__init__.py +147 -0
- claude_mpm/services/model/base_provider.py +365 -0
- claude_mpm/services/model/claude_provider.py +412 -0
- claude_mpm/services/model/model_router.py +452 -0
- claude_mpm/services/model/ollama_provider.py +415 -0
- claude_mpm/services/monitor/__init__.py +20 -0
- claude_mpm/services/monitor/daemon.py +698 -0
- claude_mpm/services/monitor/daemon_manager.py +1076 -0
- claude_mpm/services/monitor/event_emitter.py +350 -0
- claude_mpm/services/monitor/handlers/__init__.py +21 -0
- claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
- claude_mpm/services/monitor/handlers/dashboard.py +299 -0
- claude_mpm/services/monitor/handlers/file.py +264 -0
- claude_mpm/services/monitor/handlers/hooks.py +512 -0
- claude_mpm/services/monitor/management/__init__.py +18 -0
- claude_mpm/services/monitor/management/health.py +124 -0
- claude_mpm/services/monitor/management/lifecycle.py +730 -0
- claude_mpm/services/monitor/server.py +1493 -0
- claude_mpm/services/monitor_build_service.py +349 -0
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/orphan_detection.py +786 -0
- claude_mpm/services/pm_skills_deployer.py +707 -0
- claude_mpm/services/port_manager.py +597 -0
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/profile_manager.py +337 -0
- claude_mpm/services/project/__init__.py +44 -0
- claude_mpm/services/{project_analyzer.py → project/analyzer.py} +541 -291
- claude_mpm/services/project/analyzer_v2.py +566 -0
- claude_mpm/services/project/architecture_analyzer.py +461 -0
- claude_mpm/services/project/archive_manager.py +1045 -0
- claude_mpm/services/project/dependency_analyzer.py +462 -0
- claude_mpm/services/project/detection_strategies.py +719 -0
- claude_mpm/services/project/documentation_manager.py +554 -0
- claude_mpm/services/project/enhanced_analyzer.py +572 -0
- claude_mpm/services/project/language_analyzer.py +265 -0
- claude_mpm/services/project/metrics_collector.py +407 -0
- claude_mpm/services/project/project_organizer.py +1009 -0
- claude_mpm/services/project/registry.py +636 -0
- claude_mpm/services/project/toolchain_analyzer.py +583 -0
- claude_mpm/services/project_port_allocator.py +596 -0
- claude_mpm/services/recovery_manager.py +293 -240
- claude_mpm/services/response_tracker.py +267 -0
- claude_mpm/services/runner_configuration_service.py +605 -0
- claude_mpm/services/self_upgrade_service.py +608 -0
- claude_mpm/services/session_management_service.py +314 -0
- claude_mpm/services/session_manager.py +380 -0
- claude_mpm/services/shared/__init__.py +21 -0
- claude_mpm/services/shared/async_service_base.py +216 -0
- claude_mpm/services/shared/config_service_base.py +301 -0
- claude_mpm/services/shared/lifecycle_service_base.py +308 -0
- claude_mpm/services/shared/manager_base.py +315 -0
- claude_mpm/services/shared/service_factory.py +309 -0
- claude_mpm/services/skills/__init__.py +21 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1324 -0
- claude_mpm/services/skills/selective_skill_deployer.py +744 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +1168 -0
- claude_mpm/services/socketio/__init__.py +25 -0
- claude_mpm/services/socketio/client_proxy.py +229 -0
- claude_mpm/services/socketio/dashboard_server.py +362 -0
- claude_mpm/services/socketio/event_normalizer.py +798 -0
- claude_mpm/services/socketio/handlers/__init__.py +30 -0
- claude_mpm/services/socketio/handlers/base.py +136 -0
- claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
- claude_mpm/services/socketio/handlers/connection.py +643 -0
- claude_mpm/services/socketio/handlers/connection_handler.py +333 -0
- claude_mpm/services/socketio/handlers/file.py +263 -0
- claude_mpm/services/socketio/handlers/git.py +962 -0
- claude_mpm/services/socketio/handlers/hook.py +211 -0
- claude_mpm/services/socketio/handlers/memory.py +26 -0
- claude_mpm/services/socketio/handlers/project.py +24 -0
- claude_mpm/services/socketio/handlers/registry.py +214 -0
- claude_mpm/services/socketio/migration_utils.py +343 -0
- claude_mpm/services/socketio/monitor_client.py +364 -0
- claude_mpm/services/socketio/server/__init__.py +18 -0
- claude_mpm/services/socketio/server/broadcaster.py +569 -0
- claude_mpm/services/socketio/server/connection_manager.py +579 -0
- claude_mpm/services/socketio/server/core.py +1079 -0
- claude_mpm/services/socketio/server/eventbus_integration.py +245 -0
- claude_mpm/services/socketio/server/main.py +501 -0
- claude_mpm/services/socketio_client_manager.py +173 -143
- claude_mpm/services/socketio_server.py +38 -1657
- claude_mpm/services/subprocess_launcher_service.py +322 -0
- claude_mpm/services/system_instructions_service.py +270 -0
- claude_mpm/services/ticket_manager.py +25 -209
- claude_mpm/services/ticket_services/__init__.py +26 -0
- claude_mpm/services/ticket_services/crud_service.py +328 -0
- claude_mpm/services/ticket_services/formatter_service.py +290 -0
- claude_mpm/services/ticket_services/search_service.py +324 -0
- claude_mpm/services/ticket_services/validation_service.py +303 -0
- claude_mpm/services/ticket_services/workflow_service.py +244 -0
- claude_mpm/services/unified/__init__.py +65 -0
- claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
- claude_mpm/services/unified/config_strategies/__init__.py +175 -0
- claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
- claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
- claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
- claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
- claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
- claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
- claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
- claude_mpm/services/unified/deployment_strategies/base.py +553 -0
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
- claude_mpm/services/unified/deployment_strategies/local.py +607 -0
- claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
- claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
- claude_mpm/services/unified/interfaces.py +475 -0
- claude_mpm/services/unified/migration.py +509 -0
- claude_mpm/services/unified/strategies.py +534 -0
- claude_mpm/services/unified/unified_analyzer.py +542 -0
- claude_mpm/services/unified/unified_config.py +691 -0
- claude_mpm/services/unified/unified_deployment.py +466 -0
- claude_mpm/services/utility_service.py +280 -0
- claude_mpm/services/version_control/__init__.py +34 -37
- claude_mpm/services/version_control/branch_strategy.py +26 -17
- claude_mpm/services/version_control/conflict_resolution.py +52 -36
- claude_mpm/services/version_control/git_operations.py +183 -49
- claude_mpm/services/version_control/semantic_versioning.py +172 -61
- claude_mpm/services/version_control/version_parser.py +546 -0
- claude_mpm/services/version_service.py +379 -0
- claude_mpm/services/visualization/__init__.py +15 -0
- claude_mpm/services/visualization/mermaid_generator.py +937 -0
- claude_mpm/skills/__init__.py +42 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
- claude_mpm/skills/bundled/__init__.py +6 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +573 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/security-scanning.md +439 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +286 -0
- claude_mpm/skills/skill_manager.py +405 -0
- claude_mpm/skills/skills_registry.py +347 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/storage/__init__.py +9 -0
- claude_mpm/storage/state_storage.py +546 -0
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/templates/questions/__init__.py +38 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +311 -0
- claude_mpm/templates/questions/project_init.py +385 -0
- claude_mpm/templates/questions/ticket_mgmt.py +394 -0
- claude_mpm/ticket_wrapper.py +2 -2
- claude_mpm/tools/__init__.py +10 -0
- claude_mpm/tools/__main__.py +208 -0
- claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
- claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
- claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
- claude_mpm/tools/code_tree_analyzer/core.py +380 -0
- claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
- claude_mpm/tools/code_tree_analyzer/events.py +168 -0
- claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
- claude_mpm/tools/code_tree_analyzer/models.py +39 -0
- claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
- claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
- claude_mpm/tools/code_tree_builder.py +631 -0
- claude_mpm/tools/code_tree_events.py +420 -0
- claude_mpm/tools/socketio_debug.py +671 -0
- claude_mpm/utils/__init__.py +8 -8
- claude_mpm/utils/agent_dependency_loader.py +1090 -0
- claude_mpm/utils/agent_filters.py +261 -0
- claude_mpm/utils/common.py +544 -0
- claude_mpm/utils/config_manager.py +168 -126
- claude_mpm/utils/console.py +11 -0
- claude_mpm/utils/database_connector.py +298 -0
- claude_mpm/utils/dependency_cache.py +373 -0
- claude_mpm/utils/dependency_manager.py +60 -59
- claude_mpm/utils/dependency_strategies.py +381 -0
- claude_mpm/utils/display_helper.py +260 -0
- claude_mpm/utils/environment_context.py +313 -0
- claude_mpm/utils/error_handler.py +78 -66
- claude_mpm/utils/file_utils.py +305 -0
- claude_mpm/utils/framework_detection.py +12 -11
- claude_mpm/utils/git_analyzer.py +407 -0
- claude_mpm/utils/gitignore.py +244 -0
- claude_mpm/utils/import_migration_example.py +12 -60
- claude_mpm/utils/imports.py +48 -45
- claude_mpm/utils/log_cleanup.py +627 -0
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/path_operations.py +110 -104
- claude_mpm/utils/progress.py +387 -0
- claude_mpm/utils/robust_installer.py +823 -0
- claude_mpm/utils/session_logging.py +121 -0
- claude_mpm/utils/structured_questions.py +619 -0
- claude_mpm/utils/subprocess_utils.py +343 -0
- claude_mpm/validation/__init__.py +1 -1
- claude_mpm/validation/agent_validator.py +214 -108
- claude_mpm/validation/frontmatter_validator.py +252 -0
- claude_mpm-5.4.55.dist-info/METADATA +999 -0
- claude_mpm-5.4.55.dist-info/RECORD +868 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/entry_points.txt +1 -3
- claude_mpm-5.4.55.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.55.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -88
- claude_mpm/agents/INSTRUCTIONS.md +0 -352
- claude_mpm/agents/backups/INSTRUCTIONS.md +0 -352
- claude_mpm/agents/base_agent_loader.py +0 -529
- claude_mpm/agents/schema/agent_schema.json +0 -314
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -36
- claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/documentation_agent_20250726_234551.json +0 -45
- claude_mpm/agents/templates/backup/engineer_agent_20250726_234551.json +0 -49
- claude_mpm/agents/templates/backup/ops_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/qa_agent_20250726_234551.json +0 -45
- claude_mpm/agents/templates/backup/research_agent_20250726_234551.json +0 -49
- claude_mpm/agents/templates/backup/security_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/version_control_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/data_engineer.json +0 -110
- claude_mpm/agents/templates/documentation.json +0 -109
- claude_mpm/agents/templates/engineer.json +0 -113
- claude_mpm/agents/templates/ops.json +0 -109
- claude_mpm/agents/templates/pm.json +0 -25
- claude_mpm/agents/templates/qa.json +0 -111
- claude_mpm/agents/templates/research.json +0 -65
- claude_mpm/agents/templates/security.json +0 -113
- claude_mpm/agents/templates/test_integration.json +0 -112
- claude_mpm/agents/templates/version_control.json +0 -107
- claude_mpm/cli/commands/ui.py +0 -57
- claude_mpm/core/simple_runner.py +0 -1046
- claude_mpm/dashboard/open_dashboard.py +0 -34
- claude_mpm/deployment_paths.py +0 -261
- claude_mpm/hooks/builtin/__init__.py +0 -1
- claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
- claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
- claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
- claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
- claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
- claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
- claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
- claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
- claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
- claude_mpm/orchestration/__init__.py +0 -6
- claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
- claude_mpm/orchestration/archive/factory.py +0 -215
- claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
- claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
- claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
- claude_mpm/orchestration/archive/orchestrator.py +0 -501
- claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
- claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
- claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
- claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
- claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
- claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
- claude_mpm/schemas/workflow_validator.py +0 -411
- claude_mpm/services/agent_deployment.py +0 -1534
- claude_mpm/services/agent_lifecycle_manager.py +0 -1169
- claude_mpm/services/agent_memory_manager.py +0 -1415
- claude_mpm/services/agent_registry.py +0 -676
- claude_mpm/services/deployed_agent_discovery.py +0 -226
- claude_mpm/services/framework_agent_loader.py +0 -337
- claude_mpm/services/framework_claude_md_generator.py +0 -621
- claude_mpm/services/health_monitor.py +0 -892
- claude_mpm/services/memory_router.py +0 -538
- claude_mpm/services/parent_directory_manager/__init__.py +0 -577
- claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
- claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
- claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
- claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
- claude_mpm/services/parent_directory_manager/operations.py +0 -186
- claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
- claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
- claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
- claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
- claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
- claude_mpm/services/standalone_socketio_server.py +0 -1300
- claude_mpm/services/ticket_manager_di.py +0 -318
- claude_mpm/services/ticketing_service_original.py +0 -508
- claude_mpm/ui/__init__.py +0 -1
- claude_mpm/ui/rich_terminal_ui.py +0 -295
- claude_mpm/ui/terminal_ui.py +0 -328
- claude_mpm/utils/paths.py +0 -289
- claude_mpm-3.4.10.dist-info/METADATA +0 -183
- claude_mpm-3.4.10.dist-info/RECORD +0 -201
- claude_mpm-3.4.10.dist-info/licenses/LICENSE +0 -21
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/WHEEL +0 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/top_level.txt +0 -0
|
@@ -23,326 +23,356 @@ while preserving essential information.
|
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
25
|
import re
|
|
26
|
-
import
|
|
26
|
+
from datetime import datetime, timezone
|
|
27
27
|
from pathlib import Path
|
|
28
|
-
from typing import Dict, List, Optional
|
|
29
|
-
from datetime import datetime
|
|
28
|
+
from typing import Any, Dict, List, Optional
|
|
30
29
|
|
|
31
|
-
from claude_mpm.core import LoggerMixin
|
|
32
30
|
from claude_mpm.core.config import Config
|
|
33
|
-
from claude_mpm.
|
|
34
|
-
from claude_mpm.
|
|
35
|
-
from claude_mpm.
|
|
31
|
+
from claude_mpm.core.mixins import LoggerMixin
|
|
32
|
+
from claude_mpm.core.shared.config_loader import ConfigLoader
|
|
33
|
+
from claude_mpm.core.unified_paths import get_path_manager
|
|
34
|
+
from claude_mpm.services.memory.router import MemoryRouter
|
|
35
|
+
from claude_mpm.services.project.analyzer import ProjectAnalyzer
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
class MemoryBuilder(LoggerMixin):
|
|
39
39
|
"""Builds agent memories from project documentation.
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
WHY: Documentation contains patterns and guidelines that agents should know
|
|
42
42
|
about. Manual memory creation is time-consuming and prone to inconsistency.
|
|
43
43
|
This service automates the extraction and assignment process.
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
DESIGN DECISION: Uses pattern matching and content analysis to extract
|
|
46
46
|
actionable insights rather than copying raw documentation. Focuses on
|
|
47
47
|
creating learnings that will actually be useful to agents.
|
|
48
48
|
"""
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
# Documentation files to process
|
|
51
51
|
DOC_FILES = {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
"CLAUDE.md": {
|
|
53
|
+
"priority": "high",
|
|
54
|
+
"sections": ["development guidelines", "key components", "common issues"],
|
|
55
|
+
"agents": ["pm", "engineer"],
|
|
56
56
|
},
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
"docs/STRUCTURE.md": {
|
|
58
|
+
"priority": "high",
|
|
59
|
+
"sections": ["file placement", "design patterns", "directory structure"],
|
|
60
|
+
"agents": ["engineer", "documentation"],
|
|
61
61
|
},
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
"docs/QA.md": {
|
|
63
|
+
"priority": "high",
|
|
64
|
+
"sections": ["testing", "quality assurance", "validation"],
|
|
65
|
+
"agents": ["qa", "engineer"],
|
|
66
66
|
},
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
"docs/DEPLOY.md": {
|
|
68
|
+
"priority": "medium",
|
|
69
|
+
"sections": ["deployment", "versioning", "release"],
|
|
70
|
+
"agents": ["engineer", "pm"],
|
|
71
|
+
},
|
|
72
|
+
"docs/VERSIONING.md": {
|
|
73
|
+
"priority": "medium",
|
|
74
|
+
"sections": ["version management", "semantic versioning"],
|
|
75
|
+
"agents": ["engineer", "pm"],
|
|
71
76
|
},
|
|
72
|
-
'docs/VERSIONING.md': {
|
|
73
|
-
'priority': 'medium',
|
|
74
|
-
'sections': ['version management', 'semantic versioning'],
|
|
75
|
-
'agents': ['engineer', 'pm']
|
|
76
|
-
}
|
|
77
77
|
}
|
|
78
|
-
|
|
78
|
+
|
|
79
79
|
# Patterns for extracting actionable content
|
|
80
80
|
EXTRACTION_PATTERNS = {
|
|
81
|
-
|
|
82
|
-
r
|
|
83
|
-
r
|
|
84
|
-
r
|
|
81
|
+
"guidelines": [
|
|
82
|
+
r"(?:must|should|always|never|avoid|ensure|remember to)\s+(.+?)(?:\.|$)",
|
|
83
|
+
r"(?:important|note|warning|tip):\s*(.+?)(?:\.|$)",
|
|
84
|
+
r"(?:do not|don\'t)\s+(.+?)(?:\.|$)",
|
|
85
85
|
],
|
|
86
|
-
|
|
87
|
-
r
|
|
88
|
-
r
|
|
89
|
-
r
|
|
86
|
+
"patterns": [
|
|
87
|
+
r"(?:pattern|approach|strategy|method):\s*(.+?)(?:\.|$)",
|
|
88
|
+
r"(?:use|implement|follow)\s+(.+?)\s+(?:pattern|approach|for)",
|
|
89
|
+
r"(?:follows|uses|implements)\s+(.+?)\s+(?:pattern|architecture)",
|
|
90
90
|
],
|
|
91
|
-
|
|
92
|
-
r
|
|
93
|
-
r
|
|
94
|
-
r
|
|
91
|
+
"mistakes": [
|
|
92
|
+
r"(?:common\s+)?(?:mistake|error|issue|problem):\s*(.+?)(?:\.|$)",
|
|
93
|
+
r"(?:avoid|never|don\'t)\s+(.+?)(?:\.|$)",
|
|
94
|
+
r"(?:pitfall|gotcha|warning):\s*(.+?)(?:\.|$)",
|
|
95
|
+
],
|
|
96
|
+
"architecture": [
|
|
97
|
+
r"(?:architecture|structure|design):\s*(.+?)(?:\.|$)",
|
|
98
|
+
r"(?:component|service|module)\s+(.+?)\s+(?:provides|handles|manages)",
|
|
99
|
+
r"(?:uses|implements|follows)\s+(.+?)\s+(?:architecture|pattern)",
|
|
95
100
|
],
|
|
96
|
-
'architecture': [
|
|
97
|
-
r'(?:architecture|structure|design):\s*(.+?)(?:\.|$)',
|
|
98
|
-
r'(?:component|service|module)\s+(.+?)\s+(?:provides|handles|manages)',
|
|
99
|
-
r'(?:uses|implements|follows)\s+(.+?)\s+(?:architecture|pattern)'
|
|
100
|
-
]
|
|
101
101
|
}
|
|
102
|
-
|
|
103
|
-
def __init__(
|
|
102
|
+
|
|
103
|
+
def __init__(
|
|
104
|
+
self, config: Optional[Config] = None, working_directory: Optional[Path] = None
|
|
105
|
+
):
|
|
104
106
|
"""Initialize the memory builder.
|
|
105
|
-
|
|
107
|
+
|
|
106
108
|
Args:
|
|
107
109
|
config: Optional Config object
|
|
108
110
|
working_directory: Optional working directory for project-specific analysis
|
|
109
111
|
"""
|
|
110
112
|
super().__init__()
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
if config:
|
|
114
|
+
self.config = config
|
|
115
|
+
else:
|
|
116
|
+
config_loader = ConfigLoader()
|
|
117
|
+
self.config = config_loader.load_main_config()
|
|
118
|
+
self.project_root = get_path_manager().project_root
|
|
113
119
|
# Use current working directory by default, not project root
|
|
114
|
-
self.working_directory = working_directory or Path(
|
|
120
|
+
self.working_directory = working_directory or Path(Path.cwd())
|
|
115
121
|
self.memories_dir = self.working_directory / ".claude-mpm" / "memories"
|
|
116
122
|
self.router = MemoryRouter(config)
|
|
117
123
|
self.project_analyzer = ProjectAnalyzer(config, self.working_directory)
|
|
118
|
-
|
|
124
|
+
|
|
119
125
|
def _get_dynamic_doc_files(self) -> Dict[str, Dict[str, Any]]:
|
|
120
126
|
"""Get documentation files to process based on project analysis.
|
|
121
|
-
|
|
127
|
+
|
|
122
128
|
WHY: Instead of hardcoded file list, dynamically discover important files
|
|
123
129
|
based on actual project structure and characteristics.
|
|
124
|
-
|
|
130
|
+
|
|
125
131
|
Returns:
|
|
126
132
|
Dict mapping file paths to processing configuration
|
|
127
133
|
"""
|
|
128
134
|
dynamic_files = {}
|
|
129
|
-
|
|
135
|
+
|
|
130
136
|
# Start with static important files
|
|
131
137
|
static_files = self.DOC_FILES.copy()
|
|
132
|
-
|
|
138
|
+
|
|
133
139
|
# Get project-specific important files
|
|
134
140
|
try:
|
|
135
141
|
important_files = self.project_analyzer.get_important_files_for_context()
|
|
136
142
|
project_characteristics = self.project_analyzer.analyze_project()
|
|
137
|
-
|
|
143
|
+
|
|
138
144
|
# Add configuration files
|
|
139
145
|
for config_file in project_characteristics.important_configs:
|
|
140
146
|
if config_file not in static_files:
|
|
141
147
|
file_ext = Path(config_file).suffix.lower()
|
|
142
|
-
|
|
143
|
-
if file_ext in [
|
|
148
|
+
|
|
149
|
+
if file_ext in [".json", ".toml", ".yaml", ".yml"]:
|
|
144
150
|
dynamic_files[config_file] = {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
151
|
+
"priority": "medium",
|
|
152
|
+
"sections": ["configuration", "setup", "dependencies"],
|
|
153
|
+
"agents": ["engineer", "pm"],
|
|
154
|
+
"file_type": "config",
|
|
149
155
|
}
|
|
150
|
-
|
|
156
|
+
|
|
151
157
|
# Add project-specific documentation
|
|
152
158
|
for doc_file in important_files:
|
|
153
159
|
if doc_file not in static_files and doc_file not in dynamic_files:
|
|
154
160
|
file_path = Path(doc_file)
|
|
155
|
-
|
|
161
|
+
|
|
156
162
|
# Determine processing config based on file name/path
|
|
157
|
-
if
|
|
163
|
+
if "api" in doc_file.lower() or "endpoint" in doc_file.lower():
|
|
158
164
|
dynamic_files[doc_file] = {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
165
|
+
"priority": "high",
|
|
166
|
+
"sections": ["api", "endpoints", "integration"],
|
|
167
|
+
"agents": ["engineer", "integration"],
|
|
168
|
+
"file_type": "api_doc",
|
|
163
169
|
}
|
|
164
|
-
elif
|
|
170
|
+
elif (
|
|
171
|
+
"architecture" in doc_file.lower()
|
|
172
|
+
or "design" in doc_file.lower()
|
|
173
|
+
):
|
|
165
174
|
dynamic_files[doc_file] = {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
175
|
+
"priority": "high",
|
|
176
|
+
"sections": ["architecture", "design", "patterns"],
|
|
177
|
+
"agents": ["engineer", "architect"],
|
|
178
|
+
"file_type": "architecture",
|
|
170
179
|
}
|
|
171
|
-
elif
|
|
180
|
+
elif "test" in doc_file.lower():
|
|
172
181
|
dynamic_files[doc_file] = {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
182
|
+
"priority": "medium",
|
|
183
|
+
"sections": ["testing", "quality"],
|
|
184
|
+
"agents": ["qa", "engineer"],
|
|
185
|
+
"file_type": "test_doc",
|
|
177
186
|
}
|
|
178
|
-
elif file_path.suffix.lower() ==
|
|
187
|
+
elif file_path.suffix.lower() == ".md":
|
|
179
188
|
# Generic markdown file
|
|
180
189
|
dynamic_files[doc_file] = {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
190
|
+
"priority": "low",
|
|
191
|
+
"sections": ["documentation", "guidelines"],
|
|
192
|
+
"agents": ["pm", "engineer"],
|
|
193
|
+
"file_type": "markdown",
|
|
185
194
|
}
|
|
186
|
-
|
|
195
|
+
|
|
187
196
|
# Add key source files for pattern analysis (limited selection)
|
|
188
197
|
if project_characteristics.entry_points:
|
|
189
|
-
for entry_point in project_characteristics.entry_points[
|
|
198
|
+
for entry_point in project_characteristics.entry_points[
|
|
199
|
+
:2
|
|
200
|
+
]: # Only first 2
|
|
190
201
|
if entry_point not in dynamic_files:
|
|
191
202
|
dynamic_files[entry_point] = {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
203
|
+
"priority": "low",
|
|
204
|
+
"sections": ["patterns", "implementation"],
|
|
205
|
+
"agents": ["engineer"],
|
|
206
|
+
"file_type": "source",
|
|
207
|
+
"extract_patterns_only": True, # Only extract patterns, not full content
|
|
197
208
|
}
|
|
198
|
-
|
|
209
|
+
|
|
199
210
|
except Exception as e:
|
|
200
211
|
self.logger.warning(f"Error getting dynamic doc files: {e}")
|
|
201
|
-
|
|
212
|
+
|
|
202
213
|
# Merge static and dynamic files
|
|
203
214
|
all_files = {**static_files, **dynamic_files}
|
|
204
|
-
|
|
205
|
-
self.logger.debug(
|
|
215
|
+
|
|
216
|
+
self.logger.debug(
|
|
217
|
+
f"Processing {len(all_files)} documentation files ({len(static_files)} static, {len(dynamic_files)} dynamic)"
|
|
218
|
+
)
|
|
206
219
|
return all_files
|
|
207
|
-
|
|
220
|
+
|
|
208
221
|
def build_from_documentation(self, force_rebuild: bool = False) -> Dict[str, Any]:
|
|
209
222
|
"""Build agent memories from project documentation.
|
|
210
|
-
|
|
223
|
+
|
|
211
224
|
WHY: Documentation contains project-specific knowledge that agents need.
|
|
212
225
|
This method extracts and assigns relevant information to appropriate agents.
|
|
213
|
-
|
|
226
|
+
|
|
214
227
|
Args:
|
|
215
228
|
force_rebuild: If True, rebuilds even if docs haven't changed
|
|
216
|
-
|
|
229
|
+
|
|
217
230
|
Returns:
|
|
218
231
|
Dict containing build results and statistics
|
|
219
232
|
"""
|
|
220
233
|
try:
|
|
221
234
|
results = {
|
|
222
235
|
"success": True,
|
|
223
|
-
"timestamp": datetime.now().isoformat(),
|
|
236
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
224
237
|
"files_processed": 0,
|
|
225
238
|
"memories_created": 0,
|
|
226
239
|
"memories_updated": 0,
|
|
227
240
|
"agents_affected": set(),
|
|
228
241
|
"files": {},
|
|
229
|
-
"errors": []
|
|
242
|
+
"errors": [],
|
|
230
243
|
}
|
|
231
|
-
|
|
244
|
+
|
|
232
245
|
# Get dynamic list of files to process
|
|
233
246
|
doc_files = self._get_dynamic_doc_files()
|
|
234
|
-
|
|
247
|
+
|
|
235
248
|
# Process each documentation file
|
|
236
249
|
for doc_path, doc_config in doc_files.items():
|
|
237
250
|
file_path = self.project_root / doc_path
|
|
238
|
-
|
|
251
|
+
|
|
239
252
|
if not file_path.exists():
|
|
240
253
|
self.logger.debug(f"Documentation file not found: {doc_path}")
|
|
241
254
|
continue
|
|
242
|
-
|
|
255
|
+
|
|
243
256
|
# Check if rebuild is needed
|
|
244
257
|
if not force_rebuild and not self._needs_rebuild(file_path):
|
|
245
258
|
self.logger.debug(f"Skipping {doc_path} - no changes detected")
|
|
246
259
|
continue
|
|
247
|
-
|
|
260
|
+
|
|
248
261
|
file_result = self._process_documentation_file(file_path, doc_config)
|
|
249
262
|
results["files"][doc_path] = file_result
|
|
250
|
-
|
|
263
|
+
|
|
251
264
|
# Aggregate results
|
|
252
265
|
if file_result.get("success"):
|
|
253
266
|
results["files_processed"] += 1
|
|
254
|
-
results["memories_created"] += file_result.get(
|
|
255
|
-
|
|
256
|
-
|
|
267
|
+
results["memories_created"] += file_result.get(
|
|
268
|
+
"memories_created", 0
|
|
269
|
+
)
|
|
270
|
+
results["memories_updated"] += file_result.get(
|
|
271
|
+
"memories_updated", 0
|
|
272
|
+
)
|
|
273
|
+
results["agents_affected"].update(
|
|
274
|
+
file_result.get("agents_affected", [])
|
|
275
|
+
)
|
|
257
276
|
else:
|
|
258
|
-
results["errors"].append(
|
|
259
|
-
|
|
277
|
+
results["errors"].append(
|
|
278
|
+
f"{doc_path}: {file_result.get('error', 'Unknown error')}"
|
|
279
|
+
)
|
|
280
|
+
|
|
260
281
|
# Convert set to list for JSON serialization
|
|
261
282
|
results["agents_affected"] = list(results["agents_affected"])
|
|
262
283
|
results["total_agents_affected"] = len(results["agents_affected"])
|
|
263
|
-
|
|
264
|
-
self.logger.info(
|
|
284
|
+
|
|
285
|
+
self.logger.info(
|
|
286
|
+
f"Built memories from documentation: {results['files_processed']} files, {results['memories_created']} memories created"
|
|
287
|
+
)
|
|
265
288
|
return results
|
|
266
|
-
|
|
289
|
+
|
|
267
290
|
except Exception as e:
|
|
268
291
|
self.logger.error(f"Error building memories from documentation: {e}")
|
|
269
292
|
return {
|
|
270
293
|
"success": False,
|
|
271
294
|
"error": str(e),
|
|
272
|
-
"timestamp": datetime.now().isoformat()
|
|
295
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
273
296
|
}
|
|
274
|
-
|
|
297
|
+
|
|
275
298
|
def extract_from_text(self, text: str, source: str) -> List[Dict[str, Any]]:
|
|
276
299
|
"""Extract memory-worthy content from text.
|
|
277
|
-
|
|
300
|
+
|
|
278
301
|
WHY: Provides reusable text extraction logic that can be used for
|
|
279
302
|
custom documentation or other text sources beyond standard files.
|
|
280
|
-
|
|
303
|
+
|
|
281
304
|
Args:
|
|
282
305
|
text: Text content to analyze
|
|
283
306
|
source: Source identifier for context
|
|
284
|
-
|
|
307
|
+
|
|
285
308
|
Returns:
|
|
286
309
|
List of extracted memory items with metadata
|
|
287
310
|
"""
|
|
288
311
|
try:
|
|
289
312
|
extracted_items = []
|
|
290
|
-
|
|
313
|
+
|
|
291
314
|
# Process each extraction pattern type
|
|
292
315
|
for pattern_type, patterns in self.EXTRACTION_PATTERNS.items():
|
|
293
316
|
for pattern in patterns:
|
|
294
317
|
matches = re.finditer(pattern, text, re.IGNORECASE | re.MULTILINE)
|
|
295
|
-
|
|
318
|
+
|
|
296
319
|
for match in matches:
|
|
297
320
|
content = match.group(1).strip()
|
|
298
|
-
|
|
321
|
+
|
|
299
322
|
# Clean and validate content
|
|
300
323
|
content = self._clean_extracted_content(content)
|
|
301
324
|
if not self._is_valid_memory_content(content):
|
|
302
325
|
continue
|
|
303
|
-
|
|
326
|
+
|
|
304
327
|
# Route to appropriate agent
|
|
305
328
|
routing_result = self.router.analyze_and_route(content)
|
|
306
|
-
|
|
329
|
+
|
|
307
330
|
extracted_item = {
|
|
308
331
|
"content": content,
|
|
309
332
|
"type": pattern_type,
|
|
310
333
|
"source": source,
|
|
311
334
|
"target_agent": routing_result.get("target_agent", "pm"),
|
|
312
|
-
"section": routing_result.get(
|
|
335
|
+
"section": routing_result.get(
|
|
336
|
+
"section", "Recent Learnings"
|
|
337
|
+
),
|
|
313
338
|
"confidence": routing_result.get("confidence", 0.5),
|
|
314
|
-
"pattern_matched": pattern
|
|
339
|
+
"pattern_matched": pattern,
|
|
315
340
|
}
|
|
316
|
-
|
|
341
|
+
|
|
317
342
|
extracted_items.append(extracted_item)
|
|
318
|
-
|
|
343
|
+
|
|
319
344
|
# Remove near-duplicates
|
|
320
345
|
unique_items = self._deduplicate_extracted_items(extracted_items)
|
|
321
|
-
|
|
322
|
-
self.logger.debug(
|
|
346
|
+
|
|
347
|
+
self.logger.debug(
|
|
348
|
+
f"Extracted {len(unique_items)} unique items from {source}"
|
|
349
|
+
)
|
|
323
350
|
return unique_items
|
|
324
|
-
|
|
351
|
+
|
|
325
352
|
except Exception as e:
|
|
326
353
|
self.logger.error(f"Error extracting content from text: {e}")
|
|
327
354
|
return []
|
|
328
|
-
|
|
329
|
-
def build_agent_memory_from_items(
|
|
355
|
+
|
|
356
|
+
def build_agent_memory_from_items(
|
|
357
|
+
self, agent_id: str, items: List[Dict[str, Any]]
|
|
358
|
+
) -> Dict[str, Any]:
|
|
330
359
|
"""Build or update agent memory from extracted items.
|
|
331
|
-
|
|
360
|
+
|
|
332
361
|
WHY: Extracted items need to be properly integrated into agent memory
|
|
333
362
|
files while respecting existing content and size limits.
|
|
334
|
-
|
|
363
|
+
|
|
335
364
|
Args:
|
|
336
365
|
agent_id: Target agent identifier
|
|
337
366
|
items: List of extracted memory items
|
|
338
|
-
|
|
367
|
+
|
|
339
368
|
Returns:
|
|
340
369
|
Dict containing update results
|
|
341
370
|
"""
|
|
342
371
|
try:
|
|
343
|
-
from claude_mpm.services.
|
|
372
|
+
from claude_mpm.services.agents.memory import get_memory_manager
|
|
373
|
+
|
|
344
374
|
memory_manager = get_memory_manager(self.config)
|
|
345
|
-
|
|
375
|
+
|
|
346
376
|
result = {
|
|
347
377
|
"success": True,
|
|
348
378
|
"agent_id": agent_id,
|
|
@@ -350,299 +380,340 @@ class MemoryBuilder(LoggerMixin):
|
|
|
350
380
|
"items_added": 0,
|
|
351
381
|
"items_skipped": 0,
|
|
352
382
|
"sections_updated": set(),
|
|
353
|
-
"errors": []
|
|
383
|
+
"errors": [],
|
|
354
384
|
}
|
|
355
|
-
|
|
385
|
+
|
|
356
386
|
# Filter items for this agent
|
|
357
|
-
agent_items = [
|
|
358
|
-
|
|
387
|
+
agent_items = [
|
|
388
|
+
item for item in items if item.get("target_agent") == agent_id
|
|
389
|
+
]
|
|
390
|
+
|
|
359
391
|
for item in agent_items:
|
|
360
392
|
result["items_processed"] += 1
|
|
361
|
-
|
|
393
|
+
|
|
362
394
|
try:
|
|
363
395
|
# Add to memory
|
|
364
396
|
section = item.get("section", "Recent Learnings")
|
|
365
397
|
content = item.get("content", "")
|
|
366
|
-
|
|
367
|
-
success = memory_manager.update_agent_memory(
|
|
368
|
-
|
|
398
|
+
|
|
399
|
+
success = memory_manager.update_agent_memory(
|
|
400
|
+
agent_id, section, content
|
|
401
|
+
)
|
|
402
|
+
|
|
369
403
|
if success:
|
|
370
404
|
result["items_added"] += 1
|
|
371
405
|
result["sections_updated"].add(section)
|
|
372
406
|
else:
|
|
373
407
|
result["items_skipped"] += 1
|
|
374
408
|
result["errors"].append(f"Failed to add: {content[:50]}...")
|
|
375
|
-
|
|
409
|
+
|
|
376
410
|
except Exception as e:
|
|
377
411
|
result["items_skipped"] += 1
|
|
378
|
-
result["errors"].append(f"Error processing item: {
|
|
379
|
-
|
|
412
|
+
result["errors"].append(f"Error processing item: {e!s}")
|
|
413
|
+
|
|
380
414
|
# Convert set to list
|
|
381
415
|
result["sections_updated"] = list(result["sections_updated"])
|
|
382
|
-
|
|
416
|
+
|
|
383
417
|
return result
|
|
384
|
-
|
|
418
|
+
|
|
385
419
|
except Exception as e:
|
|
386
420
|
self.logger.error(f"Error building memory for {agent_id}: {e}")
|
|
387
|
-
return {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
def _extract_from_config_file(self, content: str, file_path: Path, doc_config: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
421
|
+
return {"success": False, "agent_id": agent_id, "error": str(e)}
|
|
422
|
+
|
|
423
|
+
def _extract_from_config_file(
|
|
424
|
+
self, content: str, file_path: Path, doc_config: Dict[str, Any]
|
|
425
|
+
) -> List[Dict[str, Any]]:
|
|
394
426
|
"""Extract memory-worthy information from configuration files.
|
|
395
|
-
|
|
427
|
+
|
|
396
428
|
WHY: Configuration files contain important setup patterns, dependencies,
|
|
397
429
|
and architectural decisions that agents should understand.
|
|
398
|
-
|
|
430
|
+
|
|
399
431
|
Args:
|
|
400
432
|
content: File content
|
|
401
433
|
file_path: Path to the file
|
|
402
434
|
doc_config: Processing configuration
|
|
403
|
-
|
|
435
|
+
|
|
404
436
|
Returns:
|
|
405
437
|
List of extracted memory items
|
|
406
438
|
"""
|
|
407
439
|
extracted_items = []
|
|
408
440
|
source = str(file_path.relative_to(self.project_root))
|
|
409
|
-
|
|
441
|
+
|
|
410
442
|
try:
|
|
411
443
|
file_ext = file_path.suffix.lower()
|
|
412
|
-
|
|
413
|
-
if file_ext ==
|
|
444
|
+
|
|
445
|
+
if file_ext == ".json":
|
|
414
446
|
# Parse JSON configuration
|
|
415
447
|
import json
|
|
448
|
+
|
|
416
449
|
config_data = json.loads(content)
|
|
417
450
|
items = self._extract_from_json_config(config_data, source)
|
|
418
451
|
extracted_items.extend(items)
|
|
419
|
-
|
|
420
|
-
elif file_ext in [
|
|
452
|
+
|
|
453
|
+
elif file_ext in [".toml"]:
|
|
421
454
|
# Parse TOML configuration
|
|
422
455
|
try:
|
|
423
456
|
try:
|
|
424
457
|
import tomllib
|
|
425
458
|
except ImportError:
|
|
426
459
|
import tomli as tomllib
|
|
427
|
-
with open(
|
|
460
|
+
with file_path.open("rb") as f:
|
|
428
461
|
config_data = tomllib.load(f)
|
|
429
462
|
items = self._extract_from_toml_config(config_data, source)
|
|
430
463
|
extracted_items.extend(items)
|
|
431
464
|
except ImportError:
|
|
432
465
|
self.logger.warning(f"TOML parsing not available for {source}")
|
|
433
|
-
|
|
434
|
-
elif file_ext in [
|
|
466
|
+
|
|
467
|
+
elif file_ext in [".yaml", ".yml"]:
|
|
435
468
|
# For YAML, fall back to text-based extraction for now
|
|
436
469
|
items = self.extract_from_text(content, source)
|
|
437
470
|
extracted_items.extend(items)
|
|
438
|
-
|
|
471
|
+
|
|
439
472
|
# Also extract text patterns for comments and documentation
|
|
440
473
|
text_items = self.extract_from_text(content, source)
|
|
441
474
|
extracted_items.extend(text_items)
|
|
442
|
-
|
|
475
|
+
|
|
443
476
|
except Exception as e:
|
|
444
477
|
self.logger.warning(f"Error parsing config file {source}: {e}")
|
|
445
478
|
# Fall back to text extraction
|
|
446
479
|
extracted_items = self.extract_from_text(content, source)
|
|
447
|
-
|
|
480
|
+
|
|
448
481
|
return extracted_items
|
|
449
|
-
|
|
450
|
-
def _extract_from_json_config(
|
|
482
|
+
|
|
483
|
+
def _extract_from_json_config(
|
|
484
|
+
self, config_data: dict, source: str
|
|
485
|
+
) -> List[Dict[str, Any]]:
|
|
451
486
|
"""Extract patterns from JSON configuration."""
|
|
452
487
|
items = []
|
|
453
|
-
|
|
488
|
+
|
|
454
489
|
# Extract dependencies information
|
|
455
|
-
if
|
|
456
|
-
deps = config_data[
|
|
490
|
+
if "dependencies" in config_data:
|
|
491
|
+
deps = config_data["dependencies"]
|
|
457
492
|
if isinstance(deps, dict) and deps:
|
|
458
493
|
dep_names = list(deps.keys())[:5] # Limit to prevent overwhelming
|
|
459
494
|
deps_str = ", ".join(dep_names)
|
|
460
|
-
items.append(
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
"target_agent": "engineer",
|
|
465
|
-
"section": "Current Technical Context",
|
|
466
|
-
"confidence": 0.8
|
|
467
|
-
})
|
|
468
|
-
|
|
469
|
-
# Extract scripts (for package.json)
|
|
470
|
-
if 'scripts' in config_data:
|
|
471
|
-
scripts = config_data['scripts']
|
|
472
|
-
if isinstance(scripts, dict):
|
|
473
|
-
for script_name, script_cmd in list(scripts.items())[:3]: # Limit to first 3
|
|
474
|
-
items.append({
|
|
475
|
-
"content": f"Build script '{script_name}': {script_cmd[:50]}{'...' if len(script_cmd) > 50 else ''}",
|
|
476
|
-
"type": "build_pattern",
|
|
495
|
+
items.append(
|
|
496
|
+
{
|
|
497
|
+
"content": f"Key dependencies: {deps_str}",
|
|
498
|
+
"type": "dependency_info",
|
|
477
499
|
"source": source,
|
|
478
500
|
"target_agent": "engineer",
|
|
479
|
-
"section": "
|
|
480
|
-
"confidence": 0.
|
|
481
|
-
}
|
|
482
|
-
|
|
501
|
+
"section": "Current Technical Context",
|
|
502
|
+
"confidence": 0.8,
|
|
503
|
+
}
|
|
504
|
+
)
|
|
505
|
+
|
|
506
|
+
# Extract scripts (for package.json)
|
|
507
|
+
if "scripts" in config_data:
|
|
508
|
+
scripts = config_data["scripts"]
|
|
509
|
+
if isinstance(scripts, dict):
|
|
510
|
+
for script_name, script_cmd in list(scripts.items())[
|
|
511
|
+
:3
|
|
512
|
+
]: # Limit to first 3
|
|
513
|
+
items.append(
|
|
514
|
+
{
|
|
515
|
+
"content": f"Build script '{script_name}': {script_cmd[:50]}{'...' if len(script_cmd) > 50 else ''}",
|
|
516
|
+
"type": "build_pattern",
|
|
517
|
+
"source": source,
|
|
518
|
+
"target_agent": "engineer",
|
|
519
|
+
"section": "Implementation Guidelines",
|
|
520
|
+
"confidence": 0.7,
|
|
521
|
+
}
|
|
522
|
+
)
|
|
523
|
+
|
|
483
524
|
return items
|
|
484
|
-
|
|
485
|
-
def _extract_from_toml_config(
|
|
525
|
+
|
|
526
|
+
def _extract_from_toml_config(
|
|
527
|
+
self, config_data: dict, source: str
|
|
528
|
+
) -> List[Dict[str, Any]]:
|
|
486
529
|
"""Extract patterns from TOML configuration."""
|
|
487
530
|
items = []
|
|
488
|
-
|
|
531
|
+
|
|
489
532
|
# Extract project metadata (for pyproject.toml)
|
|
490
|
-
if
|
|
491
|
-
project_info = config_data[
|
|
492
|
-
if
|
|
493
|
-
deps = project_info[
|
|
533
|
+
if "project" in config_data:
|
|
534
|
+
project_info = config_data["project"]
|
|
535
|
+
if "dependencies" in project_info:
|
|
536
|
+
deps = project_info["dependencies"]
|
|
494
537
|
if deps:
|
|
495
|
-
items.append(
|
|
496
|
-
|
|
538
|
+
items.append(
|
|
539
|
+
{
|
|
540
|
+
"content": f"Python dependencies: {', '.join(deps[:5])}",
|
|
541
|
+
"type": "dependency_info",
|
|
542
|
+
"source": source,
|
|
543
|
+
"target_agent": "engineer",
|
|
544
|
+
"section": "Current Technical Context",
|
|
545
|
+
"confidence": 0.8,
|
|
546
|
+
}
|
|
547
|
+
)
|
|
548
|
+
|
|
549
|
+
# Extract Rust dependencies (for Cargo.toml)
|
|
550
|
+
if "dependencies" in config_data:
|
|
551
|
+
deps = config_data["dependencies"]
|
|
552
|
+
if isinstance(deps, dict) and deps:
|
|
553
|
+
dep_names = list(deps.keys())[:5]
|
|
554
|
+
items.append(
|
|
555
|
+
{
|
|
556
|
+
"content": f"Rust dependencies: {', '.join(dep_names)}",
|
|
497
557
|
"type": "dependency_info",
|
|
498
558
|
"source": source,
|
|
499
559
|
"target_agent": "engineer",
|
|
500
560
|
"section": "Current Technical Context",
|
|
501
|
-
"confidence": 0.8
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
if 'dependencies' in config_data:
|
|
506
|
-
deps = config_data['dependencies']
|
|
507
|
-
if isinstance(deps, dict) and deps:
|
|
508
|
-
dep_names = list(deps.keys())[:5]
|
|
509
|
-
items.append({
|
|
510
|
-
"content": f"Rust dependencies: {', '.join(dep_names)}",
|
|
511
|
-
"type": "dependency_info",
|
|
512
|
-
"source": source,
|
|
513
|
-
"target_agent": "engineer",
|
|
514
|
-
"section": "Current Technical Context",
|
|
515
|
-
"confidence": 0.8
|
|
516
|
-
})
|
|
517
|
-
|
|
561
|
+
"confidence": 0.8,
|
|
562
|
+
}
|
|
563
|
+
)
|
|
564
|
+
|
|
518
565
|
return items
|
|
519
|
-
|
|
520
|
-
def _extract_from_source_file(
|
|
566
|
+
|
|
567
|
+
def _extract_from_source_file(
|
|
568
|
+
self, content: str, file_path: Path, doc_config: Dict[str, Any]
|
|
569
|
+
) -> List[Dict[str, Any]]:
|
|
521
570
|
"""Extract patterns from source code files.
|
|
522
|
-
|
|
571
|
+
|
|
523
572
|
WHY: Source files contain implementation patterns and architectural
|
|
524
573
|
decisions that agents should be aware of, but we only extract high-level
|
|
525
574
|
patterns rather than detailed code analysis.
|
|
526
|
-
|
|
575
|
+
|
|
527
576
|
Args:
|
|
528
577
|
content: File content
|
|
529
578
|
file_path: Path to the file
|
|
530
579
|
doc_config: Processing configuration
|
|
531
|
-
|
|
580
|
+
|
|
532
581
|
Returns:
|
|
533
582
|
List of extracted memory items
|
|
534
583
|
"""
|
|
535
584
|
extracted_items = []
|
|
536
585
|
source = str(file_path.relative_to(self.project_root))
|
|
537
|
-
|
|
586
|
+
|
|
538
587
|
# Only extract patterns if specified
|
|
539
|
-
if not doc_config.get(
|
|
588
|
+
if not doc_config.get("extract_patterns_only", False):
|
|
540
589
|
return []
|
|
541
|
-
|
|
590
|
+
|
|
542
591
|
file_ext = file_path.suffix.lower()
|
|
543
|
-
|
|
592
|
+
|
|
544
593
|
# Language-specific pattern extraction
|
|
545
|
-
if file_ext ==
|
|
594
|
+
if file_ext == ".py":
|
|
546
595
|
items = self._extract_python_patterns(content, source)
|
|
547
596
|
extracted_items.extend(items)
|
|
548
|
-
elif file_ext in [
|
|
597
|
+
elif file_ext in [".js", ".ts"]:
|
|
549
598
|
items = self._extract_javascript_patterns(content, source)
|
|
550
599
|
extracted_items.extend(items)
|
|
551
|
-
|
|
600
|
+
|
|
552
601
|
return extracted_items[:3] # Limit to prevent overwhelming
|
|
553
|
-
|
|
554
|
-
def _extract_python_patterns(
|
|
602
|
+
|
|
603
|
+
def _extract_python_patterns(
|
|
604
|
+
self, content: str, source: str
|
|
605
|
+
) -> List[Dict[str, Any]]:
|
|
555
606
|
"""Extract high-level patterns from Python source."""
|
|
556
607
|
items = []
|
|
557
|
-
|
|
608
|
+
|
|
558
609
|
# Check for common patterns
|
|
559
610
|
if 'if __name__ == "__main__"' in content:
|
|
560
|
-
items.append(
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
611
|
+
items.append(
|
|
612
|
+
{
|
|
613
|
+
"content": "Uses if __name__ == '__main__' pattern for script execution",
|
|
614
|
+
"type": "pattern",
|
|
615
|
+
"source": source,
|
|
616
|
+
"target_agent": "engineer",
|
|
617
|
+
"section": "Coding Patterns Learned",
|
|
618
|
+
"confidence": 0.8,
|
|
619
|
+
}
|
|
620
|
+
)
|
|
621
|
+
|
|
622
|
+
if "from pathlib import Path" in content:
|
|
623
|
+
items.append(
|
|
624
|
+
{
|
|
625
|
+
"content": "Uses pathlib.Path for file operations (recommended pattern)",
|
|
626
|
+
"type": "pattern",
|
|
627
|
+
"source": source,
|
|
628
|
+
"target_agent": "engineer",
|
|
629
|
+
"section": "Coding Patterns Learned",
|
|
630
|
+
"confidence": 0.7,
|
|
631
|
+
}
|
|
632
|
+
)
|
|
633
|
+
|
|
579
634
|
# Check for class definitions
|
|
580
|
-
class_matches = re.findall(r
|
|
635
|
+
class_matches = re.findall(r"class\s+(\w+)", content)
|
|
581
636
|
if class_matches:
|
|
582
|
-
items.append(
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
637
|
+
items.append(
|
|
638
|
+
{
|
|
639
|
+
"content": f"Defines classes: {', '.join(class_matches[:3])}",
|
|
640
|
+
"type": "architecture",
|
|
641
|
+
"source": source,
|
|
642
|
+
"target_agent": "engineer",
|
|
643
|
+
"section": "Project Architecture",
|
|
644
|
+
"confidence": 0.6,
|
|
645
|
+
}
|
|
646
|
+
)
|
|
647
|
+
|
|
591
648
|
return items
|
|
592
|
-
|
|
593
|
-
def _extract_javascript_patterns(
|
|
649
|
+
|
|
650
|
+
def _extract_javascript_patterns(
|
|
651
|
+
self, content: str, source: str
|
|
652
|
+
) -> List[Dict[str, Any]]:
|
|
594
653
|
"""Extract high-level patterns from JavaScript/TypeScript source."""
|
|
595
654
|
items = []
|
|
596
|
-
|
|
655
|
+
|
|
597
656
|
# Check for async patterns
|
|
598
|
-
if
|
|
599
|
-
items.append(
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
657
|
+
if "async function" in content or "async " in content:
|
|
658
|
+
items.append(
|
|
659
|
+
{
|
|
660
|
+
"content": "Uses async/await patterns for asynchronous operations",
|
|
661
|
+
"type": "pattern",
|
|
662
|
+
"source": source,
|
|
663
|
+
"target_agent": "engineer",
|
|
664
|
+
"section": "Coding Patterns Learned",
|
|
665
|
+
"confidence": 0.8,
|
|
666
|
+
}
|
|
667
|
+
)
|
|
668
|
+
|
|
608
669
|
# Check for module patterns
|
|
609
|
-
if
|
|
610
|
-
items.append(
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
670
|
+
if "export " in content:
|
|
671
|
+
items.append(
|
|
672
|
+
{
|
|
673
|
+
"content": "Uses ES6 module export patterns",
|
|
674
|
+
"type": "pattern",
|
|
675
|
+
"source": source,
|
|
676
|
+
"target_agent": "engineer",
|
|
677
|
+
"section": "Coding Patterns Learned",
|
|
678
|
+
"confidence": 0.7,
|
|
679
|
+
}
|
|
680
|
+
)
|
|
681
|
+
|
|
619
682
|
return items
|
|
620
|
-
|
|
621
|
-
def _process_documentation_file(
|
|
683
|
+
|
|
684
|
+
def _process_documentation_file(
|
|
685
|
+
self, file_path: Path, doc_config: Dict[str, Any]
|
|
686
|
+
) -> Dict[str, Any]:
|
|
622
687
|
"""Process a single documentation file with enhanced file type support.
|
|
623
|
-
|
|
688
|
+
|
|
624
689
|
Args:
|
|
625
690
|
file_path: Path to documentation file
|
|
626
691
|
doc_config: Configuration for this file type
|
|
627
|
-
|
|
692
|
+
|
|
628
693
|
Returns:
|
|
629
694
|
Processing results
|
|
630
695
|
"""
|
|
631
696
|
try:
|
|
632
697
|
# Read file content
|
|
633
|
-
content = file_path.read_text(encoding=
|
|
634
|
-
|
|
698
|
+
content = file_path.read_text(encoding="utf-8", errors="ignore")
|
|
699
|
+
|
|
635
700
|
# Handle different file types
|
|
636
|
-
file_type = doc_config.get(
|
|
637
|
-
|
|
638
|
-
if file_type ==
|
|
639
|
-
extracted_items = self._extract_from_config_file(
|
|
640
|
-
|
|
641
|
-
|
|
701
|
+
file_type = doc_config.get("file_type", "markdown")
|
|
702
|
+
|
|
703
|
+
if file_type == "config":
|
|
704
|
+
extracted_items = self._extract_from_config_file(
|
|
705
|
+
content, file_path, doc_config
|
|
706
|
+
)
|
|
707
|
+
elif file_type == "source":
|
|
708
|
+
extracted_items = self._extract_from_source_file(
|
|
709
|
+
content, file_path, doc_config
|
|
710
|
+
)
|
|
642
711
|
else:
|
|
643
712
|
# Default markdown/text processing
|
|
644
|
-
extracted_items = self.extract_from_text(
|
|
645
|
-
|
|
713
|
+
extracted_items = self.extract_from_text(
|
|
714
|
+
content, str(file_path.relative_to(self.project_root))
|
|
715
|
+
)
|
|
716
|
+
|
|
646
717
|
result = {
|
|
647
718
|
"success": True,
|
|
648
719
|
"file_path": str(file_path),
|
|
@@ -651,9 +722,9 @@ class MemoryBuilder(LoggerMixin):
|
|
|
651
722
|
"memories_created": 0,
|
|
652
723
|
"memories_updated": 0,
|
|
653
724
|
"agents_affected": [],
|
|
654
|
-
"agent_results": {}
|
|
725
|
+
"agent_results": {},
|
|
655
726
|
}
|
|
656
|
-
|
|
727
|
+
|
|
657
728
|
# Group items by target agent
|
|
658
729
|
agent_items = {}
|
|
659
730
|
for item in extracted_items:
|
|
@@ -661,165 +732,186 @@ class MemoryBuilder(LoggerMixin):
|
|
|
661
732
|
if agent not in agent_items:
|
|
662
733
|
agent_items[agent] = []
|
|
663
734
|
agent_items[agent].append(item)
|
|
664
|
-
|
|
735
|
+
|
|
665
736
|
# Update each agent's memory
|
|
666
737
|
for agent_id, items in agent_items.items():
|
|
667
738
|
agent_result = self.build_agent_memory_from_items(agent_id, items)
|
|
668
739
|
result["agent_results"][agent_id] = agent_result
|
|
669
|
-
|
|
740
|
+
|
|
670
741
|
if agent_result.get("success"):
|
|
671
742
|
result["agents_affected"].append(agent_id)
|
|
672
743
|
result["memories_created"] += agent_result.get("items_added", 0)
|
|
673
|
-
|
|
744
|
+
|
|
674
745
|
# Update last processed timestamp
|
|
675
746
|
self._update_last_processed(file_path)
|
|
676
|
-
|
|
747
|
+
|
|
677
748
|
return result
|
|
678
|
-
|
|
749
|
+
|
|
679
750
|
except Exception as e:
|
|
680
751
|
self.logger.error(f"Error processing documentation file {file_path}: {e}")
|
|
681
|
-
return {
|
|
682
|
-
|
|
683
|
-
"file_path": str(file_path),
|
|
684
|
-
"error": str(e)
|
|
685
|
-
}
|
|
686
|
-
|
|
752
|
+
return {"success": False, "file_path": str(file_path), "error": str(e)}
|
|
753
|
+
|
|
687
754
|
def _needs_rebuild(self, file_path: Path) -> bool:
|
|
688
755
|
"""Check if documentation file needs to be processed.
|
|
689
|
-
|
|
756
|
+
|
|
690
757
|
Args:
|
|
691
758
|
file_path: Path to documentation file
|
|
692
|
-
|
|
759
|
+
|
|
693
760
|
Returns:
|
|
694
761
|
True if file needs processing
|
|
695
762
|
"""
|
|
696
763
|
# Check if file was modified since last processing
|
|
697
764
|
try:
|
|
698
765
|
last_processed_file = self.memories_dir / ".last_processed.json"
|
|
699
|
-
|
|
766
|
+
|
|
700
767
|
if not last_processed_file.exists():
|
|
701
768
|
return True
|
|
702
|
-
|
|
769
|
+
|
|
703
770
|
import json
|
|
771
|
+
|
|
704
772
|
last_processed = json.loads(last_processed_file.read_text())
|
|
705
|
-
|
|
773
|
+
|
|
706
774
|
file_key = str(file_path.relative_to(self.project_root))
|
|
707
775
|
if file_key not in last_processed:
|
|
708
776
|
return True
|
|
709
|
-
|
|
777
|
+
|
|
710
778
|
last_processed_time = datetime.fromisoformat(last_processed[file_key])
|
|
711
|
-
file_modified_time = datetime.fromtimestamp(
|
|
712
|
-
|
|
779
|
+
file_modified_time = datetime.fromtimestamp(
|
|
780
|
+
file_path.stat().st_mtime, tz=timezone.utc
|
|
781
|
+
)
|
|
782
|
+
|
|
713
783
|
return file_modified_time > last_processed_time
|
|
714
|
-
|
|
784
|
+
|
|
715
785
|
except Exception as e:
|
|
716
786
|
self.logger.debug(f"Error checking rebuild status for {file_path}: {e}")
|
|
717
787
|
return True # Default to rebuilding if we can't determine
|
|
718
|
-
|
|
788
|
+
|
|
719
789
|
def _update_last_processed(self, file_path: Path):
|
|
720
790
|
"""Update last processed timestamp for file.
|
|
721
|
-
|
|
791
|
+
|
|
722
792
|
Args:
|
|
723
793
|
file_path: Path to documentation file
|
|
724
794
|
"""
|
|
725
795
|
try:
|
|
726
796
|
self.memories_dir.mkdir(parents=True, exist_ok=True)
|
|
727
797
|
last_processed_file = self.memories_dir / ".last_processed.json"
|
|
728
|
-
|
|
798
|
+
|
|
729
799
|
# Load existing data
|
|
730
800
|
if last_processed_file.exists():
|
|
731
801
|
import json
|
|
802
|
+
|
|
732
803
|
last_processed = json.loads(last_processed_file.read_text())
|
|
733
804
|
else:
|
|
734
805
|
last_processed = {}
|
|
735
|
-
|
|
806
|
+
|
|
736
807
|
# Update timestamp
|
|
737
808
|
file_key = str(file_path.relative_to(self.project_root))
|
|
738
|
-
last_processed[file_key] = datetime.now().isoformat()
|
|
739
|
-
|
|
809
|
+
last_processed[file_key] = datetime.now(timezone.utc).isoformat()
|
|
810
|
+
|
|
740
811
|
# Save back
|
|
741
812
|
import json
|
|
813
|
+
|
|
742
814
|
last_processed_file.write_text(json.dumps(last_processed, indent=2))
|
|
743
|
-
|
|
815
|
+
|
|
744
816
|
except Exception as e:
|
|
745
817
|
self.logger.warning(f"Error updating last processed timestamp: {e}")
|
|
746
|
-
|
|
818
|
+
|
|
747
819
|
def _clean_extracted_content(self, content: str) -> str:
|
|
748
820
|
"""Clean and normalize extracted content.
|
|
749
|
-
|
|
821
|
+
|
|
750
822
|
Args:
|
|
751
823
|
content: Raw extracted content
|
|
752
|
-
|
|
824
|
+
|
|
753
825
|
Returns:
|
|
754
826
|
Cleaned content string
|
|
755
827
|
"""
|
|
756
828
|
# Remove markdown formatting
|
|
757
|
-
content = re.sub(r
|
|
758
|
-
|
|
829
|
+
content = re.sub(r"[*_`#]+", "", content)
|
|
830
|
+
|
|
759
831
|
# Remove extra whitespace
|
|
760
|
-
content = re.sub(r
|
|
761
|
-
|
|
832
|
+
content = re.sub(r"\s+", " ", content).strip()
|
|
833
|
+
|
|
762
834
|
# Remove common prefixes that don't add value
|
|
763
|
-
content = re.sub(
|
|
764
|
-
|
|
835
|
+
content = re.sub(
|
|
836
|
+
r"^(?:note:|tip:|important:|warning:)\s*", "", content, flags=re.IGNORECASE
|
|
837
|
+
)
|
|
838
|
+
|
|
765
839
|
# Truncate to memory limit (with ellipsis if needed)
|
|
766
840
|
if len(content) > 95: # Leave room for ellipsis
|
|
767
841
|
content = content[:95] + "..."
|
|
768
|
-
|
|
842
|
+
|
|
769
843
|
return content
|
|
770
|
-
|
|
844
|
+
|
|
771
845
|
def _is_valid_memory_content(self, content: str) -> bool:
|
|
772
846
|
"""Validate if content is suitable for memory storage.
|
|
773
|
-
|
|
847
|
+
|
|
774
848
|
Args:
|
|
775
849
|
content: Content to validate
|
|
776
|
-
|
|
850
|
+
|
|
777
851
|
Returns:
|
|
778
852
|
True if content is valid for memory
|
|
779
853
|
"""
|
|
780
854
|
# Must have minimum length
|
|
781
855
|
if len(content) < 10:
|
|
782
856
|
return False
|
|
783
|
-
|
|
857
|
+
|
|
784
858
|
# Must contain actionable information
|
|
785
|
-
actionable_words = [
|
|
859
|
+
actionable_words = [
|
|
860
|
+
"use",
|
|
861
|
+
"avoid",
|
|
862
|
+
"ensure",
|
|
863
|
+
"follow",
|
|
864
|
+
"implement",
|
|
865
|
+
"check",
|
|
866
|
+
"must",
|
|
867
|
+
"should",
|
|
868
|
+
"never",
|
|
869
|
+
"always",
|
|
870
|
+
]
|
|
786
871
|
if not any(word in content.lower() for word in actionable_words):
|
|
787
872
|
return False
|
|
788
|
-
|
|
873
|
+
|
|
789
874
|
# Avoid overly generic content
|
|
790
|
-
generic_phrases = [
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
875
|
+
generic_phrases = [
|
|
876
|
+
"this is",
|
|
877
|
+
"this document",
|
|
878
|
+
"see above",
|
|
879
|
+
"as mentioned",
|
|
880
|
+
"for more info",
|
|
881
|
+
]
|
|
882
|
+
return not any(phrase in content.lower() for phrase in generic_phrases)
|
|
883
|
+
|
|
884
|
+
def _deduplicate_extracted_items(
|
|
885
|
+
self, items: List[Dict[str, Any]]
|
|
886
|
+
) -> List[Dict[str, Any]]:
|
|
797
887
|
"""Remove near-duplicate extracted items.
|
|
798
|
-
|
|
888
|
+
|
|
799
889
|
Args:
|
|
800
890
|
items: List of extracted items
|
|
801
|
-
|
|
891
|
+
|
|
802
892
|
Returns:
|
|
803
893
|
Deduplicated list
|
|
804
894
|
"""
|
|
805
895
|
from difflib import SequenceMatcher
|
|
806
|
-
|
|
896
|
+
|
|
807
897
|
unique_items = []
|
|
808
|
-
|
|
898
|
+
|
|
809
899
|
for item in items:
|
|
810
900
|
content = item.get("content", "")
|
|
811
901
|
is_duplicate = False
|
|
812
|
-
|
|
902
|
+
|
|
813
903
|
# Check against existing unique items
|
|
814
904
|
for unique_item in unique_items:
|
|
815
905
|
unique_content = unique_item.get("content", "")
|
|
816
|
-
similarity = SequenceMatcher(
|
|
817
|
-
|
|
906
|
+
similarity = SequenceMatcher(
|
|
907
|
+
None, content.lower(), unique_content.lower()
|
|
908
|
+
).ratio()
|
|
909
|
+
|
|
818
910
|
if similarity > 0.8: # 80% similarity threshold
|
|
819
911
|
is_duplicate = True
|
|
820
912
|
break
|
|
821
|
-
|
|
913
|
+
|
|
822
914
|
if not is_duplicate:
|
|
823
915
|
unique_items.append(item)
|
|
824
|
-
|
|
825
|
-
return unique_items
|
|
916
|
+
|
|
917
|
+
return unique_items
|