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
|
@@ -0,0 +1,682 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Code Analysis Event Handler for Socket.IO
|
|
3
|
+
==========================================
|
|
4
|
+
|
|
5
|
+
WHY: Handles code analysis requests from the dashboard, managing the analysis
|
|
6
|
+
runner subprocess and streaming results back to connected clients.
|
|
7
|
+
|
|
8
|
+
DESIGN DECISIONS:
|
|
9
|
+
- Single analysis runner instance per server
|
|
10
|
+
- Queue multiple requests for sequential processing
|
|
11
|
+
- Support cancellation of running analysis
|
|
12
|
+
- Stream events in real-time to all connected clients
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import asyncio
|
|
16
|
+
import uuid
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import Any, Dict
|
|
19
|
+
|
|
20
|
+
from ....core.logging_config import get_logger
|
|
21
|
+
from ....dashboard.analysis_runner import CodeAnalysisRunner
|
|
22
|
+
from ....tools.code_tree_analyzer import CodeTreeAnalyzer
|
|
23
|
+
from ....tools.code_tree_events import CodeTreeEventEmitter
|
|
24
|
+
from .base import BaseEventHandler
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class CodeAnalysisEventHandler(BaseEventHandler):
|
|
28
|
+
"""Handles code analysis events from dashboard clients.
|
|
29
|
+
|
|
30
|
+
WHY: Provides a clean interface between the dashboard UI and the
|
|
31
|
+
code analysis subprocess, managing requests and responses.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def __init__(self, server):
|
|
35
|
+
"""Initialize the code analysis event handler.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
server: The SocketIOServer instance
|
|
39
|
+
"""
|
|
40
|
+
super().__init__(server)
|
|
41
|
+
self.logger = get_logger(__name__)
|
|
42
|
+
self.analysis_runner = None
|
|
43
|
+
self.code_analyzer = None # For lazy loading operations
|
|
44
|
+
self._emit_tasks: set = set() # Track emit tasks to prevent GC
|
|
45
|
+
|
|
46
|
+
def _create_emit_task(self, coro):
|
|
47
|
+
"""Create a tracked emit task to prevent garbage collection."""
|
|
48
|
+
task = asyncio.get_event_loop().create_task(coro)
|
|
49
|
+
self._emit_tasks.add(task)
|
|
50
|
+
task.add_done_callback(self._emit_tasks.discard)
|
|
51
|
+
return task
|
|
52
|
+
|
|
53
|
+
def initialize(self):
|
|
54
|
+
"""Initialize the analysis runner."""
|
|
55
|
+
if not self.analysis_runner:
|
|
56
|
+
self.analysis_runner = CodeAnalysisRunner(self.server)
|
|
57
|
+
self.analysis_runner.start()
|
|
58
|
+
self.logger.info("Code analysis runner initialized")
|
|
59
|
+
|
|
60
|
+
def cleanup(self):
|
|
61
|
+
"""Cleanup the analysis runner on shutdown."""
|
|
62
|
+
if self.analysis_runner:
|
|
63
|
+
self.analysis_runner.stop()
|
|
64
|
+
self.analysis_runner = None
|
|
65
|
+
self.logger.info("Code analysis runner stopped")
|
|
66
|
+
|
|
67
|
+
def get_events(self) -> Dict[str, Any]:
|
|
68
|
+
"""Get the events this handler manages.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
Dictionary mapping event names to handler methods
|
|
72
|
+
"""
|
|
73
|
+
return {
|
|
74
|
+
# Legacy full analysis
|
|
75
|
+
"code:analyze:request": self.handle_analyze_request,
|
|
76
|
+
"code:analyze:cancel": self.handle_cancel_request,
|
|
77
|
+
"code:analyze:status": self.handle_status_request,
|
|
78
|
+
# Lazy loading operations
|
|
79
|
+
"code:discover:top_level": self.handle_discover_top_level,
|
|
80
|
+
"code:discover:directory": self.handle_discover_directory,
|
|
81
|
+
"code:analyze:file": self.handle_analyze_file,
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
def register_events(self) -> None:
|
|
85
|
+
"""Register Socket.IO event handlers.
|
|
86
|
+
|
|
87
|
+
WHY: Required by BaseEventHandler to register events with the Socket.IO server.
|
|
88
|
+
"""
|
|
89
|
+
events = self.get_events()
|
|
90
|
+
for event_name, handler_method in events.items():
|
|
91
|
+
self.server.core.sio.on(event_name, handler_method)
|
|
92
|
+
self.logger.info(f"Registered event handler: {event_name}")
|
|
93
|
+
|
|
94
|
+
async def handle_analyze_request(self, sid: str, data: Dict[str, Any]):
|
|
95
|
+
"""Handle code analysis request from client.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
sid: Socket ID of the requesting client
|
|
99
|
+
data: Request data containing path and options
|
|
100
|
+
"""
|
|
101
|
+
self.logger.info(f"Code analysis requested from {sid}: {data}")
|
|
102
|
+
|
|
103
|
+
# Initialize runner if needed
|
|
104
|
+
if not self.analysis_runner:
|
|
105
|
+
self.initialize()
|
|
106
|
+
|
|
107
|
+
# Validate request
|
|
108
|
+
path = data.get("path")
|
|
109
|
+
if not path:
|
|
110
|
+
await self.server.sio.emit(
|
|
111
|
+
"code:analysis:error",
|
|
112
|
+
{
|
|
113
|
+
"message": "Path is required for analysis",
|
|
114
|
+
"request_id": data.get("request_id"),
|
|
115
|
+
},
|
|
116
|
+
room=sid,
|
|
117
|
+
)
|
|
118
|
+
return
|
|
119
|
+
|
|
120
|
+
# Generate request ID if not provided
|
|
121
|
+
request_id = data.get("request_id") or str(uuid.uuid4())
|
|
122
|
+
|
|
123
|
+
# Extract options
|
|
124
|
+
languages = data.get("languages")
|
|
125
|
+
max_depth = data.get("max_depth")
|
|
126
|
+
ignore_patterns = data.get("ignore_patterns")
|
|
127
|
+
|
|
128
|
+
# Queue analysis request
|
|
129
|
+
success = self.analysis_runner.request_analysis(
|
|
130
|
+
request_id=request_id,
|
|
131
|
+
path=path,
|
|
132
|
+
languages=languages,
|
|
133
|
+
max_depth=max_depth,
|
|
134
|
+
ignore_patterns=ignore_patterns,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
if success:
|
|
138
|
+
# Send acknowledgment to requesting client
|
|
139
|
+
await self.server.sio.emit(
|
|
140
|
+
"code:analysis:accepted",
|
|
141
|
+
{
|
|
142
|
+
"request_id": request_id,
|
|
143
|
+
"path": path,
|
|
144
|
+
"message": "Analysis request queued",
|
|
145
|
+
},
|
|
146
|
+
room=sid,
|
|
147
|
+
)
|
|
148
|
+
else:
|
|
149
|
+
# Send error if request failed
|
|
150
|
+
await self.server.sio.emit(
|
|
151
|
+
"code:analysis:error",
|
|
152
|
+
{
|
|
153
|
+
"request_id": request_id,
|
|
154
|
+
"message": "Failed to queue analysis request",
|
|
155
|
+
},
|
|
156
|
+
room=sid,
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
async def handle_cancel_request(self, sid: str, data: Dict[str, Any]):
|
|
160
|
+
"""Handle analysis cancellation request.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
sid: Socket ID of the requesting client
|
|
164
|
+
data: Request data (may contain request_id)
|
|
165
|
+
"""
|
|
166
|
+
self.logger.info(f"Analysis cancellation requested from {sid}")
|
|
167
|
+
|
|
168
|
+
# Cancel current analysis
|
|
169
|
+
self.analysis_runner.cancel_current()
|
|
170
|
+
|
|
171
|
+
# Send confirmation
|
|
172
|
+
await self.server.sio.emit(
|
|
173
|
+
"code:analysis:cancelled",
|
|
174
|
+
{"message": "Analysis cancelled", "request_id": data.get("request_id")},
|
|
175
|
+
room=sid,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
async def handle_status_request(self, sid: str, data: Dict[str, Any]):
|
|
179
|
+
"""Handle status request from client.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
sid: Socket ID of the requesting client
|
|
183
|
+
data: Request data (unused)
|
|
184
|
+
"""
|
|
185
|
+
status = self.analysis_runner.get_status()
|
|
186
|
+
|
|
187
|
+
# Send status to requesting client
|
|
188
|
+
await self.server.sio.emit("code:analysis:status", status, room=sid)
|
|
189
|
+
|
|
190
|
+
async def handle_discover_top_level(self, sid: str, data: Dict[str, Any]):
|
|
191
|
+
"""Handle top-level directory discovery request for lazy loading.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
sid: Socket ID of the requesting client
|
|
195
|
+
data: Request data containing path and options
|
|
196
|
+
"""
|
|
197
|
+
self.logger.info(f"Top-level discovery requested from {sid}: {data}")
|
|
198
|
+
|
|
199
|
+
# Get path - this MUST be an absolute path from the frontend
|
|
200
|
+
path = data.get("path")
|
|
201
|
+
if not path:
|
|
202
|
+
await self.server.core.sio.emit(
|
|
203
|
+
"code:analysis:error",
|
|
204
|
+
{
|
|
205
|
+
"error": "Path is required for top-level discovery",
|
|
206
|
+
"request_id": data.get("request_id"),
|
|
207
|
+
},
|
|
208
|
+
room=sid,
|
|
209
|
+
)
|
|
210
|
+
return
|
|
211
|
+
|
|
212
|
+
# CRITICAL: Never use "." or allow relative paths
|
|
213
|
+
# The frontend must send the absolute working directory
|
|
214
|
+
if path in (".", "..", "/") or not Path(path).is_absolute():
|
|
215
|
+
self.logger.warning(f"Invalid path for discovery: {path}")
|
|
216
|
+
await self.server.core.sio.emit(
|
|
217
|
+
"code:analysis:error",
|
|
218
|
+
{
|
|
219
|
+
"error": f"Invalid path for discovery: {path}. Must be an absolute path.",
|
|
220
|
+
"request_id": data.get("request_id"),
|
|
221
|
+
"path": path,
|
|
222
|
+
},
|
|
223
|
+
room=sid,
|
|
224
|
+
)
|
|
225
|
+
return
|
|
226
|
+
|
|
227
|
+
# SECURITY: Validate the requested path
|
|
228
|
+
# Allow access to the explicitly chosen working directory and its subdirectories
|
|
229
|
+
Path(path).absolute()
|
|
230
|
+
|
|
231
|
+
# For now, we trust the frontend to send valid paths
|
|
232
|
+
# In production, you might want to maintain a server-side list of allowed directories
|
|
233
|
+
# or implement a more sophisticated permission system
|
|
234
|
+
|
|
235
|
+
# Basic sanity checks are done below after creating the Path object
|
|
236
|
+
|
|
237
|
+
ignore_patterns = data.get("ignore_patterns", [])
|
|
238
|
+
request_id = data.get("request_id")
|
|
239
|
+
|
|
240
|
+
try:
|
|
241
|
+
# Create analyzer if needed
|
|
242
|
+
if not self.code_analyzer:
|
|
243
|
+
# Create a custom emitter that sends to Socket.IO
|
|
244
|
+
emitter = CodeTreeEventEmitter(use_stdout=False)
|
|
245
|
+
# Override emit method to send to Socket.IO
|
|
246
|
+
original_emit = emitter.emit
|
|
247
|
+
|
|
248
|
+
def socket_emit(
|
|
249
|
+
event_type: str, event_data: Dict[str, Any], batch: bool = False
|
|
250
|
+
):
|
|
251
|
+
# Keep the original event format with colons - frontend expects this!
|
|
252
|
+
# The frontend listens for 'code:directory:discovered' not 'code.directory.discovered'
|
|
253
|
+
|
|
254
|
+
# Special handling for 'info' events - they should be passed through directly
|
|
255
|
+
if event_type == "info":
|
|
256
|
+
# INFO events for granular tracking
|
|
257
|
+
self._create_emit_task(
|
|
258
|
+
self.server.core.sio.emit(
|
|
259
|
+
"info", {"request_id": request_id, **event_data}
|
|
260
|
+
)
|
|
261
|
+
)
|
|
262
|
+
else:
|
|
263
|
+
# Regular code analysis events
|
|
264
|
+
self._create_emit_task(
|
|
265
|
+
self.server.core.sio.emit(
|
|
266
|
+
event_type, {"request_id": request_id, **event_data}
|
|
267
|
+
)
|
|
268
|
+
)
|
|
269
|
+
# Call original for stats tracking
|
|
270
|
+
original_emit(event_type, event_data, batch)
|
|
271
|
+
|
|
272
|
+
emitter.emit = socket_emit
|
|
273
|
+
# Initialize CodeTreeAnalyzer with emitter keyword argument
|
|
274
|
+
self.logger.info("Creating CodeTreeAnalyzer")
|
|
275
|
+
# Pass emit_events=False to prevent duplicate events from the analyzer
|
|
276
|
+
# The emitter will still work but the analyzer won't create its own stdout emitter
|
|
277
|
+
self.code_analyzer = CodeTreeAnalyzer(
|
|
278
|
+
emit_events=False, emitter=emitter
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
# Use the provided path as-is - the frontend sends the absolute path
|
|
282
|
+
# Make sure we're using an absolute path
|
|
283
|
+
directory = Path(path)
|
|
284
|
+
|
|
285
|
+
# Validate that the path exists and is a directory
|
|
286
|
+
if not directory.exists():
|
|
287
|
+
await self.server.core.sio.emit(
|
|
288
|
+
"code:analysis:error",
|
|
289
|
+
{
|
|
290
|
+
"request_id": request_id,
|
|
291
|
+
"path": path,
|
|
292
|
+
"error": f"Directory does not exist: {path}",
|
|
293
|
+
},
|
|
294
|
+
room=sid,
|
|
295
|
+
)
|
|
296
|
+
return
|
|
297
|
+
|
|
298
|
+
if not directory.is_dir():
|
|
299
|
+
await self.server.core.sio.emit(
|
|
300
|
+
"code:analysis:error",
|
|
301
|
+
{
|
|
302
|
+
"request_id": request_id,
|
|
303
|
+
"path": path,
|
|
304
|
+
"error": f"Path is not a directory: {path}",
|
|
305
|
+
},
|
|
306
|
+
room=sid,
|
|
307
|
+
)
|
|
308
|
+
return
|
|
309
|
+
|
|
310
|
+
# Log what we're actually discovering
|
|
311
|
+
self.logger.info(
|
|
312
|
+
f"Discovering top-level contents of: {directory.absolute()}"
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
result = self.code_analyzer.discover_top_level(directory, ignore_patterns)
|
|
316
|
+
|
|
317
|
+
# Send result to client with correct event name for top level discovery
|
|
318
|
+
await self.server.core.sio.emit(
|
|
319
|
+
"code:top_level:discovered",
|
|
320
|
+
{
|
|
321
|
+
"request_id": request_id,
|
|
322
|
+
"path": str(directory),
|
|
323
|
+
"items": result.get("children", []),
|
|
324
|
+
"stats": {
|
|
325
|
+
"files": len(
|
|
326
|
+
[
|
|
327
|
+
c
|
|
328
|
+
for c in result.get("children", [])
|
|
329
|
+
if c.get("type") == "file"
|
|
330
|
+
]
|
|
331
|
+
),
|
|
332
|
+
"directories": len(
|
|
333
|
+
[
|
|
334
|
+
c
|
|
335
|
+
for c in result.get("children", [])
|
|
336
|
+
if c.get("type") == "directory"
|
|
337
|
+
]
|
|
338
|
+
),
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
room=sid,
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
except Exception as e:
|
|
345
|
+
self.logger.error(f"Error discovering top level: {e}")
|
|
346
|
+
await self.server.core.sio.emit(
|
|
347
|
+
"code:analysis:error",
|
|
348
|
+
{
|
|
349
|
+
"request_id": request_id,
|
|
350
|
+
"path": path,
|
|
351
|
+
"error": str(e),
|
|
352
|
+
},
|
|
353
|
+
room=sid,
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
async def handle_discover_directory(self, sid: str, data: Dict[str, Any]):
|
|
357
|
+
"""Handle directory discovery request for lazy loading.
|
|
358
|
+
|
|
359
|
+
Args:
|
|
360
|
+
sid: Socket ID of the requesting client
|
|
361
|
+
data: Request data containing directory path
|
|
362
|
+
"""
|
|
363
|
+
self.logger.info(f"Directory discovery requested from {sid}: {data}")
|
|
364
|
+
|
|
365
|
+
path = data.get("path")
|
|
366
|
+
ignore_patterns = data.get("ignore_patterns", [])
|
|
367
|
+
request_id = data.get("request_id")
|
|
368
|
+
|
|
369
|
+
if not path:
|
|
370
|
+
await self.server.core.sio.emit(
|
|
371
|
+
"code:analysis:error",
|
|
372
|
+
{
|
|
373
|
+
"request_id": request_id,
|
|
374
|
+
"error": "Path is required",
|
|
375
|
+
},
|
|
376
|
+
room=sid,
|
|
377
|
+
)
|
|
378
|
+
return
|
|
379
|
+
|
|
380
|
+
# CRITICAL SECURITY FIX: Add path validation to prevent filesystem traversal
|
|
381
|
+
# The same validation logic as handle_discover_top_level
|
|
382
|
+
if path in (".", "..", "/") or not Path(path).is_absolute():
|
|
383
|
+
self.logger.warning(f"Invalid path for directory discovery: {path}")
|
|
384
|
+
await self.server.core.sio.emit(
|
|
385
|
+
"code:analysis:error",
|
|
386
|
+
{
|
|
387
|
+
"error": f"Invalid path for discovery: {path}. Must be an absolute path.",
|
|
388
|
+
"request_id": request_id,
|
|
389
|
+
"path": path,
|
|
390
|
+
},
|
|
391
|
+
room=sid,
|
|
392
|
+
)
|
|
393
|
+
return
|
|
394
|
+
|
|
395
|
+
# SECURITY: Validate the requested path
|
|
396
|
+
# Allow access to the explicitly chosen working directory and its subdirectories
|
|
397
|
+
requested_path = Path(path).absolute()
|
|
398
|
+
|
|
399
|
+
# For now, we trust the frontend to send valid paths
|
|
400
|
+
# In production, you might want to maintain a server-side list of allowed directories
|
|
401
|
+
# or implement a more sophisticated permission system
|
|
402
|
+
|
|
403
|
+
# Basic sanity checks
|
|
404
|
+
if not requested_path.exists():
|
|
405
|
+
self.logger.warning(f"Path does not exist: {path}")
|
|
406
|
+
await self.server.core.sio.emit(
|
|
407
|
+
"code:analysis:error",
|
|
408
|
+
{
|
|
409
|
+
"error": f"Path does not exist: {path}",
|
|
410
|
+
"request_id": request_id,
|
|
411
|
+
"path": path,
|
|
412
|
+
},
|
|
413
|
+
room=sid,
|
|
414
|
+
)
|
|
415
|
+
return
|
|
416
|
+
|
|
417
|
+
if not requested_path.is_dir():
|
|
418
|
+
self.logger.warning(f"Path is not a directory: {path}")
|
|
419
|
+
await self.server.core.sio.emit(
|
|
420
|
+
"code:analysis:error",
|
|
421
|
+
{
|
|
422
|
+
"error": f"Path is not a directory: {path}",
|
|
423
|
+
"request_id": request_id,
|
|
424
|
+
"path": path,
|
|
425
|
+
},
|
|
426
|
+
room=sid,
|
|
427
|
+
)
|
|
428
|
+
return
|
|
429
|
+
|
|
430
|
+
try:
|
|
431
|
+
# Ensure analyzer exists
|
|
432
|
+
if not self.code_analyzer:
|
|
433
|
+
emitter = CodeTreeEventEmitter(use_stdout=False)
|
|
434
|
+
# Override emit method to send to Socket.IO
|
|
435
|
+
original_emit = emitter.emit
|
|
436
|
+
|
|
437
|
+
def socket_emit(
|
|
438
|
+
event_type: str, event_data: Dict[str, Any], batch: bool = False
|
|
439
|
+
):
|
|
440
|
+
# Keep the original event format with colons - frontend expects this!
|
|
441
|
+
# The frontend listens for 'code:directory:discovered' not 'code.directory.discovered'
|
|
442
|
+
|
|
443
|
+
# Special handling for 'info' events - they should be passed through directly
|
|
444
|
+
if event_type == "info":
|
|
445
|
+
# INFO events for granular tracking
|
|
446
|
+
self._create_emit_task(
|
|
447
|
+
self.server.core.sio.emit(
|
|
448
|
+
"info", {"request_id": request_id, **event_data}
|
|
449
|
+
)
|
|
450
|
+
)
|
|
451
|
+
else:
|
|
452
|
+
# Regular code analysis events
|
|
453
|
+
self._create_emit_task(
|
|
454
|
+
self.server.core.sio.emit(
|
|
455
|
+
event_type, {"request_id": request_id, **event_data}
|
|
456
|
+
)
|
|
457
|
+
)
|
|
458
|
+
original_emit(event_type, event_data, batch)
|
|
459
|
+
|
|
460
|
+
emitter.emit = socket_emit
|
|
461
|
+
# Initialize CodeTreeAnalyzer with emitter keyword argument
|
|
462
|
+
self.logger.info("Creating CodeTreeAnalyzer")
|
|
463
|
+
# Pass emit_events=False to prevent duplicate events from the analyzer
|
|
464
|
+
# The emitter will still work but the analyzer won't create its own stdout emitter
|
|
465
|
+
self.code_analyzer = CodeTreeAnalyzer(
|
|
466
|
+
emit_events=False, emitter=emitter
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
# Discover directory
|
|
470
|
+
result = self.code_analyzer.discover_directory(path, ignore_patterns)
|
|
471
|
+
|
|
472
|
+
# Log what we're sending
|
|
473
|
+
self.logger.info(
|
|
474
|
+
f"Discovery result for {path}: {len(result.get('children', []))} children found"
|
|
475
|
+
)
|
|
476
|
+
self.logger.debug(f"Full result: {result}")
|
|
477
|
+
|
|
478
|
+
# DEBUG: Log exact children being sent
|
|
479
|
+
children = result.get("children", [])
|
|
480
|
+
if children:
|
|
481
|
+
self.logger.info(
|
|
482
|
+
f"Children being sent: {[child.get('name') for child in children]}"
|
|
483
|
+
)
|
|
484
|
+
self.logger.info(f"Full children data: {children}")
|
|
485
|
+
else:
|
|
486
|
+
self.logger.warning(f"No children found for {path}")
|
|
487
|
+
|
|
488
|
+
# Prepare the response data
|
|
489
|
+
response_data = {
|
|
490
|
+
"request_id": request_id,
|
|
491
|
+
"path": path, # Absolute path as requested
|
|
492
|
+
"name": Path(path).name, # Just the directory name for display
|
|
493
|
+
"type": result.get("type", "directory"),
|
|
494
|
+
"children": children, # Send children array directly
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
# CRITICAL DEBUG: Log exact JSON that will be sent
|
|
498
|
+
import json
|
|
499
|
+
|
|
500
|
+
self.logger.info(
|
|
501
|
+
f"Sending response data (JSON): {json.dumps(response_data, indent=2)}"
|
|
502
|
+
)
|
|
503
|
+
self.logger.info(
|
|
504
|
+
f"Children count in response: {len(response_data.get('children', []))}"
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
# Send result with correct event name (using colons, not dots!)
|
|
508
|
+
# Include both absolute path and relative name for frontend compatibility
|
|
509
|
+
# IMPORTANT: Don't use **result as it overwrites path and name
|
|
510
|
+
await self.server.core.sio.emit(
|
|
511
|
+
"code:directory:discovered",
|
|
512
|
+
response_data,
|
|
513
|
+
room=sid,
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
except Exception as e:
|
|
517
|
+
self.logger.error(f"Error discovering directory {path}: {e}")
|
|
518
|
+
await self.server.core.sio.emit(
|
|
519
|
+
"code:analysis:error",
|
|
520
|
+
{
|
|
521
|
+
"request_id": request_id,
|
|
522
|
+
"path": path,
|
|
523
|
+
"error": str(e),
|
|
524
|
+
},
|
|
525
|
+
room=sid,
|
|
526
|
+
)
|
|
527
|
+
|
|
528
|
+
async def handle_analyze_file(self, sid: str, data: Dict[str, Any]):
|
|
529
|
+
"""Handle file analysis request for lazy loading.
|
|
530
|
+
|
|
531
|
+
Args:
|
|
532
|
+
sid: Socket ID of the requesting client
|
|
533
|
+
data: Request data containing file path
|
|
534
|
+
"""
|
|
535
|
+
self.logger.info(f"File analysis requested from {sid}: {data}")
|
|
536
|
+
|
|
537
|
+
path = data.get("path")
|
|
538
|
+
request_id = data.get("request_id")
|
|
539
|
+
data.get("show_hidden_files", False)
|
|
540
|
+
|
|
541
|
+
if not path:
|
|
542
|
+
await self.server.core.sio.emit(
|
|
543
|
+
"code:analysis:error",
|
|
544
|
+
{
|
|
545
|
+
"request_id": request_id,
|
|
546
|
+
"error": "Path is required",
|
|
547
|
+
},
|
|
548
|
+
room=sid,
|
|
549
|
+
)
|
|
550
|
+
return
|
|
551
|
+
|
|
552
|
+
# CRITICAL SECURITY FIX: Add path validation to prevent filesystem traversal
|
|
553
|
+
if path in (".", "..", "/") or not Path(path).is_absolute():
|
|
554
|
+
self.logger.warning(f"Invalid path for file analysis: {path}")
|
|
555
|
+
await self.server.core.sio.emit(
|
|
556
|
+
"code:analysis:error",
|
|
557
|
+
{
|
|
558
|
+
"error": f"Invalid path for analysis: {path}. Must be an absolute path.",
|
|
559
|
+
"request_id": request_id,
|
|
560
|
+
"path": path,
|
|
561
|
+
},
|
|
562
|
+
room=sid,
|
|
563
|
+
)
|
|
564
|
+
return
|
|
565
|
+
|
|
566
|
+
# SECURITY: Validate the requested file path
|
|
567
|
+
# Allow access to files within the explicitly chosen working directory
|
|
568
|
+
requested_path = Path(path).absolute()
|
|
569
|
+
|
|
570
|
+
# Basic sanity checks
|
|
571
|
+
if not requested_path.exists():
|
|
572
|
+
self.logger.warning(f"File does not exist: {path}")
|
|
573
|
+
await self.server.core.sio.emit(
|
|
574
|
+
"code:analysis:error",
|
|
575
|
+
{
|
|
576
|
+
"error": f"File does not exist: {path}",
|
|
577
|
+
"request_id": request_id,
|
|
578
|
+
"path": path,
|
|
579
|
+
},
|
|
580
|
+
room=sid,
|
|
581
|
+
)
|
|
582
|
+
return
|
|
583
|
+
|
|
584
|
+
if not requested_path.is_file():
|
|
585
|
+
self.logger.warning(f"Path is not a file: {path}")
|
|
586
|
+
await self.server.core.sio.emit(
|
|
587
|
+
"code:analysis:error",
|
|
588
|
+
{
|
|
589
|
+
"error": f"Path is not a file: {path}",
|
|
590
|
+
"request_id": request_id,
|
|
591
|
+
"path": path,
|
|
592
|
+
},
|
|
593
|
+
room=sid,
|
|
594
|
+
)
|
|
595
|
+
return
|
|
596
|
+
|
|
597
|
+
try:
|
|
598
|
+
self.logger.info(f"Starting file analysis for: {path}")
|
|
599
|
+
|
|
600
|
+
# Ensure analyzer exists
|
|
601
|
+
if not self.code_analyzer:
|
|
602
|
+
self.logger.info("Creating new CodeTreeAnalyzer instance")
|
|
603
|
+
emitter = CodeTreeEventEmitter(use_stdout=False)
|
|
604
|
+
# Override emit method to send to Socket.IO
|
|
605
|
+
original_emit = emitter.emit
|
|
606
|
+
|
|
607
|
+
def socket_emit(
|
|
608
|
+
event_type: str, event_data: Dict[str, Any], batch: bool = False
|
|
609
|
+
):
|
|
610
|
+
# Keep the original event format with colons - frontend expects this!
|
|
611
|
+
# The frontend listens for 'code:file:analyzed' not 'code.file.analyzed'
|
|
612
|
+
|
|
613
|
+
# Special handling for 'info' events - they should be passed through directly
|
|
614
|
+
if event_type == "info":
|
|
615
|
+
# INFO events for granular tracking
|
|
616
|
+
self._create_emit_task(
|
|
617
|
+
self.server.core.sio.emit(
|
|
618
|
+
"info", {"request_id": request_id, **event_data}
|
|
619
|
+
)
|
|
620
|
+
)
|
|
621
|
+
else:
|
|
622
|
+
# Regular code analysis events
|
|
623
|
+
self._create_emit_task(
|
|
624
|
+
self.server.core.sio.emit(
|
|
625
|
+
event_type, {"request_id": request_id, **event_data}
|
|
626
|
+
)
|
|
627
|
+
)
|
|
628
|
+
original_emit(event_type, event_data, batch)
|
|
629
|
+
|
|
630
|
+
emitter.emit = socket_emit
|
|
631
|
+
# Initialize CodeTreeAnalyzer with emitter keyword argument
|
|
632
|
+
self.logger.info("Creating CodeTreeAnalyzer")
|
|
633
|
+
# Pass emit_events=False to prevent duplicate events from the analyzer
|
|
634
|
+
# The emitter will still work but the analyzer won't create its own stdout emitter
|
|
635
|
+
self.code_analyzer = CodeTreeAnalyzer(
|
|
636
|
+
emit_events=False, emitter=emitter
|
|
637
|
+
)
|
|
638
|
+
self.logger.info("CodeTreeAnalyzer created successfully")
|
|
639
|
+
|
|
640
|
+
# Analyze file
|
|
641
|
+
self.logger.info(f"Calling analyze_file for: {path}")
|
|
642
|
+
result = self.code_analyzer.analyze_file(path)
|
|
643
|
+
self.logger.info(
|
|
644
|
+
f"Analysis complete. Result keys: {list(result.keys()) if result else 'None'}"
|
|
645
|
+
)
|
|
646
|
+
|
|
647
|
+
if result:
|
|
648
|
+
self.logger.info(
|
|
649
|
+
f"Analysis result: elements={len(result.get('elements', []))}, nodes={len(result.get('nodes', []))}"
|
|
650
|
+
)
|
|
651
|
+
else:
|
|
652
|
+
self.logger.warning("Analysis returned None or empty result")
|
|
653
|
+
|
|
654
|
+
# Send result with correct event name (using colons, not dots!)
|
|
655
|
+
response_data = {
|
|
656
|
+
"request_id": request_id,
|
|
657
|
+
"path": path,
|
|
658
|
+
**result,
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
self.logger.info(f"Emitting code:file:analyzed event to {sid}")
|
|
662
|
+
await self.server.core.sio.emit(
|
|
663
|
+
"code:file:analyzed",
|
|
664
|
+
response_data,
|
|
665
|
+
room=sid,
|
|
666
|
+
)
|
|
667
|
+
self.logger.info("Event emitted successfully")
|
|
668
|
+
|
|
669
|
+
except Exception as e:
|
|
670
|
+
self.logger.error(f"Error analyzing file {path}: {e}")
|
|
671
|
+
import traceback
|
|
672
|
+
|
|
673
|
+
self.logger.error(f"Full traceback: {traceback.format_exc()}")
|
|
674
|
+
await self.server.core.sio.emit(
|
|
675
|
+
"code:analysis:error",
|
|
676
|
+
{
|
|
677
|
+
"request_id": request_id,
|
|
678
|
+
"path": path,
|
|
679
|
+
"error": str(e),
|
|
680
|
+
},
|
|
681
|
+
room=sid,
|
|
682
|
+
)
|