claude-mpm 4.1.6__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 +431 -214
- 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/MEMORY.md +3 -0
- claude_mpm/agents/OUTPUT_STYLE.md +335 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +1159 -0
- claude_mpm/agents/WORKFLOW.md +355 -187
- claude_mpm/agents/agent_loader.py +40 -10
- claude_mpm/agents/agent_loader_integration.py +3 -2
- claude_mpm/agents/agents_metadata.py +57 -0
- 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/.claude-mpm/memories/README.md +17 -0
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +3 -0
- claude_mpm/agents/templates/README.md +465 -0
- claude_mpm/agents/templates/agent-manager.json +267 -18
- claude_mpm/agents/templates/agentic-coder-optimizer.json +248 -0
- 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 +25 -9
- 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 +44 -10
- 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_20250826_014258_728.md +39 -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 +27 -8
- 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 +26 -6
- claude_mpm/agents/templates/react_engineer.json +239 -0
- claude_mpm/agents/templates/refactoring_engineer.json +15 -5
- claude_mpm/agents/templates/research.json +47 -22
- 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 +243 -21
- claude_mpm/agents/templates/web_ui.json +18 -5
- claude_mpm/cli/__init__.py +38 -363
- claude_mpm/cli/commands/__init__.py +8 -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 +553 -0
- claude_mpm/cli/commands/analyze_code.py +528 -0
- 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 +488 -884
- 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 +286 -0
- claude_mpm/cli/commands/debug.py +1386 -0
- 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 +168 -617
- 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 +195 -0
- 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/analyze_code_parser.py +170 -0
- claude_mpm/cli/parsers/analyze_parser.py +135 -0
- claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
- claude_mpm/cli/parsers/base_parser.py +187 -3
- claude_mpm/cli/parsers/configure_parser.py +34 -15
- claude_mpm/cli/parsers/dashboard_parser.py +113 -0
- claude_mpm/cli/parsers/debug_parser.py +319 -0
- claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
- claude_mpm/cli/parsers/mcp_parser.py +15 -0
- claude_mpm/cli/parsers/monitor_parser.py +12 -2
- claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
- 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/__init__.py +14 -0
- claude_mpm/commands/mpm-agents-detect.md +168 -0
- claude_mpm/commands/mpm-agents-recommend.md +214 -0
- claude_mpm/commands/mpm-agents.md +122 -0
- claude_mpm/commands/mpm-auto-configure.md +269 -0
- claude_mpm/commands/mpm-config.md +141 -0
- claude_mpm/commands/mpm-doctor.md +24 -0
- claude_mpm/commands/mpm-help.md +290 -0
- claude_mpm/commands/mpm-init.md +521 -0
- 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 +75 -0
- claude_mpm/commands/mpm-tickets.md +151 -0
- claude_mpm/commands/mpm-version.md +113 -0
- claude_mpm/commands/mpm.md +21 -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 +36 -7
- claude_mpm/constants.py +27 -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 +103 -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 +323 -1491
- claude_mpm/core/hook_manager.py +8 -6
- claude_mpm/core/injectable_service.py +11 -8
- claude_mpm/core/instruction_reinforcement_hook.py +267 -0
- 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 +100 -28
- 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 +118 -15
- 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 +116 -12
- claude_mpm/core/unified_config.py +6 -6
- claude_mpm/core/unified_paths.py +23 -20
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +1 -0
- claude_mpm/dashboard/__init__.py +12 -0
- claude_mpm/dashboard/analysis_runner.py +455 -0
- 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 +2 -0
- 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 +2 -0
- claude_mpm/dashboard/static/built/components/code-viewer.js +2 -0
- 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 +2 -0
- 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/activity.css +1958 -0
- claude_mpm/dashboard/static/css/dashboard.css +1413 -72
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +1 -0
- claude_mpm/dashboard/static/dist/components/activity-tree.js +2 -0
- claude_mpm/dashboard/static/dist/components/agent-inference.js +1 -1
- claude_mpm/dashboard/static/dist/components/code-tree.js +2 -0
- claude_mpm/dashboard/static/dist/components/code-viewer.js +2 -0
- 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 +2 -0
- 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 +1871 -0
- 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 +23 -13
- 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 -107
- claude_mpm/dashboard/static/js/components/event-viewer.js +98 -11
- 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 +68 -205
- claude_mpm/dashboard/static/js/components/session-manager.js +46 -10
- claude_mpm/dashboard/static/js/components/socket-manager.js +16 -0
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +359 -40
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +1824 -0
- claude_mpm/dashboard/static/js/components/working-directory.js +61 -10
- claude_mpm/dashboard/static/js/connection-manager.js +1 -1
- claude_mpm/dashboard/static/js/dashboard.js +523 -622
- 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 +549 -62
- 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 +267 -9
- claude_mpm/experimental/__init__.py +10 -0
- 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 +209 -25
- claude_mpm/hooks/claude_hooks/installer.py +783 -0
- 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 +64 -49
- 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/schemas/__init__.py +12 -0
- claude_mpm/scripts/claude-hook-handler.sh +187 -0
- 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 +156 -396
- 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_config_provider.py +127 -27
- 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 +5 -6
- claude_mpm/services/agents/deployment/agent_state_service.py +2 -2
- claude_mpm/services/agents/deployment/agent_template_builder.py +722 -37
- claude_mpm/services/agents/deployment/agent_validator.py +31 -7
- claude_mpm/services/agents/deployment/agent_version_manager.py +9 -1
- 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 +7 -7
- 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 +6 -5
- claude_mpm/services/cli/agent_dependency_service.py +1 -1
- claude_mpm/services/cli/agent_listing_service.py +5 -5
- claude_mpm/services/cli/agent_validation_service.py +6 -5
- 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 -21
- claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
- claude_mpm/services/command_deployment_service.py +17 -9
- 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/cache_manager.py +1 -3
- 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 +37 -18
- claude_mpm/services/core/service_container.py +2 -2
- 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 +22 -24
- 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 +152 -13
- 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 +12 -12
- 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/monitoring.py +12 -12
- 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 +6 -6
- claude_mpm/services/project/archive_manager.py +1045 -0
- claude_mpm/services/project/dependency_analyzer.py +8 -8
- 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/language_analyzer.py +3 -3
- claude_mpm/services/project/metrics_collector.py +7 -10
- 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 +74 -6
- claude_mpm/services/socketio/handlers/__init__.py +5 -0
- claude_mpm/services/socketio/handlers/base.py +2 -2
- claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
- claude_mpm/services/socketio/handlers/connection.py +21 -40
- claude_mpm/services/socketio/handlers/connection_handler.py +16 -28
- 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 -0
- 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 +131 -68
- claude_mpm/services/socketio/server/core.py +275 -22
- claude_mpm/services/socketio/server/eventbus_integration.py +20 -14
- claude_mpm/services/socketio/server/main.py +99 -29
- 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/services/visualization/__init__.py +19 -0
- claude_mpm/services/visualization/mermaid_generator.py +938 -0
- claude_mpm/skills/__init__.py +42 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
- claude_mpm/skills/bundled/__init__.py +6 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/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/__init__.py +10 -0
- claude_mpm/tools/__main__.py +208 -0
- claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
- claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
- claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
- claude_mpm/tools/code_tree_analyzer/core.py +380 -0
- claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
- claude_mpm/tools/code_tree_analyzer/events.py +168 -0
- claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
- claude_mpm/tools/code_tree_analyzer/models.py +39 -0
- claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
- claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
- claude_mpm/tools/code_tree_builder.py +631 -0
- claude_mpm/tools/code_tree_events.py +420 -0
- claude_mpm/tools/socketio_debug.py +671 -0
- claude_mpm/utils/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.6.dist-info → claude_mpm-4.24.0.dist-info}/entry_points.txt +1 -0
- claude_mpm/agents/INSTRUCTIONS.md +0 -237
- claude_mpm/agents/schema/agent_schema.json +0 -314
- claude_mpm/agents/templates/agent-manager.md +0 -304
- claude_mpm/cli/commands/configure_tui.py +0 -1921
- claude_mpm/cli/commands/socketio_monitor.py +0 -233
- 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_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 -424
- claude_mpm/services/cli/socketio_manager.py +0 -498
- 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-4.1.6.dist-info/METADATA +0 -325
- claude_mpm-4.1.6.dist-info/RECORD +0 -550
- {claude_mpm-4.1.6.dist-info → claude_mpm-4.24.0.dist-info}/WHEEL +0 -0
- {claude_mpm-4.1.6.dist-info → claude_mpm-4.24.0.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.1.6.dist-info → claude_mpm-4.24.0.dist-info}/top_level.txt +0 -0
|
@@ -10,10 +10,11 @@ of client states, proper event delivery, and automatic recovery mechanisms.
|
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
import asyncio
|
|
13
|
+
import contextlib
|
|
13
14
|
import time
|
|
14
15
|
from collections import deque
|
|
15
16
|
from dataclasses import dataclass, field
|
|
16
|
-
from datetime import datetime
|
|
17
|
+
from datetime import datetime, timezone
|
|
17
18
|
from enum import Enum
|
|
18
19
|
from typing import Any, Deque, Dict, List, Optional
|
|
19
20
|
from uuid import uuid4
|
|
@@ -71,20 +72,28 @@ class ClientConnection:
|
|
|
71
72
|
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
72
73
|
|
|
73
74
|
def is_healthy(self, timeout: float = 90.0) -> bool:
|
|
74
|
-
"""Check if connection is healthy based on activity.
|
|
75
|
+
"""Check if connection is healthy based on activity.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
timeout: Seconds before considering connection unhealthy (default 90s)
|
|
79
|
+
"""
|
|
75
80
|
if self.state != ConnectionState.CONNECTED:
|
|
76
81
|
return False
|
|
77
82
|
|
|
78
83
|
now = time.time()
|
|
79
84
|
|
|
80
85
|
# Check last activity (ping, pong, or event)
|
|
86
|
+
# Include metrics.last_activity for more comprehensive tracking
|
|
81
87
|
last_activity = max(
|
|
82
88
|
self.last_ping or 0,
|
|
83
89
|
self.last_pong or 0,
|
|
84
90
|
self.last_event or 0,
|
|
91
|
+
self.metrics.last_activity or 0,
|
|
85
92
|
self.connected_at,
|
|
86
93
|
)
|
|
87
94
|
|
|
95
|
+
# More aggressive timeout for stale detection (no grace period)
|
|
96
|
+
# This helps identify truly stale connections faster
|
|
88
97
|
return (now - last_activity) < timeout
|
|
89
98
|
|
|
90
99
|
def calculate_quality(self) -> float:
|
|
@@ -140,22 +149,30 @@ class ConnectionManager:
|
|
|
140
149
|
- Automatic event replay on reconnection
|
|
141
150
|
"""
|
|
142
151
|
|
|
143
|
-
def __init__(
|
|
152
|
+
def __init__(
|
|
153
|
+
self, max_buffer_size: Optional[int] = None, event_ttl: Optional[int] = None
|
|
154
|
+
):
|
|
144
155
|
"""
|
|
145
|
-
Initialize connection manager.
|
|
156
|
+
Initialize connection manager with centralized configuration.
|
|
146
157
|
|
|
147
158
|
Args:
|
|
148
|
-
max_buffer_size: Maximum events to buffer per client
|
|
149
|
-
event_ttl: Time-to-live for buffered events in seconds
|
|
159
|
+
max_buffer_size: Maximum events to buffer per client (uses config if None)
|
|
160
|
+
event_ttl: Time-to-live for buffered events in seconds (uses config if None)
|
|
150
161
|
"""
|
|
162
|
+
from ....config.socketio_config import CONNECTION_CONFIG
|
|
163
|
+
|
|
151
164
|
self.logger = get_logger(__name__)
|
|
152
165
|
self.connections: Dict[str, ClientConnection] = {}
|
|
153
166
|
self.client_mapping: Dict[str, str] = {} # client_id -> current sid
|
|
154
|
-
|
|
155
|
-
|
|
167
|
+
|
|
168
|
+
# Use centralized configuration with optional overrides
|
|
169
|
+
self.max_buffer_size = max_buffer_size or CONNECTION_CONFIG["max_events_buffer"]
|
|
170
|
+
self.event_ttl = event_ttl or CONNECTION_CONFIG["event_ttl"]
|
|
156
171
|
self.global_sequence = 0
|
|
157
|
-
self.health_check_interval =
|
|
158
|
-
|
|
172
|
+
self.health_check_interval = CONNECTION_CONFIG[
|
|
173
|
+
"health_check_interval"
|
|
174
|
+
] # 30 seconds
|
|
175
|
+
self.stale_timeout = CONNECTION_CONFIG["stale_timeout"] # 180 seconds (was 90)
|
|
159
176
|
self.health_task = None
|
|
160
177
|
self._lock = asyncio.Lock()
|
|
161
178
|
|
|
@@ -163,7 +180,7 @@ class ConnectionManager:
|
|
|
163
180
|
self, sid: str, client_id: Optional[str] = None
|
|
164
181
|
) -> ClientConnection:
|
|
165
182
|
"""
|
|
166
|
-
Register a new connection or reconnection.
|
|
183
|
+
Register a new connection or reconnection with retry logic.
|
|
167
184
|
|
|
168
185
|
Args:
|
|
169
186
|
sid: Socket ID
|
|
@@ -172,54 +189,84 @@ class ConnectionManager:
|
|
|
172
189
|
Returns:
|
|
173
190
|
ClientConnection object
|
|
174
191
|
"""
|
|
175
|
-
|
|
176
|
-
|
|
192
|
+
max_retries = 3
|
|
193
|
+
retry_delay = 0.1 # Start with 100ms
|
|
194
|
+
|
|
195
|
+
for attempt in range(max_retries):
|
|
196
|
+
try:
|
|
197
|
+
async with self._lock:
|
|
198
|
+
now = time.time()
|
|
199
|
+
|
|
200
|
+
# Check if this is a reconnection
|
|
201
|
+
if client_id and client_id in self.client_mapping:
|
|
202
|
+
old_sid = self.client_mapping[client_id]
|
|
203
|
+
if old_sid in self.connections:
|
|
204
|
+
old_conn = self.connections[old_sid]
|
|
205
|
+
|
|
206
|
+
# Create new connection with history
|
|
207
|
+
conn = ClientConnection(
|
|
208
|
+
sid=sid,
|
|
209
|
+
client_id=client_id,
|
|
210
|
+
state=ConnectionState.CONNECTED,
|
|
211
|
+
connected_at=now,
|
|
212
|
+
event_buffer=old_conn.event_buffer,
|
|
213
|
+
event_sequence=old_conn.event_sequence,
|
|
214
|
+
last_acked_sequence=old_conn.last_acked_sequence,
|
|
215
|
+
metrics=old_conn.metrics,
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
# Update metrics
|
|
219
|
+
conn.metrics.reconnect_count += 1
|
|
220
|
+
conn.metrics.connect_count += 1
|
|
221
|
+
if old_conn.disconnected_at:
|
|
222
|
+
conn.metrics.total_downtime += (
|
|
223
|
+
now - old_conn.disconnected_at
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
# Clean up old connection
|
|
227
|
+
del self.connections[old_sid]
|
|
228
|
+
|
|
229
|
+
self.logger.info(
|
|
230
|
+
f"Client {client_id} reconnected (new sid: {sid}, "
|
|
231
|
+
f"buffered events: {len(conn.event_buffer)})"
|
|
232
|
+
)
|
|
233
|
+
else:
|
|
234
|
+
# No old connection found, create new
|
|
235
|
+
client_id = client_id or str(uuid4())
|
|
236
|
+
conn = self._create_new_connection(sid, client_id, now)
|
|
237
|
+
else:
|
|
238
|
+
# New client
|
|
239
|
+
client_id = client_id or str(uuid4())
|
|
240
|
+
conn = self._create_new_connection(sid, client_id, now)
|
|
177
241
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
242
|
+
# Register connection with validation
|
|
243
|
+
if conn and conn.state == ConnectionState.CONNECTED:
|
|
244
|
+
self.connections[sid] = conn
|
|
245
|
+
self.client_mapping[client_id] = sid
|
|
246
|
+
return conn
|
|
247
|
+
raise ValueError(f"Invalid connection state for {sid}")
|
|
183
248
|
|
|
184
|
-
|
|
249
|
+
except Exception as e:
|
|
250
|
+
self.logger.warning(
|
|
251
|
+
f"Failed to register connection {sid} (attempt {attempt + 1}/{max_retries}): {e}"
|
|
252
|
+
)
|
|
253
|
+
if attempt < max_retries - 1:
|
|
254
|
+
await asyncio.sleep(retry_delay)
|
|
255
|
+
retry_delay *= 2 # Exponential backoff
|
|
256
|
+
else:
|
|
257
|
+
# Final attempt failed, create minimal connection
|
|
258
|
+
self.logger.error(
|
|
259
|
+
f"All attempts failed for {sid}, creating minimal connection"
|
|
260
|
+
)
|
|
185
261
|
conn = ClientConnection(
|
|
186
262
|
sid=sid,
|
|
187
|
-
client_id=client_id,
|
|
263
|
+
client_id=client_id or str(uuid4()),
|
|
188
264
|
state=ConnectionState.CONNECTED,
|
|
189
|
-
connected_at=
|
|
190
|
-
event_buffer=old_conn.event_buffer,
|
|
191
|
-
event_sequence=old_conn.event_sequence,
|
|
192
|
-
last_acked_sequence=old_conn.last_acked_sequence,
|
|
193
|
-
metrics=old_conn.metrics,
|
|
194
|
-
)
|
|
195
|
-
|
|
196
|
-
# Update metrics
|
|
197
|
-
conn.metrics.reconnect_count += 1
|
|
198
|
-
conn.metrics.connect_count += 1
|
|
199
|
-
if old_conn.disconnected_at:
|
|
200
|
-
conn.metrics.total_downtime += now - old_conn.disconnected_at
|
|
201
|
-
|
|
202
|
-
# Clean up old connection
|
|
203
|
-
del self.connections[old_sid]
|
|
204
|
-
|
|
205
|
-
self.logger.info(
|
|
206
|
-
f"Client {client_id} reconnected (new sid: {sid}, "
|
|
207
|
-
f"buffered events: {len(conn.event_buffer)})"
|
|
265
|
+
connected_at=time.time(),
|
|
208
266
|
)
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
conn = self._create_new_connection(sid, client_id, now)
|
|
213
|
-
else:
|
|
214
|
-
# New client
|
|
215
|
-
client_id = client_id or str(uuid4())
|
|
216
|
-
conn = self._create_new_connection(sid, client_id, now)
|
|
217
|
-
|
|
218
|
-
# Register connection
|
|
219
|
-
self.connections[sid] = conn
|
|
220
|
-
self.client_mapping[client_id] = sid
|
|
221
|
-
|
|
222
|
-
return conn
|
|
267
|
+
self.connections[sid] = conn
|
|
268
|
+
return conn
|
|
269
|
+
return None
|
|
223
270
|
|
|
224
271
|
def _create_new_connection(
|
|
225
272
|
self, sid: str, client_id: str, now: float
|
|
@@ -391,10 +438,8 @@ class ConnectionManager:
|
|
|
391
438
|
"""Stop the health monitoring task."""
|
|
392
439
|
if self.health_task:
|
|
393
440
|
self.health_task.cancel()
|
|
394
|
-
|
|
441
|
+
with contextlib.suppress(asyncio.CancelledError):
|
|
395
442
|
await self.health_task
|
|
396
|
-
except asyncio.CancelledError:
|
|
397
|
-
pass
|
|
398
443
|
self.health_task = None
|
|
399
444
|
self.logger.info("Stopped connection health monitoring")
|
|
400
445
|
|
|
@@ -419,7 +464,7 @@ class ConnectionManager:
|
|
|
419
464
|
async with self._lock:
|
|
420
465
|
now = time.time()
|
|
421
466
|
report = {
|
|
422
|
-
"timestamp": datetime.now().isoformat(),
|
|
467
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
423
468
|
"total_connections": len(self.connections),
|
|
424
469
|
"healthy": 0,
|
|
425
470
|
"stale": 0,
|
|
@@ -439,21 +484,39 @@ class ConnectionManager:
|
|
|
439
484
|
if conn.is_healthy(self.stale_timeout):
|
|
440
485
|
report["healthy"] += 1
|
|
441
486
|
else:
|
|
442
|
-
# Mark as stale
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
487
|
+
# Mark as stale only if really stale (no grace period activity)
|
|
488
|
+
last_activity = max(
|
|
489
|
+
conn.last_ping or 0,
|
|
490
|
+
conn.last_pong or 0,
|
|
491
|
+
conn.last_event or 0,
|
|
492
|
+
conn.metrics.last_activity or 0,
|
|
493
|
+
conn.connected_at,
|
|
448
494
|
)
|
|
495
|
+
time_since_activity = now - last_activity
|
|
496
|
+
|
|
497
|
+
# Only mark as stale if significantly over timeout (2x)
|
|
498
|
+
if time_since_activity > (self.stale_timeout * 2):
|
|
499
|
+
conn.state = ConnectionState.STALE
|
|
500
|
+
report["stale"] += 1
|
|
501
|
+
self.logger.warning(
|
|
502
|
+
f"Connection {conn.client_id} marked as stale "
|
|
503
|
+
f"(last activity: {time_since_activity:.1f}s ago)"
|
|
504
|
+
)
|
|
505
|
+
else:
|
|
506
|
+
# Connection is borderline - keep it alive but log
|
|
507
|
+
report["healthy"] += 1
|
|
508
|
+
self.logger.debug(
|
|
509
|
+
f"Connection {conn.client_id} borderline "
|
|
510
|
+
f"(last activity: {time_since_activity:.1f}s ago)"
|
|
511
|
+
)
|
|
512
|
+
|
|
449
513
|
elif conn.state == ConnectionState.DISCONNECTED:
|
|
450
514
|
report["disconnected"] += 1
|
|
451
515
|
|
|
452
|
-
# Clean up old disconnected connections
|
|
453
|
-
if (
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
):
|
|
516
|
+
# Clean up old disconnected connections (be conservative)
|
|
517
|
+
if conn.disconnected_at and (now - conn.disconnected_at) > (
|
|
518
|
+
self.event_ttl * 2
|
|
519
|
+
): # Double the TTL
|
|
457
520
|
to_clean.append(sid)
|
|
458
521
|
|
|
459
522
|
# Clean up old connections
|
|
@@ -13,7 +13,7 @@ import asyncio
|
|
|
13
13
|
import threading
|
|
14
14
|
import time
|
|
15
15
|
from collections import deque
|
|
16
|
-
from datetime import datetime
|
|
16
|
+
from datetime import datetime, timezone
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
from typing import Any, Dict, Set
|
|
19
19
|
|
|
@@ -158,23 +158,46 @@ class SocketIOServerCore:
|
|
|
158
158
|
async def _start_server(self):
|
|
159
159
|
"""Start the Socket.IO server with aiohttp."""
|
|
160
160
|
try:
|
|
161
|
-
#
|
|
161
|
+
# Import centralized configuration for consistency
|
|
162
|
+
from ....config.socketio_config import CONNECTION_CONFIG
|
|
163
|
+
|
|
164
|
+
# Create Socket.IO server with centralized configuration
|
|
165
|
+
# CRITICAL: These values MUST match client settings to prevent disconnections
|
|
162
166
|
self.sio = socketio.AsyncServer(
|
|
163
167
|
cors_allowed_origins="*",
|
|
164
168
|
logger=False, # Disable Socket.IO's own logging
|
|
165
169
|
engineio_logger=False,
|
|
166
|
-
ping_interval=
|
|
167
|
-
|
|
168
|
-
|
|
170
|
+
ping_interval=CONNECTION_CONFIG[
|
|
171
|
+
"ping_interval"
|
|
172
|
+
], # 45 seconds from config
|
|
173
|
+
ping_timeout=CONNECTION_CONFIG[
|
|
174
|
+
"ping_timeout"
|
|
175
|
+
], # 20 seconds from config
|
|
176
|
+
max_http_buffer_size=CONNECTION_CONFIG[
|
|
177
|
+
"max_http_buffer_size"
|
|
178
|
+
], # 100MB from config
|
|
169
179
|
)
|
|
170
180
|
|
|
171
181
|
# Create aiohttp application
|
|
172
182
|
self.app = web.Application()
|
|
173
183
|
self.sio.attach(self.app)
|
|
174
184
|
|
|
185
|
+
# CRITICAL: Register event handlers BEFORE starting the server
|
|
186
|
+
# This ensures handlers are ready when clients connect
|
|
187
|
+
if self.main_server and hasattr(self.main_server, "_register_events_async"):
|
|
188
|
+
self.logger.info(
|
|
189
|
+
"Registering Socket.IO event handlers before server start"
|
|
190
|
+
)
|
|
191
|
+
await self.main_server._register_events_async()
|
|
192
|
+
else:
|
|
193
|
+
self.logger.warning("Main server not available for event registration")
|
|
194
|
+
|
|
175
195
|
# Setup HTTP API endpoints for receiving events from hook handlers
|
|
176
196
|
self._setup_http_api()
|
|
177
197
|
|
|
198
|
+
# Setup simple directory API
|
|
199
|
+
self._setup_directory_api()
|
|
200
|
+
|
|
178
201
|
# Find and serve static files
|
|
179
202
|
self._setup_static_files()
|
|
180
203
|
|
|
@@ -188,7 +211,7 @@ class SocketIOServerCore:
|
|
|
188
211
|
await self.site.start()
|
|
189
212
|
|
|
190
213
|
self.running = True
|
|
191
|
-
self.stats["start_time"] = datetime.now()
|
|
214
|
+
self.stats["start_time"] = datetime.now(timezone.utc)
|
|
192
215
|
|
|
193
216
|
self.logger.info(
|
|
194
217
|
f"Socket.IO server listening on http://{self.host}:{self.port}"
|
|
@@ -196,9 +219,16 @@ class SocketIOServerCore:
|
|
|
196
219
|
if self.static_path:
|
|
197
220
|
self.logger.info(f"Serving static files from: {self.static_path}")
|
|
198
221
|
|
|
199
|
-
#
|
|
200
|
-
|
|
201
|
-
|
|
222
|
+
# Conditionally start heartbeat task based on configuration
|
|
223
|
+
from ....config.socketio_config import CONNECTION_CONFIG
|
|
224
|
+
|
|
225
|
+
if CONNECTION_CONFIG.get("enable_extra_heartbeat", False):
|
|
226
|
+
self.heartbeat_task = asyncio.create_task(self._heartbeat_loop())
|
|
227
|
+
self.logger.info("Started system heartbeat task")
|
|
228
|
+
else:
|
|
229
|
+
self.logger.info(
|
|
230
|
+
"System heartbeat disabled (using Socket.IO ping/pong instead)"
|
|
231
|
+
)
|
|
202
232
|
|
|
203
233
|
# Keep the server running
|
|
204
234
|
while self.running:
|
|
@@ -246,24 +276,113 @@ class SocketIOServerCore:
|
|
|
246
276
|
# Parse JSON payload
|
|
247
277
|
event_data = await request.json()
|
|
248
278
|
|
|
249
|
-
# Log receipt
|
|
250
|
-
event_type =
|
|
251
|
-
|
|
279
|
+
# Log receipt with more detail
|
|
280
|
+
event_type = (
|
|
281
|
+
event_data.get("subtype")
|
|
282
|
+
or event_data.get("hook_event_name")
|
|
283
|
+
or "unknown"
|
|
284
|
+
)
|
|
285
|
+
self.logger.info(f"📨 Received HTTP event: {event_type}")
|
|
286
|
+
self.logger.debug(f"Event data keys: {list(event_data.keys())}")
|
|
287
|
+
self.logger.debug(f"Connected clients: {len(self.connected_clients)}")
|
|
288
|
+
|
|
289
|
+
# Transform hook event format to claude_event format if needed
|
|
290
|
+
if "hook_event_name" in event_data and "event" not in event_data:
|
|
291
|
+
# This is a raw hook event, transform it
|
|
292
|
+
from claude_mpm.services.socketio.event_normalizer import (
|
|
293
|
+
EventNormalizer,
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
normalizer = EventNormalizer()
|
|
297
|
+
|
|
298
|
+
# Create the format expected by normalizer
|
|
299
|
+
raw_event = {
|
|
300
|
+
"type": "hook",
|
|
301
|
+
"subtype": event_data.get("hook_event_name", "unknown")
|
|
302
|
+
.lower()
|
|
303
|
+
.replace("submit", "")
|
|
304
|
+
.replace("use", "_use"),
|
|
305
|
+
"timestamp": event_data.get("timestamp"),
|
|
306
|
+
"data": event_data.get("hook_input_data", {}),
|
|
307
|
+
"source": "claude_hooks",
|
|
308
|
+
"session_id": event_data.get("session_id"),
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
# Map hook event names to dashboard subtypes
|
|
312
|
+
subtype_map = {
|
|
313
|
+
"UserPromptSubmit": "user_prompt",
|
|
314
|
+
"PreToolUse": "pre_tool",
|
|
315
|
+
"PostToolUse": "post_tool",
|
|
316
|
+
"Stop": "stop",
|
|
317
|
+
"SubagentStop": "subagent_stop",
|
|
318
|
+
"AssistantResponse": "assistant_response",
|
|
319
|
+
}
|
|
320
|
+
raw_event["subtype"] = subtype_map.get(
|
|
321
|
+
event_data.get("hook_event_name"), "unknown"
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
normalized = normalizer.normalize(raw_event, source="hook")
|
|
325
|
+
event_data = normalized.to_dict()
|
|
326
|
+
self.logger.debug(
|
|
327
|
+
f"Normalized event: type={event_data.get('type')}, subtype={event_data.get('subtype')}"
|
|
328
|
+
)
|
|
252
329
|
|
|
253
330
|
# Broadcast to all connected dashboard clients via SocketIO
|
|
254
331
|
if self.sio:
|
|
255
|
-
#
|
|
256
|
-
|
|
332
|
+
# CRITICAL: Use the main server's broadcaster for proper event handling
|
|
333
|
+
# The broadcaster handles retries, connection management, and buffering
|
|
334
|
+
if (
|
|
335
|
+
self.main_server
|
|
336
|
+
and hasattr(self.main_server, "broadcaster")
|
|
337
|
+
and self.main_server.broadcaster
|
|
338
|
+
):
|
|
339
|
+
# The broadcaster expects raw event data and will normalize it
|
|
340
|
+
# Since we already normalized it, we need to pass it in a way that won't double-normalize
|
|
341
|
+
# We'll emit directly through the broadcaster's sio with proper handling
|
|
342
|
+
|
|
343
|
+
# Add to event buffer and history
|
|
344
|
+
with self.buffer_lock:
|
|
345
|
+
self.event_buffer.append(event_data)
|
|
346
|
+
self.stats["events_buffered"] = len(self.event_buffer)
|
|
347
|
+
|
|
348
|
+
# Add to main server's event history
|
|
349
|
+
if hasattr(self.main_server, "event_history"):
|
|
350
|
+
self.main_server.event_history.append(event_data)
|
|
351
|
+
|
|
352
|
+
# Use the broadcaster's sio to emit (it's the same as self.sio)
|
|
353
|
+
# This ensures the event goes through the proper channels
|
|
354
|
+
await self.sio.emit("claude_event", event_data)
|
|
355
|
+
|
|
356
|
+
# Update broadcaster stats
|
|
357
|
+
if hasattr(self.main_server.broadcaster, "stats"):
|
|
358
|
+
self.main_server.broadcaster.stats["events_sent"] = (
|
|
359
|
+
self.main_server.broadcaster.stats.get("events_sent", 0)
|
|
360
|
+
+ 1
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
self.logger.info(
|
|
364
|
+
f"✅ Event broadcasted: {event_data.get('subtype', 'unknown')} to {len(self.connected_clients)} clients"
|
|
365
|
+
)
|
|
366
|
+
self.logger.debug(
|
|
367
|
+
f"Connected client IDs: {list(self.connected_clients) if self.connected_clients else 'None'}"
|
|
368
|
+
)
|
|
369
|
+
else:
|
|
370
|
+
# Fallback: Direct emit if broadcaster not available (shouldn't happen)
|
|
371
|
+
self.logger.warning(
|
|
372
|
+
"Broadcaster not available, using direct emit"
|
|
373
|
+
)
|
|
374
|
+
await self.sio.emit("claude_event", event_data)
|
|
257
375
|
|
|
258
|
-
|
|
259
|
-
|
|
376
|
+
# Update stats manually if using fallback
|
|
377
|
+
self.stats["events_sent"] = self.stats.get("events_sent", 0) + 1
|
|
260
378
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
379
|
+
# Add to event buffer for late-joining clients
|
|
380
|
+
with self.buffer_lock:
|
|
381
|
+
self.event_buffer.append(event_data)
|
|
382
|
+
self.stats["events_buffered"] = len(self.event_buffer)
|
|
265
383
|
|
|
266
384
|
# Return 204 No Content for success
|
|
385
|
+
self.logger.debug(f"✅ HTTP event processed successfully: {event_type}")
|
|
267
386
|
return web.Response(status=204)
|
|
268
387
|
|
|
269
388
|
except Exception as e:
|
|
@@ -274,6 +393,118 @@ class SocketIOServerCore:
|
|
|
274
393
|
self.app.router.add_post("/api/events", api_events_handler)
|
|
275
394
|
self.logger.info("✅ HTTP API endpoint registered at /api/events")
|
|
276
395
|
|
|
396
|
+
# Add working directory endpoint
|
|
397
|
+
async def working_directory_handler(request):
|
|
398
|
+
"""Handle GET /api/working-directory to provide current working directory."""
|
|
399
|
+
from pathlib import Path
|
|
400
|
+
|
|
401
|
+
try:
|
|
402
|
+
working_dir = Path.cwd()
|
|
403
|
+
home_dir = str(Path.home())
|
|
404
|
+
|
|
405
|
+
return web.json_response(
|
|
406
|
+
{
|
|
407
|
+
"working_directory": working_dir,
|
|
408
|
+
"home_directory": home_dir,
|
|
409
|
+
"process_cwd": working_dir,
|
|
410
|
+
"session_id": getattr(self, "session_id", None),
|
|
411
|
+
}
|
|
412
|
+
)
|
|
413
|
+
except Exception as e:
|
|
414
|
+
self.logger.error(f"Error getting working directory: {e}")
|
|
415
|
+
return web.json_response(
|
|
416
|
+
{
|
|
417
|
+
"working_directory": "/Users/masa/Projects/claude-mpm",
|
|
418
|
+
"home_directory": "/Users/masa",
|
|
419
|
+
"error": str(e),
|
|
420
|
+
},
|
|
421
|
+
status=500,
|
|
422
|
+
)
|
|
423
|
+
|
|
424
|
+
self.app.router.add_get("/api/working-directory", working_directory_handler)
|
|
425
|
+
self.logger.info(
|
|
426
|
+
"✅ Working directory endpoint registered at /api/working-directory"
|
|
427
|
+
)
|
|
428
|
+
|
|
429
|
+
# Add file reading endpoint for source viewer
|
|
430
|
+
async def file_read_handler(request):
|
|
431
|
+
"""Handle GET /api/file/read for reading source files."""
|
|
432
|
+
|
|
433
|
+
file_path = request.query.get("path", "")
|
|
434
|
+
|
|
435
|
+
if not file_path:
|
|
436
|
+
return web.json_response({"error": "No path provided"}, status=400)
|
|
437
|
+
|
|
438
|
+
abs_path = Path(Path(file_path).resolve().expanduser())
|
|
439
|
+
|
|
440
|
+
# Security check - ensure file is within the project
|
|
441
|
+
try:
|
|
442
|
+
project_root = Path.cwd()
|
|
443
|
+
if not abs_path.startswith(project_root):
|
|
444
|
+
return web.json_response({"error": "Access denied"}, status=403)
|
|
445
|
+
except Exception:
|
|
446
|
+
pass
|
|
447
|
+
|
|
448
|
+
if not Path(abs_path).exists():
|
|
449
|
+
return web.json_response({"error": "File not found"}, status=404)
|
|
450
|
+
|
|
451
|
+
if not Path(abs_path).is_file():
|
|
452
|
+
return web.json_response({"error": "Not a file"}, status=400)
|
|
453
|
+
|
|
454
|
+
try:
|
|
455
|
+
# Read file with appropriate encoding
|
|
456
|
+
encodings = ["utf-8", "latin-1", "cp1252"]
|
|
457
|
+
content = None
|
|
458
|
+
|
|
459
|
+
for encoding in encodings:
|
|
460
|
+
try:
|
|
461
|
+
with Path(abs_path).open(
|
|
462
|
+
encoding=encoding,
|
|
463
|
+
) as f:
|
|
464
|
+
content = f.read()
|
|
465
|
+
break
|
|
466
|
+
except UnicodeDecodeError:
|
|
467
|
+
continue
|
|
468
|
+
|
|
469
|
+
if content is None:
|
|
470
|
+
return web.json_response(
|
|
471
|
+
{"error": "Could not decode file"}, status=400
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
return web.json_response(
|
|
475
|
+
{
|
|
476
|
+
"path": abs_path,
|
|
477
|
+
"name": Path(abs_path).name,
|
|
478
|
+
"content": content,
|
|
479
|
+
"lines": len(content.splitlines()),
|
|
480
|
+
"size": Path(abs_path).stat().st_size,
|
|
481
|
+
}
|
|
482
|
+
)
|
|
483
|
+
|
|
484
|
+
except PermissionError:
|
|
485
|
+
return web.json_response({"error": "Permission denied"}, status=403)
|
|
486
|
+
except Exception as e:
|
|
487
|
+
return web.json_response({"error": str(e)}, status=500)
|
|
488
|
+
|
|
489
|
+
self.app.router.add_get("/api/file/read", file_read_handler)
|
|
490
|
+
self.logger.info("✅ File reading API registered at /api/file/read")
|
|
491
|
+
|
|
492
|
+
def _setup_directory_api(self):
|
|
493
|
+
"""Setup simple directory listing API.
|
|
494
|
+
|
|
495
|
+
WHY: Provides a dead-simple way to list directory contents via HTTP GET
|
|
496
|
+
without complex WebSocket interactions.
|
|
497
|
+
"""
|
|
498
|
+
try:
|
|
499
|
+
from claude_mpm.dashboard.api.simple_directory import register_routes
|
|
500
|
+
|
|
501
|
+
register_routes(self.app)
|
|
502
|
+
self.logger.info(
|
|
503
|
+
"✅ Simple directory API registered at /api/directory/list"
|
|
504
|
+
)
|
|
505
|
+
except Exception as e:
|
|
506
|
+
self.logger.error(f"Failed to setup directory API: {e}")
|
|
507
|
+
|
|
277
508
|
def _setup_static_files(self):
|
|
278
509
|
"""Setup static file serving for the dashboard."""
|
|
279
510
|
try:
|
|
@@ -324,6 +555,26 @@ class SocketIOServerCore:
|
|
|
324
555
|
|
|
325
556
|
self.app.router.add_get("/dashboard", dashboard_handler)
|
|
326
557
|
|
|
558
|
+
# Serve simple code view template at /code-simple
|
|
559
|
+
async def code_simple_handler(request):
|
|
560
|
+
code_simple_template = (
|
|
561
|
+
self.dashboard_path.parent / "templates" / "code_simple.html"
|
|
562
|
+
)
|
|
563
|
+
if code_simple_template.exists():
|
|
564
|
+
self.logger.debug(
|
|
565
|
+
f"Serving code simple template from: {code_simple_template}"
|
|
566
|
+
)
|
|
567
|
+
return web.FileResponse(code_simple_template)
|
|
568
|
+
# Return error if template doesn't exist
|
|
569
|
+
self.logger.warning(
|
|
570
|
+
f"Code simple template not found at: {code_simple_template}"
|
|
571
|
+
)
|
|
572
|
+
return web.Response(
|
|
573
|
+
text="Simple code view not available", status=404
|
|
574
|
+
)
|
|
575
|
+
|
|
576
|
+
self.app.router.add_get("/code-simple", code_simple_handler)
|
|
577
|
+
|
|
327
578
|
# Serve version.json from dashboard directory
|
|
328
579
|
async def version_handler(request):
|
|
329
580
|
version_file = self.dashboard_path / "version.json"
|
|
@@ -498,7 +749,9 @@ class SocketIOServerCore:
|
|
|
498
749
|
uptime_seconds = 0
|
|
499
750
|
if self.stats.get("start_time"):
|
|
500
751
|
uptime_seconds = int(
|
|
501
|
-
(
|
|
752
|
+
(
|
|
753
|
+
datetime.now(timezone.utc) - self.stats["start_time"]
|
|
754
|
+
).total_seconds()
|
|
502
755
|
)
|
|
503
756
|
|
|
504
757
|
# Get active sessions from main server if available
|
|
@@ -515,7 +768,7 @@ class SocketIOServerCore:
|
|
|
515
768
|
heartbeat_data = {
|
|
516
769
|
"type": "system",
|
|
517
770
|
"subtype": "heartbeat",
|
|
518
|
-
"timestamp": datetime.now().isoformat(),
|
|
771
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
519
772
|
"source": "server",
|
|
520
773
|
"data": {
|
|
521
774
|
"uptime_seconds": uptime_seconds,
|