claude-mpm 4.20.3__py3-none-any.whl → 5.1.8__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.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_PM.md +35 -6
- claude_mpm/agents/OUTPUT_STYLE.md +3 -48
- claude_mpm/agents/PM_INSTRUCTIONS.md +1241 -667
- claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +1322 -0
- claude_mpm/agents/WORKFLOW.md +75 -2
- claude_mpm/agents/__init__.py +6 -0
- claude_mpm/agents/agent_loader.py +1 -4
- claude_mpm/agents/base_agent.json +6 -3
- claude_mpm/agents/base_agent_loader.py +10 -35
- claude_mpm/agents/frontmatter_validator.py +1 -1
- claude_mpm/agents/templates/circuit-breakers.md +1254 -0
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -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/cli/__init__.py +37 -2
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +188 -30
- claude_mpm/cli/commands/agents.py +959 -36
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/analyze.py +3 -3
- claude_mpm/cli/commands/auto_configure.py +537 -239
- claude_mpm/cli/commands/cleanup.py +1 -1
- claude_mpm/cli/commands/config.py +7 -4
- claude_mpm/cli/commands/configure.py +924 -45
- claude_mpm/cli/commands/configure_agent_display.py +4 -4
- claude_mpm/cli/commands/configure_navigation.py +63 -46
- claude_mpm/cli/commands/debug.py +12 -12
- claude_mpm/cli/commands/doctor.py +10 -2
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/local_deploy.py +1 -4
- claude_mpm/cli/commands/mcp_install_commands.py +1 -1
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +573 -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/modes.py +397 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
- claude_mpm/cli/commands/mpm_init_cli.py +396 -0
- claude_mpm/cli/commands/mpm_init_handler.py +67 -1
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/run.py +125 -167
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +835 -44
- claude_mpm/cli/executor.py +78 -3
- claude_mpm/cli/interactive/agent_wizard.py +1032 -47
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +256 -4
- claude_mpm/cli/parsers/auto_configure_parser.py +13 -0
- claude_mpm/cli/parsers/base_parser.py +53 -0
- claude_mpm/cli/parsers/config_parser.py +96 -43
- claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +145 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/startup.py +564 -108
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/cli_module/commands.py +1 -1
- claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
- claude_mpm/commands/mpm-agents-detect.md +9 -0
- claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
- claude_mpm/commands/mpm-agents-recommend.md +9 -0
- claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
- claude_mpm/commands/mpm-doctor.md +9 -0
- claude_mpm/commands/mpm-help.md +17 -2
- claude_mpm/commands/mpm-init.md +28 -3
- claude_mpm/commands/mpm-monitor.md +9 -0
- claude_mpm/commands/mpm-postmortem.md +123 -0
- claude_mpm/commands/mpm-session-resume.md +381 -0
- claude_mpm/commands/mpm-status.md +9 -0
- claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
- claude_mpm/commands/mpm-ticket-view.md +552 -0
- claude_mpm/commands/mpm-version.md +9 -0
- claude_mpm/commands/mpm.md +11 -0
- claude_mpm/config/agent_presets.py +488 -0
- claude_mpm/config/agent_sources.py +325 -0
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/constants.py +13 -0
- claude_mpm/core/api_validator.py +1 -1
- claude_mpm/core/claude_runner.py +19 -35
- claude_mpm/core/config.py +24 -0
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/framework/__init__.py +3 -16
- claude_mpm/core/framework/loaders/file_loader.py +54 -101
- claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
- claude_mpm/core/framework/processors/metadata_processor.py +1 -1
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +131 -10
- claude_mpm/core/interfaces.py +56 -1
- claude_mpm/core/logger.py +3 -1
- claude_mpm/core/oneshot_session.py +110 -8
- 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/shared/singleton_manager.py +11 -4
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/unified_config.py +22 -0
- claude_mpm/dashboard/static/css/activity.css +69 -69
- claude_mpm/dashboard/static/css/connection-status.css +10 -10
- claude_mpm/dashboard/static/css/dashboard.css +15 -15
- claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
- claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
- claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
- claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
- claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
- claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
- claude_mpm/dashboard/static/js/connection-manager.js +76 -76
- claude_mpm/dashboard/static/js/dashboard.js +76 -58
- claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/js/socket-client.js +138 -121
- claude_mpm/dashboard/templates/code_simple.html +23 -23
- claude_mpm/dashboard/templates/index.html +18 -18
- claude_mpm/experimental/cli_enhancements.py +1 -5
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
- claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
- claude_mpm/hooks/claude_hooks/installer.py +45 -0
- claude_mpm/hooks/claude_hooks/memory_integration.py +12 -1
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
- claude_mpm/hooks/failure_learning/__init__.py +2 -8
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
- claude_mpm/hooks/kuzu_response_hook.py +1 -5
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/scripts/claude-hook-handler.sh +3 -3
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/agent_builder.py +45 -9
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -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/agent_deployment.py +126 -2
- claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
- claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
- claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
- claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
- claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
- claude_mpm/services/agents/git_source_manager.py +629 -0
- claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
- claude_mpm/services/agents/local_template_manager.py +50 -10
- 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 +1087 -0
- claude_mpm/services/agents/startup_sync.py +239 -0
- claude_mpm/services/agents/toolchain_detector.py +474 -0
- claude_mpm/services/analysis/__init__.py +25 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +36 -16
- claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
- claude_mpm/services/command_deployment_service.py +200 -6
- claude_mpm/services/core/base.py +31 -11
- claude_mpm/services/core/interfaces/__init__.py +1 -3
- claude_mpm/services/core/interfaces/health.py +1 -4
- claude_mpm/services/core/interfaces.py +56 -1
- claude_mpm/services/core/models/__init__.py +2 -11
- claude_mpm/services/core/models/agent_config.py +3 -0
- claude_mpm/services/core/models/process.py +4 -0
- claude_mpm/services/diagnostics/checks/__init__.py +4 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
- claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
- claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
- claude_mpm/services/diagnostics/models.py +21 -0
- claude_mpm/services/event_bus/direct_relay.py +3 -3
- claude_mpm/services/event_bus/event_bus.py +36 -3
- claude_mpm/services/event_bus/relay.py +23 -7
- claude_mpm/services/events/consumers/logging.py +1 -2
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +494 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
- claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
- claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
- 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 +5 -13
- claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
- claude_mpm/services/local_ops/health_manager.py +1 -4
- claude_mpm/services/local_ops/process_manager.py +1 -1
- claude_mpm/services/local_ops/resource_monitor.py +2 -2
- claude_mpm/services/mcp_config_manager.py +75 -145
- claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
- claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
- claude_mpm/services/mcp_gateway/core/process_pool.py +41 -26
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
- claude_mpm/services/mcp_service_verifier.py +6 -3
- claude_mpm/services/memory/failure_tracker.py +19 -4
- claude_mpm/services/memory/optimizer.py +1 -1
- claude_mpm/services/model/model_router.py +8 -9
- claude_mpm/services/monitor/daemon.py +29 -9
- claude_mpm/services/monitor/daemon_manager.py +96 -19
- claude_mpm/services/monitor/server.py +2 -2
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/port_manager.py +1 -1
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/project/documentation_manager.py +2 -1
- claude_mpm/services/project/project_organizer.py +4 -0
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +17 -3
- claude_mpm/services/self_upgrade_service.py +165 -7
- claude_mpm/services/session_management_service.py +16 -4
- claude_mpm/services/skills/__init__.py +18 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +955 -0
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/git.py +2 -2
- claude_mpm/services/socketio/server/core.py +1 -4
- claude_mpm/services/socketio/server/main.py +1 -3
- claude_mpm/services/system_instructions_service.py +1 -3
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
- claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
- claude_mpm/services/unified/unified_deployment.py +1 -5
- claude_mpm/services/version_control/conflict_resolution.py +6 -4
- claude_mpm/services/visualization/__init__.py +1 -5
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/__init__.py +3 -3
- claude_mpm/skills/agent_skills_injector.py +42 -49
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +17 -10
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +92 -39
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +13 -12
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +5 -3
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +19 -12
- claude_mpm/skills/bundled/performance-profiling.md +6 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +6 -6
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +13 -9
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +8 -8
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +37 -15
- claude_mpm/skills/skills_registry.py +44 -48
- claude_mpm/skills/skills_service.py +117 -108
- 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/tools/__main__.py +8 -8
- 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/utils/agent_dependency_loader.py +80 -13
- claude_mpm/utils/agent_filters.py +288 -0
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +244 -0
- claude_mpm/utils/log_cleanup.py +3 -3
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/progress.py +387 -0
- claude_mpm/utils/robust_installer.py +3 -5
- claude_mpm/utils/structured_questions.py +619 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/METADATA +496 -65
- {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/RECORD +328 -416
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
- claude_mpm/agents/templates/agent-manager.json +0 -273
- claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
- claude_mpm/agents/templates/api_qa.json +0 -180
- claude_mpm/agents/templates/circuit_breakers.md +0 -638
- claude_mpm/agents/templates/clerk-ops.json +0 -235
- claude_mpm/agents/templates/code_analyzer.json +0 -101
- claude_mpm/agents/templates/content-agent.json +0 -358
- claude_mpm/agents/templates/dart_engineer.json +0 -307
- claude_mpm/agents/templates/data_engineer.json +0 -225
- claude_mpm/agents/templates/documentation.json +0 -211
- claude_mpm/agents/templates/engineer.json +0 -210
- claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
- claude_mpm/agents/templates/golang_engineer.json +0 -270
- claude_mpm/agents/templates/imagemagick.json +0 -264
- claude_mpm/agents/templates/java_engineer.json +0 -346
- claude_mpm/agents/templates/local_ops_agent.json +0 -1840
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
- claude_mpm/agents/templates/memory_manager.json +0 -158
- claude_mpm/agents/templates/nextjs_engineer.json +0 -285
- claude_mpm/agents/templates/ops.json +0 -185
- claude_mpm/agents/templates/php-engineer.json +0 -281
- claude_mpm/agents/templates/product_owner.json +0 -338
- claude_mpm/agents/templates/project_organizer.json +0 -140
- claude_mpm/agents/templates/prompt-engineer.json +0 -737
- claude_mpm/agents/templates/python_engineer.json +0 -387
- claude_mpm/agents/templates/qa.json +0 -242
- claude_mpm/agents/templates/react_engineer.json +0 -238
- claude_mpm/agents/templates/refactoring_engineer.json +0 -276
- claude_mpm/agents/templates/research.json +0 -188
- claude_mpm/agents/templates/ruby-engineer.json +0 -280
- claude_mpm/agents/templates/rust_engineer.json +0 -275
- claude_mpm/agents/templates/security.json +0 -202
- claude_mpm/agents/templates/svelte-engineer.json +0 -225
- claude_mpm/agents/templates/ticketing.json +0 -177
- claude_mpm/agents/templates/typescript_engineer.json +0 -285
- claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
- claude_mpm/agents/templates/version_control.json +0 -157
- claude_mpm/agents/templates/web_qa.json +0 -399
- claude_mpm/agents/templates/web_ui.json +0 -189
- claude_mpm/cli/commands/mpm_init.py +0 -2093
- claude_mpm/commands/mpm-tickets.md +0 -102
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
- claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
- claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
- claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
- claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
- claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
- claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
- claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
- claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
- claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
- claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
- claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/built/connection-manager.js +0 -536
- claude_mpm/dashboard/static/built/dashboard.js +0 -2
- claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/built/react/events.js +0 -30
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
- claude_mpm/dashboard/static/built/shared/logger.js +0 -385
- claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/built/socket-client.js +0 -2
- claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/dist/dashboard.js +0 -2
- claude_mpm/dashboard/static/dist/react/events.js +0 -30
- claude_mpm/dashboard/static/dist/socket-client.js +0 -2
- claude_mpm/dashboard/static/events.html +0 -607
- claude_mpm/dashboard/static/index.html +0 -635
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/js/shared/logger.js +0 -385
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
- claude_mpm/dashboard/static/legacy/activity.html +0 -736
- claude_mpm/dashboard/static/legacy/agents.html +0 -786
- claude_mpm/dashboard/static/legacy/files.html +0 -747
- claude_mpm/dashboard/static/legacy/tools.html +0 -831
- claude_mpm/dashboard/static/monitors.html +0 -431
- claude_mpm/dashboard/static/production/events.html +0 -659
- claude_mpm/dashboard/static/production/main.html +0 -698
- claude_mpm/dashboard/static/production/monitors.html +0 -483
- claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
- claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
- claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
- claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
- claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -75
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -184
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -107
- claude_mpm/skills/bundled/collaboration/requesting-code-review/code-reviewer.md +0 -146
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -118
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -177
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -175
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/common-failures.md +0 -213
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -314
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -227
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -74
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -32
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -328
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -209
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -123
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -304
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -96
- claude_mpm/tools/code_tree_analyzer.py +0 -1825
- /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
- /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
- /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
- /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/WHEEL +0 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/top_level.txt +0 -0
|
@@ -199,7 +199,9 @@ class KuzuMemoryService(BaseToolAdapter):
|
|
|
199
199
|
try:
|
|
200
200
|
if action == "store":
|
|
201
201
|
result = await self.store_memory(
|
|
202
|
-
params.get("content"),
|
|
202
|
+
params.get("content"),
|
|
203
|
+
params.get("tags"),
|
|
204
|
+
{}, # metadata
|
|
203
205
|
)
|
|
204
206
|
elif action == "recall":
|
|
205
207
|
result = await self.recall_memories(
|
|
@@ -213,7 +215,9 @@ class KuzuMemoryService(BaseToolAdapter):
|
|
|
213
215
|
)
|
|
214
216
|
elif action == "context":
|
|
215
217
|
result = await self.get_context(
|
|
216
|
-
params.get("query", ""),
|
|
218
|
+
params.get("query", ""),
|
|
219
|
+
2,
|
|
220
|
+
True, # depth # include_related
|
|
217
221
|
)
|
|
218
222
|
else:
|
|
219
223
|
return MCPToolResult(success=False, error=f"Unknown action: {action}")
|
|
@@ -620,12 +620,15 @@ class MCPServiceVerifier:
|
|
|
620
620
|
return True
|
|
621
621
|
|
|
622
622
|
if "claude-mpm configure" in diagnostic.fix_command:
|
|
623
|
-
#
|
|
623
|
+
# Check if services are available (read-only)
|
|
624
624
|
from .mcp_config_manager import MCPConfigManager
|
|
625
625
|
|
|
626
626
|
manager = MCPConfigManager()
|
|
627
|
-
|
|
628
|
-
|
|
627
|
+
available, message = manager.check_mcp_services_available()
|
|
628
|
+
if not available:
|
|
629
|
+
# Cannot auto-fix - user must install services manually
|
|
630
|
+
self.logger.warning(f"Cannot auto-fix: {message}")
|
|
631
|
+
return available
|
|
629
632
|
|
|
630
633
|
except Exception as e:
|
|
631
634
|
self.logger.error(f"Auto-fix failed for {service_name}: {e}")
|
|
@@ -29,6 +29,7 @@ Example flow:
|
|
|
29
29
|
|
|
30
30
|
import logging
|
|
31
31
|
import re
|
|
32
|
+
import threading
|
|
32
33
|
from dataclasses import dataclass, field
|
|
33
34
|
from datetime import datetime, timezone
|
|
34
35
|
from typing import Dict, List, Optional, Tuple
|
|
@@ -536,6 +537,7 @@ class FailureTracker:
|
|
|
536
537
|
|
|
537
538
|
# Singleton instance for session-level tracking
|
|
538
539
|
_tracker_instance: Optional[FailureTracker] = None
|
|
540
|
+
_tracker_lock = threading.Lock()
|
|
539
541
|
|
|
540
542
|
|
|
541
543
|
def get_failure_tracker() -> FailureTracker:
|
|
@@ -544,13 +546,23 @@ def get_failure_tracker() -> FailureTracker:
|
|
|
544
546
|
WHY: Session-level tracking requires a singleton to maintain state
|
|
545
547
|
across multiple hook invocations during the same session.
|
|
546
548
|
|
|
549
|
+
Thread-safe implementation using double-checked locking pattern to
|
|
550
|
+
prevent race conditions during concurrent initialization.
|
|
551
|
+
|
|
547
552
|
Returns:
|
|
548
553
|
The FailureTracker singleton instance
|
|
549
554
|
"""
|
|
550
555
|
global _tracker_instance
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
556
|
+
|
|
557
|
+
# Fast path - check without lock
|
|
558
|
+
if _tracker_instance is not None:
|
|
559
|
+
return _tracker_instance
|
|
560
|
+
|
|
561
|
+
# Slow path - acquire lock and double-check
|
|
562
|
+
with _tracker_lock:
|
|
563
|
+
if _tracker_instance is None:
|
|
564
|
+
_tracker_instance = FailureTracker()
|
|
565
|
+
return _tracker_instance
|
|
554
566
|
|
|
555
567
|
|
|
556
568
|
def reset_failure_tracker() -> None:
|
|
@@ -558,6 +570,9 @@ def reset_failure_tracker() -> None:
|
|
|
558
570
|
|
|
559
571
|
WHY: Tests need to reset state between runs. Also useful for
|
|
560
572
|
explicitly starting a new tracking session.
|
|
573
|
+
|
|
574
|
+
Thread-safe implementation ensures proper cleanup.
|
|
561
575
|
"""
|
|
562
576
|
global _tracker_instance
|
|
563
|
-
|
|
577
|
+
with _tracker_lock:
|
|
578
|
+
_tracker_instance = None
|
|
@@ -618,7 +618,7 @@ class MemoryOptimizer(LoggerMixin):
|
|
|
618
618
|
)
|
|
619
619
|
|
|
620
620
|
# Check for similar items
|
|
621
|
-
|
|
621
|
+
_consolidated, consolidated_count = self._consolidate_similar_items(
|
|
622
622
|
unique_points
|
|
623
623
|
)
|
|
624
624
|
if consolidated_count > 0:
|
|
@@ -266,7 +266,7 @@ class ModelRouter(BaseService, IModelRouter):
|
|
|
266
266
|
|
|
267
267
|
# Route based on strategy
|
|
268
268
|
if self.strategy == RoutingStrategy.CLAUDE_ONLY:
|
|
269
|
-
return await self._route_to_claude(content, task, model, **kwargs)
|
|
269
|
+
return await self._route_to_claude(content, task, model=model, **kwargs)
|
|
270
270
|
|
|
271
271
|
if self.strategy in (
|
|
272
272
|
RoutingStrategy.OLLAMA_ONLY,
|
|
@@ -275,13 +275,13 @@ class ModelRouter(BaseService, IModelRouter):
|
|
|
275
275
|
return await self._route_to_ollama(
|
|
276
276
|
content,
|
|
277
277
|
task,
|
|
278
|
-
model,
|
|
278
|
+
model=model,
|
|
279
279
|
require_success=True,
|
|
280
280
|
**kwargs,
|
|
281
281
|
)
|
|
282
282
|
|
|
283
283
|
# AUTO strategy
|
|
284
|
-
return await self._route_auto(content, task, model, **kwargs)
|
|
284
|
+
return await self._route_auto(content, task, model=model, **kwargs)
|
|
285
285
|
|
|
286
286
|
async def _route_auto(
|
|
287
287
|
self,
|
|
@@ -308,7 +308,7 @@ class ModelRouter(BaseService, IModelRouter):
|
|
|
308
308
|
response = await self._route_to_ollama(
|
|
309
309
|
content,
|
|
310
310
|
task,
|
|
311
|
-
model,
|
|
311
|
+
model=model,
|
|
312
312
|
require_success=False,
|
|
313
313
|
**kwargs,
|
|
314
314
|
)
|
|
@@ -325,7 +325,7 @@ class ModelRouter(BaseService, IModelRouter):
|
|
|
325
325
|
# Ollama unavailable or failed - fallback to Claude
|
|
326
326
|
if self.fallback_enabled:
|
|
327
327
|
self.log_info("Falling back to Claude")
|
|
328
|
-
return await self._route_to_claude(content, task, model, **kwargs)
|
|
328
|
+
return await self._route_to_claude(content, task, model=model, **kwargs)
|
|
329
329
|
return self._create_error_response(
|
|
330
330
|
task,
|
|
331
331
|
model,
|
|
@@ -356,8 +356,7 @@ class ModelRouter(BaseService, IModelRouter):
|
|
|
356
356
|
if require_success and not await self.ollama_provider.is_available():
|
|
357
357
|
if self.strategy == RoutingStrategy.PRIVACY_FIRST:
|
|
358
358
|
error_msg = (
|
|
359
|
-
"Ollama not available. Privacy mode enabled - "
|
|
360
|
-
"not sending to cloud."
|
|
359
|
+
"Ollama not available. Privacy mode enabled - not sending to cloud."
|
|
361
360
|
)
|
|
362
361
|
else:
|
|
363
362
|
error_msg = "Ollama not available and required by configuration"
|
|
@@ -368,7 +367,7 @@ class ModelRouter(BaseService, IModelRouter):
|
|
|
368
367
|
self._route_count["ollama"] += 1
|
|
369
368
|
|
|
370
369
|
return await self.ollama_provider.analyze_content(
|
|
371
|
-
content, task, model, **kwargs
|
|
370
|
+
content, task, model=model, **kwargs
|
|
372
371
|
)
|
|
373
372
|
|
|
374
373
|
async def _route_to_claude(
|
|
@@ -394,7 +393,7 @@ class ModelRouter(BaseService, IModelRouter):
|
|
|
394
393
|
self._route_count["claude"] += 1
|
|
395
394
|
|
|
396
395
|
return await self.claude_provider.analyze_content(
|
|
397
|
-
content, task, model, **kwargs
|
|
396
|
+
content, task, model=model, **kwargs
|
|
398
397
|
)
|
|
399
398
|
|
|
400
399
|
def _create_error_response(
|
|
@@ -88,11 +88,12 @@ class UnifiedMonitorDaemon:
|
|
|
88
88
|
self.shutdown_event = threading.Event()
|
|
89
89
|
|
|
90
90
|
def _get_default_pid_file(self) -> str:
|
|
91
|
-
"""Get default PID file path."""
|
|
91
|
+
"""Get default PID file path with port number to support multiple daemons."""
|
|
92
92
|
project_root = Path.cwd()
|
|
93
93
|
claude_mpm_dir = project_root / ".claude-mpm"
|
|
94
94
|
claude_mpm_dir.mkdir(exist_ok=True)
|
|
95
|
-
|
|
95
|
+
# Include port in filename to support multiple daemon instances
|
|
96
|
+
return str(claude_mpm_dir / f"monitor-daemon-{self.port}.pid")
|
|
96
97
|
|
|
97
98
|
def start(self, force_restart: bool = False) -> bool:
|
|
98
99
|
"""Start the unified monitor daemon.
|
|
@@ -145,16 +146,26 @@ class UnifiedMonitorDaemon:
|
|
|
145
146
|
if self.daemon_manager.is_running():
|
|
146
147
|
existing_pid = self.daemon_manager.get_pid()
|
|
147
148
|
if not force_restart:
|
|
148
|
-
|
|
149
|
+
msg = f"Daemon already running on port {self.port} with PID {existing_pid}"
|
|
150
|
+
self.logger.warning(msg)
|
|
151
|
+
# If we're in subprocess mode, this is an error - we should have cleaned up
|
|
152
|
+
if os.environ.get("CLAUDE_MPM_SUBPROCESS_DAEMON") == "1":
|
|
153
|
+
self.logger.error(
|
|
154
|
+
f"SUBPROCESS ERROR: {msg} - This should not happen in subprocess mode!"
|
|
155
|
+
)
|
|
149
156
|
return False
|
|
150
157
|
# Force restart was already handled above
|
|
151
158
|
|
|
152
159
|
# Check for our service on the port
|
|
153
160
|
is_ours, pid = self.daemon_manager.is_our_service()
|
|
154
161
|
if is_ours and pid and not force_restart:
|
|
155
|
-
self.
|
|
156
|
-
|
|
157
|
-
|
|
162
|
+
msg = f"Our service already running on port {self.port} (PID: {pid})"
|
|
163
|
+
self.logger.warning(msg)
|
|
164
|
+
# If we're in subprocess mode, this is an error - we should have cleaned up
|
|
165
|
+
if os.environ.get("CLAUDE_MPM_SUBPROCESS_DAEMON") == "1":
|
|
166
|
+
self.logger.error(
|
|
167
|
+
f"SUBPROCESS ERROR: {msg} - This should not happen in subprocess mode!"
|
|
168
|
+
)
|
|
158
169
|
return False
|
|
159
170
|
|
|
160
171
|
# Use subprocess approach for clean daemon startup (v4.2.40)
|
|
@@ -169,20 +180,29 @@ class UnifiedMonitorDaemon:
|
|
|
169
180
|
if os.environ.get("CLAUDE_MPM_SUBPROCESS_DAEMON") == "1":
|
|
170
181
|
# We're in a subprocess started by start_daemon_subprocess
|
|
171
182
|
# We need to write the PID file ourselves since parent didn't
|
|
172
|
-
self.logger.info("Running in subprocess daemon mode
|
|
183
|
+
self.logger.info(f"Running in subprocess daemon mode on port {self.port}")
|
|
184
|
+
self.logger.info(f"Subprocess PID: {os.getpid()}")
|
|
185
|
+
self.logger.info(f"PID file path: {self.daemon_manager.pid_file}")
|
|
173
186
|
self.daemon_manager.write_pid_file()
|
|
187
|
+
self.logger.info("PID file written successfully")
|
|
174
188
|
|
|
175
189
|
# Setup signal handlers for graceful shutdown
|
|
176
190
|
self._setup_signal_handlers()
|
|
191
|
+
self.logger.info("Signal handlers configured")
|
|
177
192
|
|
|
178
193
|
# Start the server (this will run until shutdown)
|
|
194
|
+
self.logger.info("Starting server in subprocess mode...")
|
|
179
195
|
try:
|
|
180
196
|
result = self._run_server()
|
|
181
197
|
if not result:
|
|
182
198
|
self.logger.error("Failed to start server in subprocess mode")
|
|
199
|
+
return result
|
|
200
|
+
self.logger.info("Server started successfully in subprocess mode")
|
|
183
201
|
return result
|
|
184
202
|
except Exception as e:
|
|
185
|
-
self.logger.error(
|
|
203
|
+
self.logger.error(
|
|
204
|
+
f"Server startup exception in subprocess: {e}", exc_info=True
|
|
205
|
+
)
|
|
186
206
|
raise
|
|
187
207
|
else:
|
|
188
208
|
# Legacy fork approach (kept for compatibility but not used by default)
|
|
@@ -479,7 +499,7 @@ class UnifiedMonitorDaemon:
|
|
|
479
499
|
except OSError:
|
|
480
500
|
if i < 9:
|
|
481
501
|
self.logger.debug(
|
|
482
|
-
f"Port {self.port} still in use, waiting... ({i+1}/10)"
|
|
502
|
+
f"Port {self.port} still in use, waiting... ({i + 1}/10)"
|
|
483
503
|
)
|
|
484
504
|
time.sleep(1)
|
|
485
505
|
else:
|
|
@@ -80,18 +80,20 @@ class DaemonManager:
|
|
|
80
80
|
self.startup_status_file = None
|
|
81
81
|
|
|
82
82
|
def _get_default_pid_file(self) -> Path:
|
|
83
|
-
"""Get default PID file path."""
|
|
83
|
+
"""Get default PID file path with port number to support multiple daemons."""
|
|
84
84
|
project_root = Path.cwd()
|
|
85
85
|
claude_mpm_dir = project_root / ".claude-mpm"
|
|
86
86
|
claude_mpm_dir.mkdir(exist_ok=True)
|
|
87
|
-
|
|
87
|
+
# Include port in filename to support multiple daemon instances
|
|
88
|
+
return claude_mpm_dir / f"monitor-daemon-{self.port}.pid"
|
|
88
89
|
|
|
89
90
|
def _get_default_log_file(self) -> Path:
|
|
90
|
-
"""Get default log file path."""
|
|
91
|
+
"""Get default log file path with port number to support multiple daemons."""
|
|
91
92
|
project_root = Path.cwd()
|
|
92
93
|
claude_mpm_dir = project_root / ".claude-mpm"
|
|
93
94
|
claude_mpm_dir.mkdir(exist_ok=True)
|
|
94
|
-
|
|
95
|
+
# Include port in filename to support multiple daemon instances
|
|
96
|
+
return claude_mpm_dir / f"monitor-daemon-{self.port}.log"
|
|
95
97
|
|
|
96
98
|
def cleanup_port_conflicts(self, max_retries: int = 3) -> bool:
|
|
97
99
|
"""Clean up any processes using the daemon port.
|
|
@@ -471,6 +473,55 @@ class DaemonManager:
|
|
|
471
473
|
|
|
472
474
|
return None
|
|
473
475
|
|
|
476
|
+
def _verify_daemon_health(self, max_attempts: int = 3) -> bool:
|
|
477
|
+
"""Verify daemon is healthy by checking HTTP health endpoint.
|
|
478
|
+
|
|
479
|
+
Args:
|
|
480
|
+
max_attempts: Maximum number of connection attempts
|
|
481
|
+
|
|
482
|
+
Returns:
|
|
483
|
+
True if health check passes, False otherwise
|
|
484
|
+
"""
|
|
485
|
+
try:
|
|
486
|
+
import requests
|
|
487
|
+
|
|
488
|
+
for attempt in range(max_attempts):
|
|
489
|
+
try:
|
|
490
|
+
# Try to connect to health endpoint
|
|
491
|
+
response = requests.get(
|
|
492
|
+
f"http://{self.host}:{self.port}/health", timeout=2
|
|
493
|
+
)
|
|
494
|
+
|
|
495
|
+
if response.status_code == 200:
|
|
496
|
+
self.logger.debug(
|
|
497
|
+
f"Health check passed on attempt {attempt + 1}/{max_attempts}"
|
|
498
|
+
)
|
|
499
|
+
return True
|
|
500
|
+
|
|
501
|
+
self.logger.debug(
|
|
502
|
+
f"Health check returned status {response.status_code} on attempt {attempt + 1}/{max_attempts}"
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
except requests.exceptions.RequestException as e:
|
|
506
|
+
self.logger.debug(
|
|
507
|
+
f"Health check attempt {attempt + 1}/{max_attempts} failed: {e}"
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
# Wait before retry (except on last attempt)
|
|
511
|
+
if attempt < max_attempts - 1:
|
|
512
|
+
time.sleep(1)
|
|
513
|
+
|
|
514
|
+
self.logger.debug(f"Health check failed after {max_attempts} attempts")
|
|
515
|
+
return False
|
|
516
|
+
|
|
517
|
+
except ImportError:
|
|
518
|
+
# requests not available, skip health check
|
|
519
|
+
self.logger.debug("requests library not available, skipping health check")
|
|
520
|
+
return True
|
|
521
|
+
except Exception as e:
|
|
522
|
+
self.logger.debug(f"Health check error: {e}")
|
|
523
|
+
return False
|
|
524
|
+
|
|
474
525
|
def start_daemon(self, force_restart: bool = False) -> bool:
|
|
475
526
|
"""Start the daemon with automatic cleanup and retry.
|
|
476
527
|
|
|
@@ -588,36 +639,62 @@ class DaemonManager:
|
|
|
588
639
|
pid = process.pid
|
|
589
640
|
self.logger.info(f"Monitor subprocess started with PID {pid}")
|
|
590
641
|
|
|
591
|
-
# Wait for the subprocess to write its PID file
|
|
642
|
+
# Wait for the subprocess to write its PID file and bind to port
|
|
592
643
|
# The subprocess will write the PID file after it starts successfully
|
|
593
644
|
max_wait = 10 # seconds
|
|
594
645
|
start_time = time.time()
|
|
646
|
+
pid_file_found = False
|
|
647
|
+
port_bound = False
|
|
648
|
+
|
|
649
|
+
self.logger.debug(f"Waiting up to {max_wait}s for daemon to start...")
|
|
595
650
|
|
|
596
651
|
while time.time() - start_time < max_wait:
|
|
597
652
|
# Check if process is still running
|
|
598
|
-
|
|
599
|
-
|
|
653
|
+
returncode = process.poll()
|
|
654
|
+
if returncode is not None:
|
|
655
|
+
# Process exited - this is the bug we're fixing!
|
|
656
|
+
self.logger.error(
|
|
657
|
+
f"Monitor daemon subprocess exited prematurely with code {returncode}"
|
|
658
|
+
)
|
|
600
659
|
self.logger.error(
|
|
601
|
-
f"
|
|
660
|
+
f"Port {self.port} daemon failed to start. Check {self.log_file} for details."
|
|
602
661
|
)
|
|
603
662
|
return False
|
|
604
663
|
|
|
605
664
|
# Check if PID file was written
|
|
606
|
-
if self.pid_file.exists():
|
|
665
|
+
if not pid_file_found and self.pid_file.exists():
|
|
607
666
|
try:
|
|
608
667
|
with self.pid_file.open() as f:
|
|
609
668
|
written_pid = int(f.read().strip())
|
|
610
669
|
if written_pid == pid:
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
)
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
670
|
+
pid_file_found = True
|
|
671
|
+
self.logger.debug(
|
|
672
|
+
f"PID file found with correct PID {pid}"
|
|
673
|
+
)
|
|
674
|
+
except Exception as e:
|
|
675
|
+
self.logger.debug(f"Error reading PID file: {e}")
|
|
676
|
+
|
|
677
|
+
# Check if port is bound (health check)
|
|
678
|
+
if not port_bound and not self._is_port_available():
|
|
679
|
+
# Port NOT available means it's in use (good!)
|
|
680
|
+
port_bound = True
|
|
681
|
+
self.logger.debug(f"Port {self.port} is now bound")
|
|
682
|
+
|
|
683
|
+
# Success criteria: both PID file exists and port is bound
|
|
684
|
+
if pid_file_found and port_bound:
|
|
685
|
+
self.logger.info(
|
|
686
|
+
f"Monitor daemon successfully started on port {self.port} (PID: {pid})"
|
|
687
|
+
)
|
|
688
|
+
# Additional health check: verify we can connect
|
|
689
|
+
if self._verify_daemon_health(max_attempts=3):
|
|
690
|
+
self.logger.info("Daemon health check passed")
|
|
691
|
+
return True
|
|
692
|
+
self.logger.warning(
|
|
693
|
+
"Daemon started but health check failed - may still be initializing"
|
|
694
|
+
)
|
|
695
|
+
return (
|
|
696
|
+
True # Return success anyway if PID file and port are good
|
|
697
|
+
)
|
|
621
698
|
|
|
622
699
|
time.sleep(0.5)
|
|
623
700
|
|
|
@@ -203,8 +203,8 @@ class UnifiedMonitorServer:
|
|
|
203
203
|
# Create Socket.IO server with proper ping configuration
|
|
204
204
|
self.sio = socketio.AsyncServer(
|
|
205
205
|
cors_allowed_origins="*",
|
|
206
|
-
logger=
|
|
207
|
-
engineio_logger=
|
|
206
|
+
logger=True, # Enable to see Socket.IO events and connection lifecycle
|
|
207
|
+
engineio_logger=True, # Enable to see Engine.IO protocol handshake details
|
|
208
208
|
ping_interval=30, # 30 seconds ping interval (matches client expectation)
|
|
209
209
|
ping_timeout=60, # 60 seconds ping timeout (generous for stability)
|
|
210
210
|
)
|