claude-mpm 4.1.26__py3-none-any.whl → 4.24.0__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/BUILD_NUMBER +1 -1
- claude_mpm/VERSION +1 -1
- claude_mpm/__init__.py +20 -5
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +118 -0
- claude_mpm/agents/BASE_DOCUMENTATION.md +53 -0
- claude_mpm/agents/BASE_ENGINEER.md +658 -0
- claude_mpm/agents/BASE_OPS.md +219 -0
- claude_mpm/agents/BASE_PM.md +420 -158
- claude_mpm/agents/BASE_PROMPT_ENGINEER.md +787 -0
- claude_mpm/agents/BASE_QA.md +167 -0
- claude_mpm/agents/BASE_RESEARCH.md +53 -0
- claude_mpm/agents/OUTPUT_STYLE.md +299 -29
- claude_mpm/agents/PM_INSTRUCTIONS.md +1159 -0
- claude_mpm/agents/WORKFLOW.md +355 -191
- claude_mpm/agents/agent_loader.py +40 -10
- claude_mpm/agents/agent_loader_integration.py +3 -2
- claude_mpm/agents/async_agent_loader.py +3 -3
- claude_mpm/agents/base_agent_loader.py +11 -9
- claude_mpm/agents/frontmatter_validator.py +291 -251
- claude_mpm/agents/system_agent_config.py +3 -2
- claude_mpm/agents/templates/README.md +465 -0
- claude_mpm/agents/templates/agent-manager.json +7 -4
- claude_mpm/agents/templates/{agentic_coder_optimizer.json → agentic-coder-optimizer.json} +33 -7
- claude_mpm/agents/templates/api_qa.json +16 -4
- claude_mpm/agents/templates/circuit_breakers.md +638 -0
- claude_mpm/agents/templates/clerk-ops.json +235 -0
- claude_mpm/agents/templates/code_analyzer.json +10 -4
- claude_mpm/agents/templates/content-agent.json +358 -0
- claude_mpm/agents/templates/dart_engineer.json +307 -0
- claude_mpm/agents/templates/data_engineer.json +87 -14
- claude_mpm/agents/templates/documentation.json +76 -13
- claude_mpm/agents/templates/engineer.json +43 -9
- claude_mpm/agents/templates/gcp_ops_agent.json +253 -0
- claude_mpm/agents/templates/git_file_tracking.md +584 -0
- claude_mpm/agents/templates/golang_engineer.json +270 -0
- claude_mpm/agents/templates/imagemagick.json +5 -2
- claude_mpm/agents/templates/java_engineer.json +346 -0
- claude_mpm/agents/templates/javascript_engineer_agent.json +380 -0
- claude_mpm/agents/templates/local_ops_agent.json +1840 -0
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +400 -0
- claude_mpm/agents/templates/memory_manager.json +6 -3
- claude_mpm/agents/templates/nextjs_engineer.json +285 -0
- claude_mpm/agents/templates/ops.json +14 -4
- claude_mpm/agents/templates/php-engineer.json +287 -0
- claude_mpm/agents/templates/pm_examples.md +474 -0
- claude_mpm/agents/templates/pm_red_flags.md +262 -0
- claude_mpm/agents/templates/product_owner.json +338 -0
- claude_mpm/agents/templates/project_organizer.json +19 -5
- claude_mpm/agents/templates/prompt-engineer.json +737 -0
- claude_mpm/agents/templates/python_engineer.json +387 -0
- claude_mpm/agents/templates/qa.json +25 -5
- claude_mpm/agents/templates/react_engineer.json +239 -0
- claude_mpm/agents/templates/refactoring_engineer.json +15 -5
- claude_mpm/agents/templates/research.json +46 -21
- claude_mpm/agents/templates/response_format.md +583 -0
- claude_mpm/agents/templates/ruby-engineer.json +280 -0
- claude_mpm/agents/templates/rust_engineer.json +275 -0
- claude_mpm/agents/templates/security.json +59 -10
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/agents/templates/tauri_engineer.json +274 -0
- claude_mpm/agents/templates/ticketing.json +16 -7
- claude_mpm/agents/templates/typescript_engineer.json +285 -0
- claude_mpm/agents/templates/validation_templates.md +312 -0
- claude_mpm/agents/templates/vercel_ops_agent.json +164 -33
- claude_mpm/agents/templates/version_control.json +16 -4
- claude_mpm/agents/templates/web_qa.json +167 -21
- claude_mpm/agents/templates/web_ui.json +18 -5
- claude_mpm/cli/__init__.py +38 -378
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/agent_manager.py +675 -20
- claude_mpm/cli/commands/agent_state_manager.py +186 -0
- claude_mpm/cli/commands/agents.py +722 -150
- claude_mpm/cli/commands/agents_detect.py +380 -0
- claude_mpm/cli/commands/agents_recommend.py +309 -0
- claude_mpm/cli/commands/aggregate.py +10 -6
- claude_mpm/cli/commands/analyze.py +15 -10
- claude_mpm/cli/commands/analyze_code.py +8 -4
- claude_mpm/cli/commands/auto_configure.py +570 -0
- claude_mpm/cli/commands/cleanup.py +12 -12
- claude_mpm/cli/commands/config.py +47 -13
- claude_mpm/cli/commands/configure.py +469 -1064
- claude_mpm/cli/commands/configure_agent_display.py +261 -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 +167 -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 +50 -52
- claude_mpm/cli/commands/debug.py +7 -7
- claude_mpm/cli/commands/doctor.py +43 -7
- claude_mpm/cli/commands/info.py +3 -4
- claude_mpm/cli/commands/local_deploy.py +537 -0
- claude_mpm/cli/commands/mcp.py +17 -10
- claude_mpm/cli/commands/mcp_command_router.py +11 -0
- claude_mpm/cli/commands/mcp_config.py +154 -0
- claude_mpm/cli/commands/mcp_external_commands.py +249 -0
- claude_mpm/cli/commands/mcp_install_commands.py +101 -32
- claude_mpm/cli/commands/mcp_pipx_config.py +2 -2
- claude_mpm/cli/commands/mcp_setup_external.py +868 -0
- claude_mpm/cli/commands/memory.py +55 -21
- claude_mpm/cli/commands/monitor.py +160 -70
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +525 -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 +114 -4
- claude_mpm/cli/commands/run.py +169 -42
- claude_mpm/cli/commands/search.py +458 -0
- claude_mpm/cli/commands/skills.py +488 -0
- 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 +204 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +21 -0
- claude_mpm/cli/interactive/agent_wizard.py +962 -0
- claude_mpm/cli/interactive/skills_wizard.py +491 -0
- claude_mpm/cli/parser.py +79 -2
- claude_mpm/cli/parsers/__init__.py +7 -1
- claude_mpm/cli/parsers/agent_manager_parser.py +161 -1
- claude_mpm/cli/parsers/agents_parser.py +116 -0
- claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
- claude_mpm/cli/parsers/base_parser.py +143 -3
- claude_mpm/cli/parsers/configure_parser.py +11 -15
- claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
- claude_mpm/cli/parsers/mcp_parser.py +15 -0
- claude_mpm/cli/parsers/monitor_parser.py +12 -2
- claude_mpm/cli/parsers/mpm_init_parser.py +179 -9
- claude_mpm/cli/parsers/run_parser.py +5 -0
- claude_mpm/cli/parsers/search_parser.py +245 -0
- claude_mpm/cli/parsers/skills_parser.py +137 -0
- claude_mpm/cli/shared/argument_patterns.py +20 -13
- claude_mpm/cli/shared/base_command.py +2 -2
- claude_mpm/cli/shared/output_formatters.py +28 -19
- claude_mpm/cli/startup.py +562 -0
- claude_mpm/cli/startup_logging.py +179 -13
- claude_mpm/cli/utils.py +53 -2
- claude_mpm/commands/mpm-agents-detect.md +168 -0
- claude_mpm/commands/mpm-agents-recommend.md +214 -0
- claude_mpm/commands/mpm-agents.md +118 -8
- claude_mpm/commands/mpm-auto-configure.md +269 -0
- claude_mpm/commands/mpm-config.md +137 -14
- claude_mpm/commands/mpm-help.md +285 -5
- claude_mpm/commands/mpm-init.md +374 -15
- claude_mpm/commands/mpm-monitor.md +409 -0
- claude_mpm/commands/mpm-organize.md +295 -0
- claude_mpm/commands/mpm-resume.md +372 -0
- claude_mpm/commands/mpm-status.md +71 -9
- claude_mpm/commands/mpm-tickets.md +56 -7
- claude_mpm/commands/mpm-version.md +113 -0
- claude_mpm/commands/mpm.md +2 -0
- claude_mpm/config/agent_config.py +4 -4
- claude_mpm/config/experimental_features.py +7 -7
- claude_mpm/config/model_config.py +428 -0
- claude_mpm/config/paths.py +3 -2
- claude_mpm/config/socketio_config.py +3 -3
- claude_mpm/constants.py +15 -1
- claude_mpm/core/__init__.py +53 -17
- claude_mpm/core/agent_name_normalizer.py +3 -2
- claude_mpm/core/agent_registry.py +2 -2
- claude_mpm/core/agent_session_manager.py +10 -10
- claude_mpm/core/api_validator.py +330 -0
- claude_mpm/core/base_service.py +33 -23
- claude_mpm/core/cache.py +9 -9
- claude_mpm/core/claude_runner.py +19 -8
- claude_mpm/core/config.py +85 -8
- claude_mpm/core/config_aliases.py +7 -6
- claude_mpm/core/constants.py +65 -0
- claude_mpm/core/container.py +11 -5
- claude_mpm/core/enums.py +452 -0
- claude_mpm/core/error_handler.py +623 -0
- claude_mpm/core/factories.py +1 -1
- claude_mpm/core/file_utils.py +764 -0
- claude_mpm/core/framework/__init__.py +38 -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 +288 -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 +210 -0
- claude_mpm/core/framework/loaders/file_loader.py +223 -0
- claude_mpm/core/framework/loaders/instruction_loader.py +161 -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 +321 -1631
- claude_mpm/core/hook_manager.py +8 -6
- claude_mpm/core/injectable_service.py +11 -8
- claude_mpm/core/instruction_reinforcement_hook.py +4 -3
- claude_mpm/core/interactive_session.py +55 -8
- claude_mpm/core/interfaces.py +56 -1
- claude_mpm/core/lazy.py +3 -3
- claude_mpm/core/log_manager.py +92 -23
- claude_mpm/core/logger.py +19 -14
- claude_mpm/core/logging_config.py +6 -2
- claude_mpm/core/logging_utils.py +520 -0
- claude_mpm/core/oneshot_session.py +51 -7
- claude_mpm/core/optimized_agent_loader.py +9 -9
- claude_mpm/core/optimized_startup.py +1 -1
- claude_mpm/core/output_style_manager.py +12 -192
- claude_mpm/core/pm_hook_interceptor.py +18 -12
- claude_mpm/core/service_registry.py +7 -3
- claude_mpm/core/session_manager.py +14 -12
- claude_mpm/core/shared/config_loader.py +1 -1
- claude_mpm/core/socketio_pool.py +15 -15
- claude_mpm/core/tool_access_control.py +3 -2
- claude_mpm/core/types.py +4 -11
- claude_mpm/core/typing_utils.py +7 -6
- claude_mpm/core/unified_agent_registry.py +115 -11
- claude_mpm/core/unified_config.py +6 -6
- claude_mpm/core/unified_paths.py +23 -20
- claude_mpm/dashboard/analysis_runner.py +4 -4
- claude_mpm/dashboard/api/simple_directory.py +261 -0
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +188 -0
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +156 -0
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +38 -0
- claude_mpm/dashboard/react/components/shared/FilterBar.module.css +92 -0
- claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +248 -0
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +61 -0
- claude_mpm/dashboard/static/archive/test_activity_connection.html +179 -0
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +68 -0
- claude_mpm/dashboard/static/archive/test_dashboard.html +409 -0
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +519 -0
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +181 -0
- claude_mpm/dashboard/static/archive/test_file_data.html +315 -0
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +243 -0
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +234 -0
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +117 -0
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +115 -0
- claude_mpm/dashboard/static/archive/test_file_viewer.html +224 -0
- claude_mpm/dashboard/static/archive/test_final_activity.html +220 -0
- claude_mpm/dashboard/static/archive/test_tab_fix.html +139 -0
- claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +1 -0
- claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +777 -0
- claude_mpm/dashboard/static/built/components/agent-inference.js +1 -1
- claude_mpm/dashboard/static/built/components/build-tracker.js +333 -0
- claude_mpm/dashboard/static/built/components/code-simple.js +857 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +353 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +235 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +409 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +435 -0
- claude_mpm/dashboard/static/built/components/code-tree.js +1 -1
- claude_mpm/dashboard/static/built/components/code-viewer.js +1 -1
- claude_mpm/dashboard/static/built/components/connection-debug.js +654 -0
- claude_mpm/dashboard/static/built/components/diff-viewer.js +891 -0
- claude_mpm/dashboard/static/built/components/event-processor.js +1 -1
- claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
- claude_mpm/dashboard/static/built/components/export-manager.js +1 -1
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +443 -0
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +690 -0
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +1 -1
- claude_mpm/dashboard/static/built/components/file-viewer.js +2 -0
- claude_mpm/dashboard/static/built/components/module-viewer.js +1 -1
- claude_mpm/dashboard/static/built/components/nav-bar.js +145 -0
- claude_mpm/dashboard/static/built/components/page-structure.js +429 -0
- claude_mpm/dashboard/static/built/components/session-manager.js +1 -1
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js +1 -1
- claude_mpm/dashboard/static/built/components/working-directory.js +1 -1
- claude_mpm/dashboard/static/built/connection-manager.js +536 -0
- claude_mpm/dashboard/static/built/dashboard.js +1 -1
- claude_mpm/dashboard/static/built/extension-error-handler.js +164 -0
- claude_mpm/dashboard/static/built/react/events.js +30 -0
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +396 -0
- claude_mpm/dashboard/static/built/shared/event-bus.js +330 -0
- claude_mpm/dashboard/static/built/shared/event-filter-service.js +540 -0
- claude_mpm/dashboard/static/built/shared/logger.js +385 -0
- claude_mpm/dashboard/static/built/shared/page-structure.js +249 -0
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +253 -0
- claude_mpm/dashboard/static/built/socket-client.js +1 -1
- claude_mpm/dashboard/static/built/tab-isolation-fix.js +185 -0
- claude_mpm/dashboard/static/css/dashboard.css +588 -6
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +1 -0
- claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
- claude_mpm/dashboard/static/dist/components/agent-inference.js +1 -1
- claude_mpm/dashboard/static/dist/components/code-tree.js +1 -1
- claude_mpm/dashboard/static/dist/components/code-viewer.js +1 -1
- claude_mpm/dashboard/static/dist/components/event-processor.js +1 -1
- claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
- claude_mpm/dashboard/static/dist/components/export-manager.js +1 -1
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +1 -1
- claude_mpm/dashboard/static/dist/components/file-viewer.js +2 -0
- claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
- claude_mpm/dashboard/static/dist/components/session-manager.js +1 -1
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +1 -1
- claude_mpm/dashboard/static/dist/components/working-directory.js +1 -1
- claude_mpm/dashboard/static/dist/dashboard.js +1 -1
- claude_mpm/dashboard/static/dist/react/events.js +30 -0
- claude_mpm/dashboard/static/dist/socket-client.js +1 -1
- claude_mpm/dashboard/static/events.html +607 -0
- claude_mpm/dashboard/static/index.html +635 -0
- claude_mpm/dashboard/static/js/components/activity-tree.js +3 -17
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +4 -1
- claude_mpm/dashboard/static/js/components/agent-inference.js +3 -0
- claude_mpm/dashboard/static/js/components/build-tracker.js +8 -0
- claude_mpm/dashboard/static/js/components/code-simple.js +857 -0
- claude_mpm/dashboard/static/js/components/diff-viewer.js +891 -0
- claude_mpm/dashboard/static/js/components/event-processor.js +3 -0
- claude_mpm/dashboard/static/js/components/event-viewer.js +39 -2
- claude_mpm/dashboard/static/js/components/export-manager.js +3 -0
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +443 -0
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +690 -0
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +30 -10
- claude_mpm/dashboard/static/js/components/file-viewer.js +580 -0
- claude_mpm/dashboard/static/js/components/module-viewer.js +26 -0
- claude_mpm/dashboard/static/js/components/session-manager.js +7 -7
- claude_mpm/dashboard/static/js/components/socket-manager.js +4 -0
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +356 -41
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +455 -23
- claude_mpm/dashboard/static/js/components/working-directory.js +44 -9
- claude_mpm/dashboard/static/js/dashboard.js +245 -132
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +396 -0
- claude_mpm/dashboard/static/js/shared/event-bus.js +330 -0
- claude_mpm/dashboard/static/js/shared/logger.js +385 -0
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +253 -0
- claude_mpm/dashboard/static/js/socket-client.js +49 -22
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +562 -0
- claude_mpm/dashboard/static/js/tab-isolation-fix.js +185 -0
- claude_mpm/dashboard/static/legacy/activity.html +736 -0
- claude_mpm/dashboard/static/legacy/agents.html +786 -0
- claude_mpm/dashboard/static/legacy/files.html +747 -0
- claude_mpm/dashboard/static/legacy/tools.html +831 -0
- claude_mpm/dashboard/static/monitors.html +431 -0
- claude_mpm/dashboard/static/production/events.html +659 -0
- claude_mpm/dashboard/static/production/main.html +698 -0
- claude_mpm/dashboard/static/production/monitors.html +483 -0
- claude_mpm/dashboard/static/socket.io.min.js +7 -0
- claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +7 -0
- claude_mpm/dashboard/static/test-archive/dashboard.html +635 -0
- claude_mpm/dashboard/static/test-archive/debug-events.html +147 -0
- claude_mpm/dashboard/static/test-archive/test-navigation.html +256 -0
- claude_mpm/dashboard/static/test-archive/test-react-exports.html +180 -0
- claude_mpm/dashboard/static/test-archive/test_debug.html +25 -0
- claude_mpm/dashboard/templates/code_simple.html +153 -0
- claude_mpm/dashboard/templates/index.html +112 -109
- claude_mpm/experimental/cli_enhancements.py +4 -2
- claude_mpm/generators/agent_profile_generator.py +5 -3
- claude_mpm/hooks/__init__.py +37 -1
- claude_mpm/hooks/base_hook.py +5 -4
- claude_mpm/hooks/claude_hooks/connection_pool.py +4 -4
- claude_mpm/hooks/claude_hooks/event_handlers.py +21 -18
- claude_mpm/hooks/claude_hooks/hook_handler.py +29 -22
- claude_mpm/hooks/claude_hooks/installer.py +67 -22
- claude_mpm/hooks/claude_hooks/memory_integration.py +3 -3
- claude_mpm/hooks/claude_hooks/response_tracking.py +57 -17
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +62 -64
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +140 -76
- claude_mpm/hooks/claude_hooks/services/state_manager.py +11 -9
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +3 -3
- claude_mpm/hooks/failure_learning/__init__.py +60 -0
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +235 -0
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +217 -0
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +286 -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 +183 -0
- claude_mpm/hooks/memory_integration_hook.py +1 -1
- 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 +8 -5
- claude_mpm/hooks/validation_hooks.py +3 -3
- claude_mpm/init.py +23 -4
- claude_mpm/models/agent_session.py +8 -6
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/scripts/claude-hook-handler.sh +33 -7
- claude_mpm/scripts/launch_monitor.py +85 -0
- claude_mpm/scripts/mcp_server.py +3 -5
- claude_mpm/scripts/mpm_doctor.py +3 -2
- claude_mpm/scripts/socketio_daemon.py +159 -512
- claude_mpm/services/__init__.py +144 -160
- claude_mpm/services/agents/__init__.py +18 -5
- claude_mpm/services/agents/agent_builder.py +13 -11
- claude_mpm/services/agents/auto_config_manager.py +796 -0
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_deployment.py +38 -15
- claude_mpm/services/agents/deployment/agent_discovery_service.py +125 -7
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +5 -5
- claude_mpm/services/agents/deployment/agent_format_converter.py +56 -12
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +4 -2
- claude_mpm/services/agents/deployment/agent_operation_service.py +2 -2
- claude_mpm/services/agents/deployment/agent_record_service.py +4 -4
- claude_mpm/services/agents/deployment/agent_state_service.py +2 -2
- claude_mpm/services/agents/deployment/agent_template_builder.py +715 -47
- claude_mpm/services/agents/deployment/agent_validator.py +31 -7
- claude_mpm/services/agents/deployment/agent_version_manager.py +8 -5
- claude_mpm/services/agents/deployment/agent_versioning.py +1 -1
- claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
- claude_mpm/services/agents/deployment/deployment_config_loader.py +131 -7
- claude_mpm/services/agents/deployment/deployment_type_detector.py +10 -14
- claude_mpm/services/agents/deployment/deployment_wrapper.py +58 -0
- claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
- claude_mpm/services/agents/deployment/local_template_deployment.py +360 -0
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +134 -38
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +8 -7
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +7 -5
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +9 -6
- claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
- claude_mpm/services/agents/deployment/validation/template_validator.py +64 -44
- claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
- claude_mpm/services/agents/loading/agent_profile_loader.py +10 -9
- claude_mpm/services/agents/loading/base_agent_manager.py +16 -6
- claude_mpm/services/agents/loading/framework_agent_loader.py +2 -2
- claude_mpm/services/agents/local_template_manager.py +744 -0
- claude_mpm/services/agents/management/agent_capabilities_generator.py +3 -2
- claude_mpm/services/agents/management/agent_management_service.py +5 -5
- claude_mpm/services/agents/memory/agent_memory_manager.py +32 -29
- claude_mpm/services/agents/memory/content_manager.py +17 -9
- claude_mpm/services/agents/memory/memory_categorization_service.py +4 -2
- claude_mpm/services/agents/memory/memory_file_service.py +32 -6
- claude_mpm/services/agents/memory/memory_format_service.py +6 -4
- claude_mpm/services/agents/memory/memory_limits_service.py +4 -2
- claude_mpm/services/agents/memory/template_generator.py +3 -3
- claude_mpm/services/agents/observers.py +547 -0
- claude_mpm/services/agents/recommender.py +615 -0
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +3 -3
- claude_mpm/services/agents/registry/modification_tracker.py +30 -19
- claude_mpm/services/async_session_logger.py +141 -98
- claude_mpm/services/claude_session_logger.py +82 -74
- claude_mpm/services/cli/agent_cleanup_service.py +5 -0
- claude_mpm/services/cli/agent_listing_service.py +5 -5
- claude_mpm/services/cli/agent_validation_service.py +3 -1
- claude_mpm/services/cli/memory_crud_service.py +12 -7
- claude_mpm/services/cli/memory_output_formatter.py +2 -2
- claude_mpm/services/cli/resume_service.py +617 -0
- claude_mpm/services/cli/session_manager.py +104 -13
- 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 +13 -10
- claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
- claude_mpm/services/command_deployment_service.py +9 -7
- claude_mpm/services/command_handler_service.py +11 -5
- claude_mpm/services/core/__init__.py +33 -1
- claude_mpm/services/core/base.py +26 -11
- claude_mpm/services/core/interfaces/__init__.py +90 -3
- claude_mpm/services/core/interfaces/agent.py +184 -0
- claude_mpm/services/core/interfaces/health.py +172 -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/stability.py +260 -0
- claude_mpm/services/core/interfaces.py +56 -1
- claude_mpm/services/core/memory_manager.py +92 -47
- claude_mpm/services/core/models/__init__.py +79 -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 +36 -14
- claude_mpm/services/diagnostics/__init__.py +2 -2
- claude_mpm/services/diagnostics/checks/__init__.py +4 -2
- claude_mpm/services/diagnostics/checks/agent_check.py +30 -32
- claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
- claude_mpm/services/diagnostics/checks/common_issues_check.py +28 -27
- claude_mpm/services/diagnostics/checks/configuration_check.py +26 -25
- claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
- claude_mpm/services/diagnostics/checks/installation_check.py +165 -60
- claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
- claude_mpm/services/diagnostics/checks/mcp_check.py +57 -43
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +1066 -0
- claude_mpm/services/diagnostics/checks/monitor_check.py +24 -23
- claude_mpm/services/diagnostics/checks/startup_log_check.py +14 -11
- claude_mpm/services/diagnostics/diagnostic_runner.py +22 -13
- claude_mpm/services/diagnostics/doctor_reporter.py +275 -47
- claude_mpm/services/diagnostics/models.py +37 -21
- claude_mpm/services/event_aggregator.py +5 -3
- claude_mpm/services/event_bus/direct_relay.py +8 -4
- claude_mpm/services/event_bus/event_bus.py +51 -9
- claude_mpm/services/event_bus/relay.py +33 -14
- claude_mpm/services/events/consumers/dead_letter.py +7 -5
- claude_mpm/services/events/core.py +5 -6
- claude_mpm/services/events/producers/hook.py +6 -6
- claude_mpm/services/events/producers/system.py +8 -8
- claude_mpm/services/exceptions.py +5 -5
- claude_mpm/services/framework_claude_md_generator/__init__.py +1 -1
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +5 -5
- claude_mpm/services/framework_claude_md_generator/content_validator.py +2 -2
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +3 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +2 -2
- claude_mpm/services/framework_claude_md_generator/version_manager.py +1 -1
- claude_mpm/services/hook_installer_service.py +506 -0
- claude_mpm/services/hook_service.py +5 -6
- claude_mpm/services/infrastructure/context_preservation.py +13 -11
- claude_mpm/services/infrastructure/daemon_manager.py +9 -9
- claude_mpm/services/infrastructure/logging.py +2 -2
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
- claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
- claude_mpm/services/infrastructure/monitoring/base.py +5 -13
- claude_mpm/services/infrastructure/monitoring/network.py +7 -6
- claude_mpm/services/infrastructure/monitoring/process.py +13 -12
- claude_mpm/services/infrastructure/monitoring/resources.py +8 -7
- claude_mpm/services/infrastructure/monitoring/service.py +16 -15
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/local_ops/__init__.py +165 -0
- claude_mpm/services/local_ops/crash_detector.py +257 -0
- claude_mpm/services/local_ops/health_checks/__init__.py +28 -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 +430 -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 +1612 -0
- claude_mpm/services/mcp_gateway/__init__.py +97 -93
- claude_mpm/services/mcp_gateway/auto_configure.py +43 -38
- claude_mpm/services/mcp_gateway/config/config_loader.py +3 -3
- claude_mpm/services/mcp_gateway/config/configuration.py +23 -4
- claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
- claude_mpm/services/mcp_gateway/core/base.py +20 -33
- claude_mpm/services/mcp_gateway/core/process_pool.py +585 -31
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +2 -2
- claude_mpm/services/mcp_gateway/core/startup_verification.py +3 -3
- claude_mpm/services/mcp_gateway/main.py +90 -15
- claude_mpm/services/mcp_gateway/registry/service_registry.py +4 -2
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +12 -9
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +4 -4
- claude_mpm/services/mcp_gateway/server/stdio_server.py +9 -15
- claude_mpm/services/mcp_gateway/tools/__init__.py +14 -2
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +15 -15
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +10 -9
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +654 -0
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +36 -34
- claude_mpm/services/mcp_gateway/tools/hello_world.py +8 -8
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +551 -0
- claude_mpm/services/mcp_gateway/utils/__init__.py +14 -0
- claude_mpm/services/mcp_gateway/utils/package_version_checker.py +160 -0
- claude_mpm/services/mcp_gateway/utils/update_preferences.py +170 -0
- claude_mpm/services/mcp_service_verifier.py +729 -0
- claude_mpm/services/memory/builder.py +9 -8
- claude_mpm/services/memory/cache/shared_prompt_cache.py +2 -1
- claude_mpm/services/memory/cache/simple_cache.py +2 -2
- claude_mpm/services/memory/failure_tracker.py +578 -0
- claude_mpm/services/memory/indexed_memory.py +8 -8
- claude_mpm/services/memory/optimizer.py +8 -9
- claude_mpm/services/memory/router.py +3 -3
- claude_mpm/services/memory_hook_service.py +165 -4
- 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 +453 -0
- claude_mpm/services/model/ollama_provider.py +415 -0
- claude_mpm/services/monitor/__init__.py +20 -0
- claude_mpm/services/monitor/daemon.py +671 -0
- claude_mpm/services/monitor/daemon_manager.py +963 -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 +724 -0
- claude_mpm/services/monitor/server.py +817 -0
- claude_mpm/services/monitor_build_service.py +2 -2
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/orphan_detection.py +786 -0
- claude_mpm/services/port_manager.py +2 -2
- claude_mpm/services/project/__init__.py +23 -0
- claude_mpm/services/project/analyzer.py +3 -3
- claude_mpm/services/project/architecture_analyzer.py +5 -5
- claude_mpm/services/project/archive_manager.py +1045 -0
- claude_mpm/services/project/dependency_analyzer.py +4 -4
- claude_mpm/services/project/detection_strategies.py +719 -0
- claude_mpm/services/project/documentation_manager.py +553 -0
- claude_mpm/services/project/enhanced_analyzer.py +572 -0
- claude_mpm/services/project/metrics_collector.py +4 -4
- claude_mpm/services/project/project_organizer.py +1005 -0
- claude_mpm/services/project/registry.py +13 -7
- claude_mpm/services/project/toolchain_analyzer.py +581 -0
- claude_mpm/services/project_port_allocator.py +596 -0
- claude_mpm/services/response_tracker.py +21 -10
- claude_mpm/services/runner_configuration_service.py +1 -0
- claude_mpm/services/self_upgrade_service.py +500 -0
- claude_mpm/services/session_management_service.py +7 -5
- claude_mpm/services/session_manager.py +380 -0
- claude_mpm/services/shared/__init__.py +2 -1
- claude_mpm/services/shared/async_service_base.py +16 -27
- claude_mpm/services/shared/config_service_base.py +17 -14
- claude_mpm/services/shared/lifecycle_service_base.py +1 -14
- claude_mpm/services/shared/service_factory.py +8 -5
- claude_mpm/services/socketio/client_proxy.py +60 -5
- claude_mpm/services/socketio/dashboard_server.py +361 -0
- claude_mpm/services/socketio/event_normalizer.py +10 -6
- claude_mpm/services/socketio/handlers/__init__.py +5 -2
- claude_mpm/services/socketio/handlers/base.py +2 -2
- claude_mpm/services/socketio/handlers/code_analysis.py +90 -27
- claude_mpm/services/socketio/handlers/connection.py +21 -40
- claude_mpm/services/socketio/handlers/connection_handler.py +13 -10
- claude_mpm/services/socketio/handlers/file.py +46 -10
- claude_mpm/services/socketio/handlers/git.py +8 -8
- claude_mpm/services/socketio/handlers/hook.py +29 -17
- claude_mpm/services/socketio/handlers/registry.py +4 -2
- claude_mpm/services/socketio/monitor_client.py +364 -0
- claude_mpm/services/socketio/server/broadcaster.py +9 -7
- claude_mpm/services/socketio/server/connection_manager.py +2 -2
- claude_mpm/services/socketio/server/core.py +141 -4
- claude_mpm/services/socketio/server/eventbus_integration.py +20 -14
- claude_mpm/services/socketio/server/main.py +23 -21
- claude_mpm/services/socketio_client_manager.py +4 -4
- claude_mpm/services/subprocess_launcher_service.py +19 -15
- claude_mpm/services/system_instructions_service.py +2 -2
- claude_mpm/services/ticket_services/formatter_service.py +1 -1
- claude_mpm/services/ticket_services/validation_service.py +5 -5
- 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 +903 -0
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +746 -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 +475 -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 +470 -0
- claude_mpm/services/utility_service.py +6 -3
- claude_mpm/services/version_control/branch_strategy.py +2 -2
- claude_mpm/services/version_control/conflict_resolution.py +8 -4
- claude_mpm/services/version_control/git_operations.py +26 -24
- claude_mpm/services/version_control/semantic_versioning.py +14 -14
- claude_mpm/services/version_control/version_parser.py +14 -11
- claude_mpm/services/version_service.py +104 -1
- claude_mpm/skills/__init__.py +42 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
- claude_mpm/skills/bundled/__init__.py +6 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +573 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/security-scanning.md +327 -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/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +286 -0
- claude_mpm/skills/skill_manager.py +310 -0
- claude_mpm/skills/skills_registry.py +348 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/storage/state_storage.py +31 -31
- claude_mpm/tools/__main__.py +1 -1
- 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 +6 -6
- claude_mpm/tools/code_tree_events.py +14 -10
- claude_mpm/tools/socketio_debug.py +11 -11
- claude_mpm/utils/agent_dependency_loader.py +108 -27
- claude_mpm/utils/common.py +544 -0
- claude_mpm/utils/config_manager.py +12 -6
- claude_mpm/utils/database_connector.py +298 -0
- claude_mpm/utils/dependency_cache.py +2 -2
- claude_mpm/utils/dependency_strategies.py +15 -10
- claude_mpm/utils/display_helper.py +260 -0
- claude_mpm/utils/environment_context.py +4 -3
- claude_mpm/utils/error_handler.py +5 -3
- claude_mpm/utils/file_utils.py +13 -14
- claude_mpm/utils/git_analyzer.py +407 -0
- claude_mpm/utils/log_cleanup.py +627 -0
- claude_mpm/utils/path_operations.py +7 -4
- claude_mpm/utils/robust_installer.py +133 -24
- claude_mpm/utils/session_logging.py +2 -2
- claude_mpm/utils/subprocess_utils.py +9 -8
- claude_mpm/validation/agent_validator.py +6 -6
- claude_mpm/validation/frontmatter_validator.py +6 -6
- claude_mpm-4.24.0.dist-info/METADATA +675 -0
- claude_mpm-4.24.0.dist-info/RECORD +1018 -0
- {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/entry_points.txt +1 -0
- claude_mpm/agents/INSTRUCTIONS.md +0 -261
- claude_mpm/agents/templates/agent-manager.md +0 -619
- claude_mpm/cli/commands/configure_tui.py +0 -1927
- claude_mpm/cli/commands/mpm_init.py +0 -594
- claude_mpm/cli/commands/socketio_monitor.py +0 -233
- claude_mpm/dashboard/static/css/code-tree.css +0 -1408
- claude_mpm/dashboard/static/js/components/code-tree.js +0 -3220
- claude_mpm/dashboard/static/js/components/code-viewer.js +0 -480
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
- claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1040
- claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
- claude_mpm/scripts/socketio_daemon_hardened.py +0 -937
- claude_mpm/scripts/socketio_daemon_wrapper.py +0 -78
- claude_mpm/scripts/socketio_server_manager.py +0 -349
- claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
- claude_mpm/services/cli/dashboard_launcher.py +0 -423
- claude_mpm/services/cli/socketio_manager.py +0 -537
- claude_mpm/services/diagnostics/checks/claude_desktop_check.py +0 -286
- claude_mpm/services/mcp_gateway/tools/ticket_tools.py +0 -645
- claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +0 -602
- claude_mpm/services/project/analyzer_refactored.py +0 -450
- claude_mpm/tools/code_tree_analyzer.py +0 -1693
- claude_mpm-4.1.26.dist-info/METADATA +0 -332
- claude_mpm-4.1.26.dist-info/RECORD +0 -606
- {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/WHEEL +0 -0
- {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/top_level.txt +0 -0
|
@@ -4,9 +4,10 @@ WHY: This module handles hook events from Claude to track session information,
|
|
|
4
4
|
agent delegations, and other hook-based activity for the system heartbeat.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
from datetime import datetime
|
|
7
|
+
from datetime import datetime, timezone
|
|
8
8
|
from typing import Any, Dict
|
|
9
9
|
|
|
10
|
+
from ....core.enums import ServiceState
|
|
10
11
|
from .base import BaseEventHandler
|
|
11
12
|
|
|
12
13
|
|
|
@@ -60,13 +61,18 @@ class HookEventHandler(BaseEventHandler):
|
|
|
60
61
|
|
|
61
62
|
hook_data = data.get("data", {})
|
|
62
63
|
|
|
64
|
+
# Log hook event processing
|
|
65
|
+
tool_name = hook_data.get("tool_name", "N/A")
|
|
66
|
+
self.logger.info(f"Processing hook event: {hook_event} - tool: {tool_name}")
|
|
67
|
+
|
|
63
68
|
# Create properly formatted event for history
|
|
64
69
|
# Note: add_to_history expects the event data directly, not wrapped
|
|
65
70
|
history_event = {
|
|
66
71
|
"type": "hook",
|
|
67
72
|
"event": hook_event,
|
|
68
73
|
"data": hook_data,
|
|
69
|
-
"timestamp": data.get("timestamp")
|
|
74
|
+
"timestamp": data.get("timestamp")
|
|
75
|
+
or datetime.now(timezone.utc).isoformat(),
|
|
70
76
|
}
|
|
71
77
|
|
|
72
78
|
# Add the event to history for replay
|
|
@@ -75,6 +81,12 @@ class HookEventHandler(BaseEventHandler):
|
|
|
75
81
|
|
|
76
82
|
# Broadcast the original event to all connected clients
|
|
77
83
|
# (preserves all original fields)
|
|
84
|
+
connected_clients = (
|
|
85
|
+
len(self.server.clients) if hasattr(self.server, "clients") else 0
|
|
86
|
+
)
|
|
87
|
+
self.logger.info(
|
|
88
|
+
f"Broadcasting claude_event to {connected_clients} clients: {hook_event}"
|
|
89
|
+
)
|
|
78
90
|
await self.broadcast_event("claude_event", data)
|
|
79
91
|
|
|
80
92
|
# Track sessions based on hook events
|
|
@@ -105,11 +117,11 @@ class HookEventHandler(BaseEventHandler):
|
|
|
105
117
|
if hasattr(self.server, "active_sessions"):
|
|
106
118
|
self.server.active_sessions[session_id] = {
|
|
107
119
|
"session_id": session_id,
|
|
108
|
-
"start_time": datetime.now().isoformat(),
|
|
120
|
+
"start_time": datetime.now(timezone.utc).isoformat(),
|
|
109
121
|
"agent": agent_type,
|
|
110
|
-
"status":
|
|
122
|
+
"status": ServiceState.RUNNING,
|
|
111
123
|
"prompt": data.get("prompt", "")[:100], # First 100 chars
|
|
112
|
-
"last_activity": datetime.now().isoformat(),
|
|
124
|
+
"last_activity": datetime.now(timezone.utc).isoformat(),
|
|
113
125
|
}
|
|
114
126
|
|
|
115
127
|
self.logger.debug(
|
|
@@ -132,9 +144,9 @@ class HookEventHandler(BaseEventHandler):
|
|
|
132
144
|
if session_id in self.server.active_sessions:
|
|
133
145
|
# Mark as completed rather than removing immediately
|
|
134
146
|
self.server.active_sessions[session_id]["status"] = "completed"
|
|
135
|
-
self.server.active_sessions[session_id][
|
|
136
|
-
|
|
137
|
-
|
|
147
|
+
self.server.active_sessions[session_id]["last_activity"] = datetime.now(
|
|
148
|
+
timezone.utc
|
|
149
|
+
).isoformat()
|
|
138
150
|
|
|
139
151
|
self.logger.debug(
|
|
140
152
|
f"Marked session completed: session={session_id[:8]}..."
|
|
@@ -156,18 +168,18 @@ class HookEventHandler(BaseEventHandler):
|
|
|
156
168
|
if session_id not in self.server.active_sessions:
|
|
157
169
|
self.server.active_sessions[session_id] = {
|
|
158
170
|
"session_id": session_id,
|
|
159
|
-
"start_time": datetime.now().isoformat(),
|
|
171
|
+
"start_time": datetime.now(timezone.utc).isoformat(),
|
|
160
172
|
"agent": "pm", # Default to PM
|
|
161
|
-
"status":
|
|
173
|
+
"status": ServiceState.RUNNING,
|
|
162
174
|
"prompt": data.get("prompt_text", "")[:100],
|
|
163
175
|
"working_directory": data.get("working_directory", ""),
|
|
164
|
-
"last_activity": datetime.now().isoformat(),
|
|
176
|
+
"last_activity": datetime.now(timezone.utc).isoformat(),
|
|
165
177
|
}
|
|
166
178
|
else:
|
|
167
179
|
# Update last activity
|
|
168
|
-
self.server.active_sessions[session_id][
|
|
169
|
-
|
|
170
|
-
|
|
180
|
+
self.server.active_sessions[session_id]["last_activity"] = datetime.now(
|
|
181
|
+
timezone.utc
|
|
182
|
+
).isoformat()
|
|
171
183
|
|
|
172
184
|
async def _handle_pre_tool(self, data: Dict[str, Any]):
|
|
173
185
|
"""Handle pre-tool events.
|
|
@@ -190,9 +202,9 @@ class HookEventHandler(BaseEventHandler):
|
|
|
190
202
|
if session_id in self.server.active_sessions:
|
|
191
203
|
self.server.active_sessions[session_id]["agent"] = agent_type
|
|
192
204
|
self.server.active_sessions[session_id]["status"] = "delegated"
|
|
193
|
-
self.server.active_sessions[session_id][
|
|
194
|
-
|
|
195
|
-
|
|
205
|
+
self.server.active_sessions[session_id]["last_activity"] = datetime.now(
|
|
206
|
+
timezone.utc
|
|
207
|
+
).isoformat()
|
|
196
208
|
|
|
197
209
|
self.logger.debug(
|
|
198
210
|
f"Updated session delegation: session={session_id[:8]}..., agent={agent_type}"
|
|
@@ -15,7 +15,8 @@ if TYPE_CHECKING:
|
|
|
15
15
|
|
|
16
16
|
from ..server import SocketIOServer
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
# DISABLED: File Tree interface removed from dashboard
|
|
19
|
+
# from .code_analysis import CodeAnalysisEventHandler
|
|
19
20
|
from .connection import ConnectionEventHandler
|
|
20
21
|
from .file import FileEventHandler
|
|
21
22
|
from .git import GitEventHandler
|
|
@@ -38,7 +39,8 @@ class EventHandlerRegistry:
|
|
|
38
39
|
HookEventHandler, # Hook events for session tracking
|
|
39
40
|
GitEventHandler, # Git operations
|
|
40
41
|
FileEventHandler, # File operations
|
|
41
|
-
|
|
42
|
+
# DISABLED: File Tree interface removed from dashboard
|
|
43
|
+
# CodeAnalysisEventHandler, # Code analysis for dashboard
|
|
42
44
|
ProjectEventHandler, # Project management (future)
|
|
43
45
|
MemoryEventHandler, # Memory management (future)
|
|
44
46
|
]
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SocketIO Monitor Client for claude-mpm dashboard.
|
|
3
|
+
|
|
4
|
+
WHY: This module provides a SocketIO client that connects the dashboard to the
|
|
5
|
+
independent monitor server, allowing the dashboard to receive events even when
|
|
6
|
+
running as a separate service.
|
|
7
|
+
|
|
8
|
+
DESIGN DECISIONS:
|
|
9
|
+
- Asynchronous client using python-socketio AsyncClient
|
|
10
|
+
- Automatic reconnection with exponential backoff
|
|
11
|
+
- Event relay from monitor to dashboard UI
|
|
12
|
+
- Graceful degradation when monitor is not available
|
|
13
|
+
- Health monitoring and connection status reporting
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import asyncio
|
|
17
|
+
import threading
|
|
18
|
+
import time
|
|
19
|
+
from datetime import datetime, timezone
|
|
20
|
+
from typing import Any, Callable, Dict
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
import socketio
|
|
24
|
+
|
|
25
|
+
SOCKETIO_AVAILABLE = True
|
|
26
|
+
except ImportError:
|
|
27
|
+
SOCKETIO_AVAILABLE = False
|
|
28
|
+
socketio = None
|
|
29
|
+
|
|
30
|
+
import contextlib
|
|
31
|
+
|
|
32
|
+
from ...core.logging_config import get_logger
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class MonitorClient:
|
|
36
|
+
"""SocketIO client for connecting dashboard to monitor server.
|
|
37
|
+
|
|
38
|
+
WHY: This client allows the dashboard service to receive events from
|
|
39
|
+
the monitor server, enabling decoupled architecture where:
|
|
40
|
+
- Monitor server (port 8766) collects events from hooks
|
|
41
|
+
- Dashboard service (port 8765) provides UI and connects to monitor
|
|
42
|
+
- Dashboard can restart without affecting event collection
|
|
43
|
+
- Multiple dashboards can connect to the same monitor
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
monitor_host: str = "localhost",
|
|
49
|
+
monitor_port: int = 8766,
|
|
50
|
+
auto_reconnect: bool = True,
|
|
51
|
+
):
|
|
52
|
+
self.monitor_host = monitor_host
|
|
53
|
+
self.monitor_port = monitor_port
|
|
54
|
+
self.monitor_url = f"http://{monitor_host}:{monitor_port}"
|
|
55
|
+
self.auto_reconnect = auto_reconnect
|
|
56
|
+
|
|
57
|
+
self.logger = get_logger(__name__ + ".MonitorClient")
|
|
58
|
+
|
|
59
|
+
# Client state
|
|
60
|
+
self.client = None
|
|
61
|
+
self.connected = False
|
|
62
|
+
self.connecting = False
|
|
63
|
+
self.should_stop = False
|
|
64
|
+
self.connection_thread = None
|
|
65
|
+
self.reconnect_task = None
|
|
66
|
+
|
|
67
|
+
# Event handlers - functions to call when events are received
|
|
68
|
+
self.event_handlers: Dict[str, Callable] = {}
|
|
69
|
+
|
|
70
|
+
# Connection statistics
|
|
71
|
+
self.stats = {
|
|
72
|
+
"connection_attempts": 0,
|
|
73
|
+
"successful_connections": 0,
|
|
74
|
+
"events_received": 0,
|
|
75
|
+
"last_connected": None,
|
|
76
|
+
"last_disconnected": None,
|
|
77
|
+
"auto_reconnect_enabled": auto_reconnect,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
# Reconnection settings
|
|
81
|
+
self.reconnect_delay = 1.0 # Start with 1 second
|
|
82
|
+
self.max_reconnect_delay = 30.0 # Max 30 seconds between attempts
|
|
83
|
+
self.reconnect_backoff = 1.5 # Exponential backoff multiplier
|
|
84
|
+
|
|
85
|
+
def start(self) -> bool:
|
|
86
|
+
"""Start the monitor client and connect to monitor server."""
|
|
87
|
+
if not SOCKETIO_AVAILABLE:
|
|
88
|
+
self.logger.error("SocketIO not available - monitor client cannot start")
|
|
89
|
+
return False
|
|
90
|
+
|
|
91
|
+
if self.connected or self.connecting:
|
|
92
|
+
self.logger.info("Monitor client already connected or connecting")
|
|
93
|
+
return True
|
|
94
|
+
|
|
95
|
+
self.logger.info(f"Starting monitor client connection to {self.monitor_url}")
|
|
96
|
+
self.should_stop = False
|
|
97
|
+
|
|
98
|
+
# Start connection in background thread
|
|
99
|
+
self.connection_thread = threading.Thread(
|
|
100
|
+
target=self._run_client, daemon=True, name="MonitorClient"
|
|
101
|
+
)
|
|
102
|
+
self.connection_thread.start()
|
|
103
|
+
|
|
104
|
+
# Wait a moment for initial connection attempt
|
|
105
|
+
time.sleep(1)
|
|
106
|
+
return self.connecting or self.connected
|
|
107
|
+
|
|
108
|
+
def stop(self):
|
|
109
|
+
"""Stop the monitor client and disconnect."""
|
|
110
|
+
self.logger.info("Stopping monitor client")
|
|
111
|
+
self.should_stop = True
|
|
112
|
+
|
|
113
|
+
if self.reconnect_task:
|
|
114
|
+
with contextlib.suppress(Exception):
|
|
115
|
+
self.reconnect_task.cancel()
|
|
116
|
+
|
|
117
|
+
if self.client and self.connected:
|
|
118
|
+
try:
|
|
119
|
+
# Use the event loop from the client thread
|
|
120
|
+
if hasattr(self.client, "disconnect"):
|
|
121
|
+
asyncio.run(self.client.disconnect())
|
|
122
|
+
except Exception:
|
|
123
|
+
pass
|
|
124
|
+
|
|
125
|
+
self.connected = False
|
|
126
|
+
self.connecting = False
|
|
127
|
+
|
|
128
|
+
# Wait for thread to finish
|
|
129
|
+
if self.connection_thread and self.connection_thread.is_alive():
|
|
130
|
+
self.connection_thread.join(timeout=5)
|
|
131
|
+
|
|
132
|
+
def add_event_handler(self, event_name: str, handler: Callable):
|
|
133
|
+
"""Add an event handler for a specific event type."""
|
|
134
|
+
self.event_handlers[event_name] = handler
|
|
135
|
+
self.logger.debug(f"Added event handler for '{event_name}'")
|
|
136
|
+
|
|
137
|
+
def remove_event_handler(self, event_name: str):
|
|
138
|
+
"""Remove an event handler."""
|
|
139
|
+
if event_name in self.event_handlers:
|
|
140
|
+
del self.event_handlers[event_name]
|
|
141
|
+
self.logger.debug(f"Removed event handler for '{event_name}'")
|
|
142
|
+
|
|
143
|
+
def is_connected(self) -> bool:
|
|
144
|
+
"""Check if client is connected to monitor."""
|
|
145
|
+
return self.connected
|
|
146
|
+
|
|
147
|
+
def get_stats(self) -> Dict[str, Any]:
|
|
148
|
+
"""Get client connection statistics."""
|
|
149
|
+
return {
|
|
150
|
+
**self.stats,
|
|
151
|
+
"connected": self.connected,
|
|
152
|
+
"monitor_url": self.monitor_url,
|
|
153
|
+
"uptime": (
|
|
154
|
+
(
|
|
155
|
+
datetime.now(timezone.utc)
|
|
156
|
+
- datetime.fromisoformat(self.stats["last_connected"])
|
|
157
|
+
).total_seconds()
|
|
158
|
+
if self.stats["last_connected"] and self.connected
|
|
159
|
+
else 0
|
|
160
|
+
),
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
def _run_client(self):
|
|
164
|
+
"""Run the client in its own event loop."""
|
|
165
|
+
try:
|
|
166
|
+
# Create new event loop for this thread
|
|
167
|
+
loop = asyncio.new_event_loop()
|
|
168
|
+
asyncio.set_event_loop(loop)
|
|
169
|
+
|
|
170
|
+
# Run the async client
|
|
171
|
+
loop.run_until_complete(self._run_client_async())
|
|
172
|
+
|
|
173
|
+
except Exception as e:
|
|
174
|
+
self.logger.error(f"Error in monitor client thread: {e}")
|
|
175
|
+
finally:
|
|
176
|
+
self.connected = False
|
|
177
|
+
self.connecting = False
|
|
178
|
+
|
|
179
|
+
async def _run_client_async(self):
|
|
180
|
+
"""Run the async client with reconnection logic."""
|
|
181
|
+
while not self.should_stop:
|
|
182
|
+
try:
|
|
183
|
+
await self._connect_to_monitor()
|
|
184
|
+
|
|
185
|
+
if self.connected:
|
|
186
|
+
# Wait for disconnection or stop signal
|
|
187
|
+
while self.connected and not self.should_stop:
|
|
188
|
+
await asyncio.sleep(1)
|
|
189
|
+
|
|
190
|
+
# Handle reconnection
|
|
191
|
+
if not self.should_stop and self.auto_reconnect:
|
|
192
|
+
await self._handle_reconnection()
|
|
193
|
+
else:
|
|
194
|
+
break
|
|
195
|
+
|
|
196
|
+
except Exception as e:
|
|
197
|
+
self.logger.error(f"Error in monitor client loop: {e}")
|
|
198
|
+
if not self.auto_reconnect:
|
|
199
|
+
break
|
|
200
|
+
await asyncio.sleep(self.reconnect_delay)
|
|
201
|
+
|
|
202
|
+
async def _connect_to_monitor(self):
|
|
203
|
+
"""Establish connection to monitor server."""
|
|
204
|
+
try:
|
|
205
|
+
self.connecting = True
|
|
206
|
+
self.stats["connection_attempts"] += 1
|
|
207
|
+
|
|
208
|
+
self.logger.info(f"Connecting to monitor server at {self.monitor_url}")
|
|
209
|
+
|
|
210
|
+
# Create new SocketIO client
|
|
211
|
+
self.client = socketio.AsyncClient(
|
|
212
|
+
logger=False,
|
|
213
|
+
engineio_logger=False,
|
|
214
|
+
reconnection=False, # We handle reconnection ourselves
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
# Register event handlers
|
|
218
|
+
self._register_client_events()
|
|
219
|
+
|
|
220
|
+
# Connect to monitor server
|
|
221
|
+
await self.client.connect(self.monitor_url)
|
|
222
|
+
|
|
223
|
+
# Connection successful
|
|
224
|
+
self.connected = True
|
|
225
|
+
self.connecting = False
|
|
226
|
+
self.stats["successful_connections"] += 1
|
|
227
|
+
self.stats["last_connected"] = datetime.now(timezone.utc).isoformat()
|
|
228
|
+
self.reconnect_delay = 1.0 # Reset reconnect delay on successful connection
|
|
229
|
+
|
|
230
|
+
self.logger.info(f"Connected to monitor server at {self.monitor_url}")
|
|
231
|
+
|
|
232
|
+
# Request status from monitor
|
|
233
|
+
await self.client.emit("get_status")
|
|
234
|
+
|
|
235
|
+
except Exception as e:
|
|
236
|
+
self.logger.error(f"Failed to connect to monitor server: {e}")
|
|
237
|
+
self.connected = False
|
|
238
|
+
self.connecting = False
|
|
239
|
+
|
|
240
|
+
if self.client:
|
|
241
|
+
with contextlib.suppress(Exception):
|
|
242
|
+
await self.client.disconnect()
|
|
243
|
+
self.client = None
|
|
244
|
+
|
|
245
|
+
def _register_client_events(self):
|
|
246
|
+
"""Register client-side event handlers."""
|
|
247
|
+
|
|
248
|
+
@self.client.event
|
|
249
|
+
async def connect():
|
|
250
|
+
"""Handle successful connection."""
|
|
251
|
+
self.logger.info("Successfully connected to monitor server")
|
|
252
|
+
|
|
253
|
+
@self.client.event
|
|
254
|
+
async def disconnect():
|
|
255
|
+
"""Handle disconnection."""
|
|
256
|
+
self.logger.info("Disconnected from monitor server")
|
|
257
|
+
self.connected = False
|
|
258
|
+
self.stats["last_disconnected"] = datetime.now(timezone.utc).isoformat()
|
|
259
|
+
|
|
260
|
+
@self.client.event
|
|
261
|
+
async def connect_error(data):
|
|
262
|
+
"""Handle connection error."""
|
|
263
|
+
self.logger.error(f"Connection error: {data}")
|
|
264
|
+
self.connected = False
|
|
265
|
+
|
|
266
|
+
@self.client.event
|
|
267
|
+
async def status_response(data):
|
|
268
|
+
"""Handle status response from monitor."""
|
|
269
|
+
self.logger.debug(f"Monitor server status: {data}")
|
|
270
|
+
|
|
271
|
+
# Register handlers for all monitor events that we want to relay
|
|
272
|
+
monitor_events = [
|
|
273
|
+
"session_started",
|
|
274
|
+
"session_ended",
|
|
275
|
+
"claude_status",
|
|
276
|
+
"claude_output",
|
|
277
|
+
"agent_delegated",
|
|
278
|
+
"todos_updated",
|
|
279
|
+
"ticket_created",
|
|
280
|
+
"memory_loaded",
|
|
281
|
+
"memory_created",
|
|
282
|
+
"memory_updated",
|
|
283
|
+
"memory_injected",
|
|
284
|
+
"file_changed",
|
|
285
|
+
"git_status_changed",
|
|
286
|
+
"project_analyzed",
|
|
287
|
+
"connection_status",
|
|
288
|
+
"heartbeat",
|
|
289
|
+
]
|
|
290
|
+
|
|
291
|
+
for event_name in monitor_events:
|
|
292
|
+
# Create a closure to capture the event name
|
|
293
|
+
def make_handler(event_name):
|
|
294
|
+
async def handler(data):
|
|
295
|
+
await self._handle_monitor_event(event_name, data)
|
|
296
|
+
|
|
297
|
+
return handler
|
|
298
|
+
|
|
299
|
+
self.client.on(event_name, make_handler(event_name))
|
|
300
|
+
|
|
301
|
+
async def _handle_monitor_event(self, event_name: str, data: Any):
|
|
302
|
+
"""Handle event received from monitor server."""
|
|
303
|
+
self.stats["events_received"] += 1
|
|
304
|
+
self.logger.debug(f"Received event from monitor: {event_name}")
|
|
305
|
+
|
|
306
|
+
# Call registered event handler if available
|
|
307
|
+
if event_name in self.event_handlers:
|
|
308
|
+
try:
|
|
309
|
+
handler = self.event_handlers[event_name]
|
|
310
|
+
if asyncio.iscoroutinefunction(handler):
|
|
311
|
+
await handler(data)
|
|
312
|
+
else:
|
|
313
|
+
handler(data)
|
|
314
|
+
except Exception as e:
|
|
315
|
+
self.logger.error(f"Error in event handler for {event_name}: {e}")
|
|
316
|
+
|
|
317
|
+
async def _handle_reconnection(self):
|
|
318
|
+
"""Handle reconnection with exponential backoff."""
|
|
319
|
+
if self.should_stop:
|
|
320
|
+
return
|
|
321
|
+
|
|
322
|
+
self.logger.info(
|
|
323
|
+
f"Attempting to reconnect in {self.reconnect_delay:.1f} seconds"
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
try:
|
|
327
|
+
await asyncio.sleep(self.reconnect_delay)
|
|
328
|
+
|
|
329
|
+
# Increase reconnect delay for next attempt (exponential backoff)
|
|
330
|
+
self.reconnect_delay = min(
|
|
331
|
+
self.reconnect_delay * self.reconnect_backoff, self.max_reconnect_delay
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
except asyncio.CancelledError:
|
|
335
|
+
# Sleep was cancelled, probably due to stop()
|
|
336
|
+
pass
|
|
337
|
+
|
|
338
|
+
def send_to_monitor(self, event_name: str, data: Any = None) -> bool:
|
|
339
|
+
"""Send an event to the monitor server."""
|
|
340
|
+
if not self.connected or not self.client:
|
|
341
|
+
self.logger.warning(
|
|
342
|
+
f"Cannot send event '{event_name}' - not connected to monitor"
|
|
343
|
+
)
|
|
344
|
+
return False
|
|
345
|
+
|
|
346
|
+
try:
|
|
347
|
+
# Schedule the emission in the client's event loop
|
|
348
|
+
if hasattr(self.client, "emit"):
|
|
349
|
+
# Create a simple coroutine to emit the event
|
|
350
|
+
async def emit_event():
|
|
351
|
+
await self.client.emit(event_name, data)
|
|
352
|
+
|
|
353
|
+
# Run it in the client's event loop if available
|
|
354
|
+
if hasattr(self.client, "eio") and hasattr(self.client.eio, "loop"):
|
|
355
|
+
loop = self.client.eio.loop
|
|
356
|
+
if loop and not loop.is_closed():
|
|
357
|
+
asyncio.run_coroutine_threadsafe(emit_event(), loop)
|
|
358
|
+
return True
|
|
359
|
+
|
|
360
|
+
return False
|
|
361
|
+
|
|
362
|
+
except Exception as e:
|
|
363
|
+
self.logger.error(f"Error sending event to monitor: {e}")
|
|
364
|
+
return False
|
|
@@ -13,7 +13,7 @@ import asyncio
|
|
|
13
13
|
import time
|
|
14
14
|
from collections import deque
|
|
15
15
|
from dataclasses import dataclass
|
|
16
|
-
from datetime import datetime
|
|
16
|
+
from datetime import datetime, timezone
|
|
17
17
|
from typing import Any, Deque, Dict, List, Optional, Set
|
|
18
18
|
|
|
19
19
|
from ..event_normalizer import EventNormalizer
|
|
@@ -284,7 +284,7 @@ class SocketIOEventBroadcaster:
|
|
|
284
284
|
# Reconstruct the raw event
|
|
285
285
|
raw_event = {
|
|
286
286
|
"type": event.event_type,
|
|
287
|
-
"timestamp": datetime.now().isoformat(),
|
|
287
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
288
288
|
"data": {**event.data, "retry_attempt": event.attempt_count + 1},
|
|
289
289
|
}
|
|
290
290
|
|
|
@@ -323,7 +323,7 @@ class SocketIOEventBroadcaster:
|
|
|
323
323
|
# Create raw event for normalization
|
|
324
324
|
raw_event = {
|
|
325
325
|
"type": event_type,
|
|
326
|
-
"timestamp": datetime.now().isoformat(),
|
|
326
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
327
327
|
"data": data,
|
|
328
328
|
}
|
|
329
329
|
|
|
@@ -388,11 +388,11 @@ class SocketIOEventBroadcaster:
|
|
|
388
388
|
asyncio.run_coroutine_threadsafe(
|
|
389
389
|
update_activities(), self.loop
|
|
390
390
|
)
|
|
391
|
-
except:
|
|
391
|
+
except Exception:
|
|
392
392
|
pass # Non-critical
|
|
393
393
|
|
|
394
394
|
self.logger.debug(f"Broadcasted event: {event_type}")
|
|
395
|
-
except:
|
|
395
|
+
except Exception:
|
|
396
396
|
# Will be added to retry queue below
|
|
397
397
|
pass
|
|
398
398
|
else:
|
|
@@ -426,13 +426,15 @@ class SocketIOEventBroadcaster:
|
|
|
426
426
|
"session_id": session_id,
|
|
427
427
|
"launch_method": launch_method,
|
|
428
428
|
"working_dir": working_dir,
|
|
429
|
-
"timestamp": datetime.now().isoformat(),
|
|
429
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
430
430
|
},
|
|
431
431
|
)
|
|
432
432
|
|
|
433
433
|
def session_ended(self):
|
|
434
434
|
"""Notify that a session has ended."""
|
|
435
|
-
self.broadcast_event(
|
|
435
|
+
self.broadcast_event(
|
|
436
|
+
"session_ended", {"timestamp": datetime.now(timezone.utc).isoformat()}
|
|
437
|
+
)
|
|
436
438
|
|
|
437
439
|
def claude_status_changed(
|
|
438
440
|
self, status: str, pid: Optional[int] = None, message: str = ""
|
|
@@ -14,7 +14,7 @@ import contextlib
|
|
|
14
14
|
import time
|
|
15
15
|
from collections import deque
|
|
16
16
|
from dataclasses import dataclass, field
|
|
17
|
-
from datetime import datetime
|
|
17
|
+
from datetime import datetime, timezone
|
|
18
18
|
from enum import Enum
|
|
19
19
|
from typing import Any, Deque, Dict, List, Optional
|
|
20
20
|
from uuid import uuid4
|
|
@@ -464,7 +464,7 @@ class ConnectionManager:
|
|
|
464
464
|
async with self._lock:
|
|
465
465
|
now = time.time()
|
|
466
466
|
report = {
|
|
467
|
-
"timestamp": datetime.now().isoformat(),
|
|
467
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
468
468
|
"total_connections": len(self.connections),
|
|
469
469
|
"healthy": 0,
|
|
470
470
|
"stale": 0,
|