claude-mpm 4.21.3__py3-none-any.whl → 5.1.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_PM.md +12 -0
- claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +3 -48
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +1239 -674
- claude_mpm/agents/WORKFLOW.md +75 -2
- claude_mpm/agents/__init__.py +6 -0
- claude_mpm/agents/agent_loader.py +1 -4
- claude_mpm/agents/base_agent.json +6 -3
- claude_mpm/agents/base_agent_loader.py +10 -35
- claude_mpm/agents/frontmatter_validator.py +69 -1
- claude_mpm/agents/templates/circuit-breakers.md +1254 -0
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -0
- claude_mpm/agents/templates/structured-questions-examples.md +615 -0
- claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
- claude_mpm/agents/templates/ticketing-examples.md +277 -0
- claude_mpm/cli/__init__.py +37 -2
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +188 -30
- claude_mpm/cli/commands/agents.py +1128 -36
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/analyze.py +3 -3
- claude_mpm/cli/commands/auto_configure.py +537 -239
- claude_mpm/cli/commands/cleanup.py +1 -1
- claude_mpm/cli/commands/config.py +7 -4
- claude_mpm/cli/commands/configure.py +935 -45
- claude_mpm/cli/commands/configure_agent_display.py +4 -4
- claude_mpm/cli/commands/configure_navigation.py +63 -46
- claude_mpm/cli/commands/debug.py +12 -12
- claude_mpm/cli/commands/doctor.py +10 -2
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/local_deploy.py +1 -4
- claude_mpm/cli/commands/mcp_install_commands.py +1 -1
- claude_mpm/cli/commands/mpm_init/core.py +50 -2
- claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
- claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/run.py +125 -167
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +757 -20
- claude_mpm/cli/executor.py +78 -3
- claude_mpm/cli/interactive/agent_wizard.py +1032 -47
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +310 -4
- claude_mpm/cli/parsers/auto_configure_parser.py +13 -0
- claude_mpm/cli/parsers/base_parser.py +53 -0
- claude_mpm/cli/parsers/config_parser.py +96 -43
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +145 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/startup.py +564 -108
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/cli_module/commands.py +1 -1
- claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
- claude_mpm/commands/mpm-agents-detect.md +9 -0
- claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
- claude_mpm/commands/mpm-agents-recommend.md +9 -0
- claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
- claude_mpm/commands/mpm-doctor.md +9 -0
- claude_mpm/commands/mpm-help.md +14 -2
- claude_mpm/commands/mpm-init.md +27 -2
- claude_mpm/commands/mpm-monitor.md +9 -0
- claude_mpm/commands/mpm-postmortem.md +123 -0
- claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
- claude_mpm/commands/mpm-status.md +9 -0
- claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
- claude_mpm/commands/mpm-ticket-view.md +552 -0
- claude_mpm/commands/mpm-version.md +9 -0
- claude_mpm/commands/mpm.md +10 -0
- claude_mpm/config/agent_presets.py +488 -0
- claude_mpm/config/agent_sources.py +325 -0
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/constants.py +13 -0
- claude_mpm/core/api_validator.py +1 -1
- claude_mpm/core/claude_runner.py +19 -35
- claude_mpm/core/config.py +24 -0
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/framework/__init__.py +3 -16
- claude_mpm/core/framework/loaders/file_loader.py +54 -101
- claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
- claude_mpm/core/framework/processors/metadata_processor.py +1 -1
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +131 -10
- claude_mpm/core/logger.py +3 -1
- claude_mpm/core/oneshot_session.py +110 -8
- claude_mpm/core/output_style_manager.py +173 -43
- claude_mpm/core/protocols/__init__.py +23 -0
- claude_mpm/core/protocols/runner_protocol.py +103 -0
- claude_mpm/core/protocols/session_protocol.py +131 -0
- claude_mpm/core/shared/singleton_manager.py +11 -4
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/unified_agent_registry.py +129 -1
- claude_mpm/core/unified_config.py +22 -0
- claude_mpm/dashboard/static/css/activity.css +69 -69
- claude_mpm/dashboard/static/css/connection-status.css +10 -10
- claude_mpm/dashboard/static/css/dashboard.css +15 -15
- claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
- claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
- claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
- claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
- claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
- claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
- claude_mpm/dashboard/static/js/connection-manager.js +76 -76
- claude_mpm/dashboard/static/js/dashboard.js +76 -58
- claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/js/socket-client.js +138 -121
- claude_mpm/dashboard/templates/code_simple.html +23 -23
- claude_mpm/dashboard/templates/index.html +18 -18
- claude_mpm/experimental/cli_enhancements.py +1 -5
- claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
- claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
- claude_mpm/hooks/claude_hooks/installer.py +45 -0
- claude_mpm/hooks/claude_hooks/memory_integration.py +12 -1
- claude_mpm/hooks/failure_learning/__init__.py +2 -8
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
- claude_mpm/hooks/kuzu_response_hook.py +1 -5
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/models/agent_definition.py +7 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/scripts/claude-hook-handler.sh +3 -3
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/agent_builder.py +45 -9
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -0
- claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
- claude_mpm/services/agents/cache_git_manager.py +621 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
- claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
- claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
- claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
- claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
- claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +225 -18
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +557 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
- claude_mpm/services/agents/git_source_manager.py +629 -0
- claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
- claude_mpm/services/agents/local_template_manager.py +50 -10
- claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
- claude_mpm/services/agents/sources/__init__.py +13 -0
- claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
- claude_mpm/services/agents/startup_sync.py +239 -0
- claude_mpm/services/agents/toolchain_detector.py +474 -0
- claude_mpm/services/analysis/__init__.py +25 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/cli/session_pause_manager.py +1 -1
- claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
- claude_mpm/services/command_deployment_service.py +200 -6
- claude_mpm/services/core/base.py +7 -2
- claude_mpm/services/core/interfaces/__init__.py +1 -3
- claude_mpm/services/core/interfaces/health.py +1 -4
- claude_mpm/services/core/models/__init__.py +2 -11
- claude_mpm/services/diagnostics/checks/__init__.py +4 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
- claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
- claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
- claude_mpm/services/event_bus/direct_relay.py +3 -3
- claude_mpm/services/event_bus/event_bus.py +36 -3
- claude_mpm/services/events/consumers/logging.py +1 -2
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +494 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
- claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
- claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
- claude_mpm/services/instructions/__init__.py +9 -0
- claude_mpm/services/instructions/instruction_cache_service.py +374 -0
- claude_mpm/services/local_ops/__init__.py +3 -13
- claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
- claude_mpm/services/local_ops/health_manager.py +1 -4
- claude_mpm/services/local_ops/process_manager.py +1 -1
- claude_mpm/services/local_ops/resource_monitor.py +2 -2
- claude_mpm/services/mcp_config_manager.py +75 -145
- claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
- claude_mpm/services/mcp_gateway/core/process_pool.py +22 -16
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
- claude_mpm/services/mcp_service_verifier.py +6 -3
- claude_mpm/services/memory/optimizer.py +1 -1
- claude_mpm/services/model/model_router.py +8 -9
- claude_mpm/services/monitor/daemon.py +29 -9
- claude_mpm/services/monitor/daemon_manager.py +96 -19
- claude_mpm/services/monitor/server.py +2 -2
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/port_manager.py +1 -1
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/project/documentation_manager.py +2 -1
- claude_mpm/services/project/project_organizer.py +4 -0
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +17 -3
- claude_mpm/services/self_upgrade_service.py +165 -7
- claude_mpm/services/session_management_service.py +16 -4
- claude_mpm/services/skills/__init__.py +18 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +955 -0
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/git.py +2 -2
- claude_mpm/services/socketio/server/core.py +1 -4
- claude_mpm/services/socketio/server/main.py +1 -3
- claude_mpm/services/system_instructions_service.py +1 -3
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
- claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
- claude_mpm/services/unified/unified_deployment.py +1 -5
- claude_mpm/services/version_control/conflict_resolution.py +6 -4
- claude_mpm/services/visualization/__init__.py +1 -5
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/performance-profiling.md +6 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
- claude_mpm/skills/skills_registry.py +0 -1
- claude_mpm/templates/questions/__init__.py +38 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +311 -0
- claude_mpm/templates/questions/project_init.py +385 -0
- claude_mpm/templates/questions/ticket_mgmt.py +394 -0
- claude_mpm/tools/__main__.py +8 -8
- claude_mpm/tools/code_tree_analyzer/analysis.py +1 -1
- claude_mpm/utils/agent_dependency_loader.py +80 -13
- claude_mpm/utils/agent_filters.py +288 -0
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +244 -0
- claude_mpm/utils/log_cleanup.py +3 -3
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/progress.py +387 -0
- claude_mpm/utils/robust_installer.py +3 -5
- claude_mpm/utils/structured_questions.py +619 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/METADATA +496 -65
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/RECORD +284 -443
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
- claude_mpm/agents/templates/agent-manager.json +0 -273
- claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
- claude_mpm/agents/templates/api_qa.json +0 -180
- claude_mpm/agents/templates/circuit_breakers.md +0 -638
- claude_mpm/agents/templates/clerk-ops.json +0 -235
- claude_mpm/agents/templates/code_analyzer.json +0 -101
- claude_mpm/agents/templates/content-agent.json +0 -358
- claude_mpm/agents/templates/dart_engineer.json +0 -307
- claude_mpm/agents/templates/data_engineer.json +0 -225
- claude_mpm/agents/templates/documentation.json +0 -211
- claude_mpm/agents/templates/engineer.json +0 -210
- claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
- claude_mpm/agents/templates/golang_engineer.json +0 -270
- claude_mpm/agents/templates/imagemagick.json +0 -264
- claude_mpm/agents/templates/java_engineer.json +0 -346
- claude_mpm/agents/templates/local_ops_agent.json +0 -1840
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
- claude_mpm/agents/templates/memory_manager.json +0 -158
- claude_mpm/agents/templates/nextjs_engineer.json +0 -285
- claude_mpm/agents/templates/ops.json +0 -185
- claude_mpm/agents/templates/php-engineer.json +0 -287
- claude_mpm/agents/templates/product_owner.json +0 -338
- claude_mpm/agents/templates/project_organizer.json +0 -140
- claude_mpm/agents/templates/prompt-engineer.json +0 -737
- claude_mpm/agents/templates/python_engineer.json +0 -387
- claude_mpm/agents/templates/qa.json +0 -242
- claude_mpm/agents/templates/react_engineer.json +0 -238
- claude_mpm/agents/templates/refactoring_engineer.json +0 -276
- claude_mpm/agents/templates/research.json +0 -188
- claude_mpm/agents/templates/ruby-engineer.json +0 -280
- claude_mpm/agents/templates/rust_engineer.json +0 -275
- claude_mpm/agents/templates/security.json +0 -202
- claude_mpm/agents/templates/svelte-engineer.json +0 -225
- claude_mpm/agents/templates/ticketing.json +0 -177
- claude_mpm/agents/templates/typescript_engineer.json +0 -285
- claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
- claude_mpm/agents/templates/version_control.json +0 -157
- claude_mpm/agents/templates/web_qa.json +0 -399
- claude_mpm/agents/templates/web_ui.json +0 -189
- claude_mpm/commands/mpm-tickets.md +0 -102
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
- claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
- claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
- claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
- claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
- claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
- claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
- claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
- claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
- claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
- claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
- claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/built/connection-manager.js +0 -536
- claude_mpm/dashboard/static/built/dashboard.js +0 -2
- claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/built/react/events.js +0 -30
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
- claude_mpm/dashboard/static/built/shared/logger.js +0 -385
- claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/built/socket-client.js +0 -2
- claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/dist/dashboard.js +0 -2
- claude_mpm/dashboard/static/dist/react/events.js +0 -30
- claude_mpm/dashboard/static/dist/socket-client.js +0 -2
- claude_mpm/dashboard/static/events.html +0 -607
- claude_mpm/dashboard/static/index.html +0 -635
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/js/shared/logger.js +0 -385
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
- claude_mpm/dashboard/static/legacy/activity.html +0 -736
- claude_mpm/dashboard/static/legacy/agents.html +0 -786
- claude_mpm/dashboard/static/legacy/files.html +0 -747
- claude_mpm/dashboard/static/legacy/tools.html +0 -831
- claude_mpm/dashboard/static/monitors.html +0 -431
- claude_mpm/dashboard/static/production/events.html +0 -659
- claude_mpm/dashboard/static/production/main.html +0 -698
- claude_mpm/dashboard/static/production/monitors.html +0 -483
- claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
- claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
- claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
- claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
- claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
- /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
- /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
- /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
- /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/WHEEL +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/top_level.txt +0 -0
|
@@ -246,14 +246,29 @@ class DoctorReporter:
|
|
|
246
246
|
def _report_markdown(self, summary: DiagnosticSummary):
|
|
247
247
|
"""Generate comprehensive Markdown-formatted report."""
|
|
248
248
|
import datetime
|
|
249
|
+
import platform
|
|
250
|
+
import sys
|
|
249
251
|
|
|
250
|
-
# Header with timestamp
|
|
252
|
+
# Header with timestamp and system info
|
|
251
253
|
print("# Claude MPM Doctor Report")
|
|
254
|
+
print()
|
|
255
|
+
now = datetime.datetime.now(datetime.timezone.utc)
|
|
256
|
+
print(f"**Generated:** {now.strftime('%Y-%m-%d %H:%M:%S %Z')}")
|
|
252
257
|
print(
|
|
253
|
-
f"
|
|
258
|
+
f"**System:** {platform.system()} {platform.release()} ({platform.machine()})"
|
|
254
259
|
)
|
|
255
|
-
print(f"**
|
|
256
|
-
print("
|
|
260
|
+
print(f"**Python:** {sys.version.split()[0]}")
|
|
261
|
+
print(f"**claude-mpm:** {self._get_version()}")
|
|
262
|
+
|
|
263
|
+
# Get current working directory for context
|
|
264
|
+
from pathlib import Path
|
|
265
|
+
|
|
266
|
+
cwd = Path.cwd()
|
|
267
|
+
print(f"**Working Directory:** {cwd}")
|
|
268
|
+
|
|
269
|
+
print()
|
|
270
|
+
print("---")
|
|
271
|
+
print()
|
|
257
272
|
|
|
258
273
|
# System Overview
|
|
259
274
|
print("## System Overview\n")
|
|
@@ -271,15 +286,17 @@ class DoctorReporter:
|
|
|
271
286
|
+ summary.skipped_count
|
|
272
287
|
)
|
|
273
288
|
if total > 0:
|
|
274
|
-
print(f"| ✅ OK | {summary.ok_count} | {summary.ok_count*100//total}% |")
|
|
275
289
|
print(
|
|
276
|
-
f"|
|
|
290
|
+
f"| ✅ OK | {summary.ok_count} | {summary.ok_count * 100 // total}% |"
|
|
277
291
|
)
|
|
278
292
|
print(
|
|
279
|
-
f"|
|
|
293
|
+
f"| ⚠️ Warning | {summary.warning_count} | {summary.warning_count * 100 // total}% |"
|
|
280
294
|
)
|
|
281
295
|
print(
|
|
282
|
-
f"|
|
|
296
|
+
f"| ❌ Error | {summary.error_count} | {summary.error_count * 100 // total}% |"
|
|
297
|
+
)
|
|
298
|
+
print(
|
|
299
|
+
f"| ⏭️ Skipped | {summary.skipped_count} | {summary.skipped_count * 100 // total}% |"
|
|
283
300
|
)
|
|
284
301
|
print()
|
|
285
302
|
|
|
@@ -331,10 +348,23 @@ class DoctorReporter:
|
|
|
331
348
|
print("```")
|
|
332
349
|
print()
|
|
333
350
|
|
|
334
|
-
# Footer
|
|
351
|
+
# Footer with generation metadata
|
|
352
|
+
print("---")
|
|
353
|
+
print()
|
|
354
|
+
print("## Report Metadata")
|
|
355
|
+
print()
|
|
356
|
+
print("- **Tool:** `claude-mpm doctor`")
|
|
357
|
+
print(f"- **Version:** {self._get_version()}")
|
|
358
|
+
print(f"- **Generated:** {now.strftime('%Y-%m-%d %H:%M:%S %Z')}")
|
|
359
|
+
if self.verbose:
|
|
360
|
+
print("- **Verbose Mode:** Enabled")
|
|
361
|
+
print()
|
|
335
362
|
print("---")
|
|
363
|
+
print()
|
|
364
|
+
print("🤖 *Generated with [Claude Code](https://claude.com/claude-code)*")
|
|
365
|
+
print()
|
|
336
366
|
print(
|
|
337
|
-
"
|
|
367
|
+
"*For more information, run `claude-mpm doctor --verbose` or visit the [documentation](https://github.com/bobmatnyc/claude-mpm).*"
|
|
338
368
|
)
|
|
339
369
|
|
|
340
370
|
def _color(self, text: str, color: str) -> str:
|
|
@@ -256,9 +256,9 @@ class DirectSocketIORelay:
|
|
|
256
256
|
event_type, broadcast_data
|
|
257
257
|
)
|
|
258
258
|
self.stats["events_relayed"] += 1
|
|
259
|
-
self.stats[
|
|
260
|
-
|
|
261
|
-
|
|
259
|
+
self.stats["events_failed"] -= (
|
|
260
|
+
1 # Undo the failure count
|
|
261
|
+
)
|
|
262
262
|
logger.info(
|
|
263
263
|
f"[DirectRelay] Retry successful for {event_type}"
|
|
264
264
|
)
|
|
@@ -68,6 +68,9 @@ class EventBus:
|
|
|
68
68
|
# Track async handler tasks to prevent garbage collection
|
|
69
69
|
self._handler_tasks: Set[asyncio.Task] = set()
|
|
70
70
|
|
|
71
|
+
# Track handler wrappers for removal
|
|
72
|
+
self._handler_wrappers: Dict[tuple, Callable] = {}
|
|
73
|
+
|
|
71
74
|
logger.info("EventBus initialized")
|
|
72
75
|
|
|
73
76
|
@classmethod
|
|
@@ -266,8 +269,20 @@ class EventBus:
|
|
|
266
269
|
|
|
267
270
|
logger.debug(f"Registered wildcard handler for: {event_type}")
|
|
268
271
|
else:
|
|
269
|
-
#
|
|
270
|
-
|
|
272
|
+
# Wrap handler to catch exceptions and prevent them from stopping other handlers
|
|
273
|
+
def safe_handler(data):
|
|
274
|
+
try:
|
|
275
|
+
handler(data)
|
|
276
|
+
except Exception as e:
|
|
277
|
+
if self._debug:
|
|
278
|
+
logger.debug(f"Handler error for {event_type}: {e}")
|
|
279
|
+
|
|
280
|
+
# Store mapping for later removal
|
|
281
|
+
wrapper_key = (event_type, handler)
|
|
282
|
+
self._handler_wrappers[wrapper_key] = safe_handler
|
|
283
|
+
|
|
284
|
+
# Regular event registration with wrapped handler
|
|
285
|
+
self._emitter.on(event_type, safe_handler)
|
|
271
286
|
logger.debug(f"Registered handler for: {event_type}")
|
|
272
287
|
|
|
273
288
|
def once(self, event_type: str, handler: Callable) -> None:
|
|
@@ -287,7 +302,17 @@ class EventBus:
|
|
|
287
302
|
event_type: The event type
|
|
288
303
|
handler: The handler to remove
|
|
289
304
|
"""
|
|
290
|
-
|
|
305
|
+
# Check if we have a wrapped version of this handler
|
|
306
|
+
wrapper_key = (event_type, handler)
|
|
307
|
+
if wrapper_key in self._handler_wrappers:
|
|
308
|
+
# Remove the wrapped handler from pyee
|
|
309
|
+
wrapped_handler = self._handler_wrappers[wrapper_key]
|
|
310
|
+
self._emitter.remove_listener(event_type, wrapped_handler)
|
|
311
|
+
# Remove from our tracking dict
|
|
312
|
+
del self._handler_wrappers[wrapper_key]
|
|
313
|
+
else:
|
|
314
|
+
# No wrapper, remove directly (e.g., for wildcard handlers or direct registrations)
|
|
315
|
+
self._emitter.remove_listener(event_type, handler)
|
|
291
316
|
logger.debug(f"Removed handler for: {event_type}")
|
|
292
317
|
|
|
293
318
|
def remove_all_listeners(self, event_type: Optional[str] = None) -> None:
|
|
@@ -298,9 +323,17 @@ class EventBus:
|
|
|
298
323
|
"""
|
|
299
324
|
if event_type:
|
|
300
325
|
self._emitter.remove_all_listeners(event_type)
|
|
326
|
+
# Clean up wrappers for this event type
|
|
327
|
+
wrappers_to_remove = [
|
|
328
|
+
key for key in self._handler_wrappers if key[0] == event_type
|
|
329
|
+
]
|
|
330
|
+
for key in wrappers_to_remove:
|
|
331
|
+
del self._handler_wrappers[key]
|
|
301
332
|
logger.debug(f"Removed all handlers for: {event_type}")
|
|
302
333
|
else:
|
|
303
334
|
self._emitter.remove_all_listeners()
|
|
335
|
+
# Clean up all wrappers
|
|
336
|
+
self._handler_wrappers.clear()
|
|
304
337
|
logger.debug("Removed all event handlers")
|
|
305
338
|
|
|
306
339
|
def _record_event(self, event_type: str, data: Any) -> None:
|
|
@@ -133,8 +133,7 @@ class LoggingConsumer(IEventConsumer):
|
|
|
133
133
|
"""Format an event for logging."""
|
|
134
134
|
# Build base message
|
|
135
135
|
message = (
|
|
136
|
-
f"[{event.topic}] {event.type} "
|
|
137
|
-
f"(id={event.id[:8]}, source={event.source})"
|
|
136
|
+
f"[{event.topic}] {event.type} (id={event.id[:8]}, source={event.source})"
|
|
138
137
|
)
|
|
139
138
|
|
|
140
139
|
# Add data if configured
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Git Operations Service Package
|
|
3
|
+
================================
|
|
4
|
+
|
|
5
|
+
Provides Git operations abstraction for PR workflow automation.
|
|
6
|
+
Used by agent-improver and skills-manager agents.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .git_operations_service import (
|
|
10
|
+
GitAuthenticationError,
|
|
11
|
+
GitConflictError,
|
|
12
|
+
GitOperationError,
|
|
13
|
+
GitOperationsService,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"GitAuthenticationError",
|
|
18
|
+
"GitConflictError",
|
|
19
|
+
"GitOperationError",
|
|
20
|
+
"GitOperationsService",
|
|
21
|
+
]
|
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Git Operations Service
|
|
3
|
+
======================
|
|
4
|
+
|
|
5
|
+
Abstraction layer for Git operations used in PR workflow automation.
|
|
6
|
+
|
|
7
|
+
Design Decisions:
|
|
8
|
+
- Uses subprocess for git commands (not gitpython) for simplicity and reliability
|
|
9
|
+
- Provides rollback mechanism on failures
|
|
10
|
+
- Validates repo state before operations
|
|
11
|
+
- Clear error messages for debugging
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
>>> service = GitOperationsService()
|
|
15
|
+
>>> success = service.create_branch(Path("~/.claude-mpm/cache/remote-agents"), "improve/research-memory")
|
|
16
|
+
>>> if success:
|
|
17
|
+
... service.stage_files(Path("~/.claude-mpm/cache/remote-agents"), ["agents/research.md"])
|
|
18
|
+
... service.commit(Path("~/.claude-mpm/cache/remote-agents"), "feat: improve research agent memory handling")
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import subprocess
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from typing import List, Optional, Tuple
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# Custom Exceptions
|
|
27
|
+
class GitOperationError(Exception):
|
|
28
|
+
"""Base exception for git operation failures."""
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class GitConflictError(GitOperationError):
|
|
32
|
+
"""Raised when git detects merge conflicts."""
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class GitAuthenticationError(GitOperationError):
|
|
36
|
+
"""Raised when git authentication fails."""
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class GitOperationsService:
|
|
40
|
+
"""
|
|
41
|
+
Service for Git repository operations.
|
|
42
|
+
|
|
43
|
+
Provides abstraction over git commands for PR workflow automation.
|
|
44
|
+
All operations validate repository state and provide clear error messages.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def __init__(self, timeout: int = 30):
|
|
48
|
+
"""
|
|
49
|
+
Initialize git operations service.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
timeout: Command timeout in seconds (default: 30)
|
|
53
|
+
"""
|
|
54
|
+
self.timeout = timeout
|
|
55
|
+
|
|
56
|
+
def is_git_repo(self, repo_path: Path) -> bool:
|
|
57
|
+
"""
|
|
58
|
+
Check if directory is a git repository.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
repo_path: Path to check
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
True if directory is a git repo, False otherwise
|
|
65
|
+
|
|
66
|
+
Example:
|
|
67
|
+
>>> service = GitOperationsService()
|
|
68
|
+
>>> service.is_git_repo(Path("~/.claude-mpm/cache/remote-agents"))
|
|
69
|
+
True
|
|
70
|
+
"""
|
|
71
|
+
try:
|
|
72
|
+
result = self._run_git_command(
|
|
73
|
+
["git", "rev-parse", "--git-dir"], cwd=repo_path
|
|
74
|
+
)
|
|
75
|
+
return result[0] == 0
|
|
76
|
+
except Exception:
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
def get_current_branch(self, repo_path: Path) -> str:
|
|
80
|
+
"""
|
|
81
|
+
Get current branch name.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
repo_path: Repository path
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
Current branch name
|
|
88
|
+
|
|
89
|
+
Raises:
|
|
90
|
+
GitOperationError: If not in a git repo or command fails
|
|
91
|
+
"""
|
|
92
|
+
self._validate_repo(repo_path)
|
|
93
|
+
|
|
94
|
+
returncode, stdout, stderr = self._run_git_command(
|
|
95
|
+
["git", "branch", "--show-current"], cwd=repo_path
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
if returncode != 0:
|
|
99
|
+
raise GitOperationError(f"Failed to get current branch: {stderr}")
|
|
100
|
+
|
|
101
|
+
return stdout.strip()
|
|
102
|
+
|
|
103
|
+
def has_uncommitted_changes(self, repo_path: Path) -> bool:
|
|
104
|
+
"""
|
|
105
|
+
Check if repository has uncommitted changes.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
repo_path: Repository path
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
True if there are uncommitted changes
|
|
112
|
+
|
|
113
|
+
Raises:
|
|
114
|
+
GitOperationError: If command fails
|
|
115
|
+
"""
|
|
116
|
+
self._validate_repo(repo_path)
|
|
117
|
+
|
|
118
|
+
returncode, stdout, stderr = self._run_git_command(
|
|
119
|
+
["git", "status", "--porcelain"], cwd=repo_path
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
if returncode != 0:
|
|
123
|
+
raise GitOperationError(f"Failed to check git status: {stderr}")
|
|
124
|
+
|
|
125
|
+
return bool(stdout.strip())
|
|
126
|
+
|
|
127
|
+
def create_and_checkout_branch(
|
|
128
|
+
self, repo_path: Path, branch_name: str, base_branch: str = "main"
|
|
129
|
+
) -> bool:
|
|
130
|
+
"""
|
|
131
|
+
Create and checkout a new branch from base branch.
|
|
132
|
+
|
|
133
|
+
Pulls latest from remote before creating branch to avoid conflicts.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
repo_path: Repository path
|
|
137
|
+
branch_name: New branch name (e.g., "improve/research-memory")
|
|
138
|
+
base_branch: Base branch to branch from (default: "main")
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
True if successful
|
|
142
|
+
|
|
143
|
+
Raises:
|
|
144
|
+
GitOperationError: If operation fails
|
|
145
|
+
GitConflictError: If merge conflicts detected
|
|
146
|
+
|
|
147
|
+
Example:
|
|
148
|
+
>>> service = GitOperationsService()
|
|
149
|
+
>>> service.create_and_checkout_branch(
|
|
150
|
+
... Path("~/.claude-mpm/cache/remote-agents"),
|
|
151
|
+
... "improve/research-memory",
|
|
152
|
+
... "main"
|
|
153
|
+
... )
|
|
154
|
+
True
|
|
155
|
+
"""
|
|
156
|
+
self._validate_repo(repo_path)
|
|
157
|
+
|
|
158
|
+
# Store current branch for rollback
|
|
159
|
+
original_branch = self.get_current_branch(repo_path)
|
|
160
|
+
|
|
161
|
+
try:
|
|
162
|
+
# Checkout base branch
|
|
163
|
+
returncode, _stdout, stderr = self._run_git_command(
|
|
164
|
+
["git", "checkout", base_branch], cwd=repo_path
|
|
165
|
+
)
|
|
166
|
+
if returncode != 0:
|
|
167
|
+
raise GitOperationError(f"Failed to checkout {base_branch}: {stderr}")
|
|
168
|
+
|
|
169
|
+
# Pull latest from remote
|
|
170
|
+
returncode, _stdout, stderr = self._run_git_command(
|
|
171
|
+
["git", "pull", "origin", base_branch], cwd=repo_path
|
|
172
|
+
)
|
|
173
|
+
if returncode != 0:
|
|
174
|
+
# Non-blocking if pull fails (might not have remote configured)
|
|
175
|
+
pass
|
|
176
|
+
|
|
177
|
+
# Create and checkout new branch
|
|
178
|
+
returncode, _stdout, stderr = self._run_git_command(
|
|
179
|
+
["git", "checkout", "-b", branch_name], cwd=repo_path
|
|
180
|
+
)
|
|
181
|
+
if returncode != 0:
|
|
182
|
+
raise GitOperationError(
|
|
183
|
+
f"Failed to create branch {branch_name}: {stderr}"
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
return True
|
|
187
|
+
|
|
188
|
+
except Exception as e:
|
|
189
|
+
# Rollback to original branch on failure
|
|
190
|
+
try:
|
|
191
|
+
self._run_git_command(
|
|
192
|
+
["git", "checkout", original_branch], cwd=repo_path
|
|
193
|
+
)
|
|
194
|
+
except Exception:
|
|
195
|
+
pass # Best effort rollback
|
|
196
|
+
|
|
197
|
+
raise GitOperationError(f"Failed to create branch: {e}") from e
|
|
198
|
+
|
|
199
|
+
def stage_files(self, repo_path: Path, files: List[str]) -> bool:
|
|
200
|
+
"""
|
|
201
|
+
Stage files for commit.
|
|
202
|
+
|
|
203
|
+
Args:
|
|
204
|
+
repo_path: Repository path
|
|
205
|
+
files: List of file paths relative to repo root
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
True if successful
|
|
209
|
+
|
|
210
|
+
Raises:
|
|
211
|
+
GitOperationError: If staging fails
|
|
212
|
+
"""
|
|
213
|
+
self._validate_repo(repo_path)
|
|
214
|
+
|
|
215
|
+
if not files:
|
|
216
|
+
raise GitOperationError("No files specified for staging")
|
|
217
|
+
|
|
218
|
+
returncode, _stdout, stderr = self._run_git_command(
|
|
219
|
+
["git", "add"] + files, cwd=repo_path
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
if returncode != 0:
|
|
223
|
+
raise GitOperationError(f"Failed to stage files: {stderr}")
|
|
224
|
+
|
|
225
|
+
return True
|
|
226
|
+
|
|
227
|
+
def commit(self, repo_path: Path, message: str, allow_empty: bool = False) -> bool:
|
|
228
|
+
"""
|
|
229
|
+
Commit staged changes.
|
|
230
|
+
|
|
231
|
+
Args:
|
|
232
|
+
repo_path: Repository path
|
|
233
|
+
message: Commit message (should follow conventional commits format)
|
|
234
|
+
allow_empty: Allow empty commits
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
True if successful
|
|
238
|
+
|
|
239
|
+
Raises:
|
|
240
|
+
GitOperationError: If commit fails
|
|
241
|
+
|
|
242
|
+
Example:
|
|
243
|
+
>>> service = GitOperationsService()
|
|
244
|
+
>>> service.commit(
|
|
245
|
+
... Path("~/.claude-mpm/cache/remote-agents"),
|
|
246
|
+
... "feat(agent): improve research agent memory handling\\n\\n- Add hard limit of 5 files"
|
|
247
|
+
... )
|
|
248
|
+
True
|
|
249
|
+
"""
|
|
250
|
+
self._validate_repo(repo_path)
|
|
251
|
+
|
|
252
|
+
if not message:
|
|
253
|
+
raise GitOperationError("Commit message cannot be empty")
|
|
254
|
+
|
|
255
|
+
cmd = ["git", "commit", "-m", message]
|
|
256
|
+
if allow_empty:
|
|
257
|
+
cmd.append("--allow-empty")
|
|
258
|
+
|
|
259
|
+
returncode, _stdout, stderr = self._run_git_command(cmd, cwd=repo_path)
|
|
260
|
+
|
|
261
|
+
if returncode != 0:
|
|
262
|
+
# Check if it's just "nothing to commit"
|
|
263
|
+
if "nothing to commit" in stderr.lower() and not allow_empty:
|
|
264
|
+
raise GitOperationError("No changes to commit")
|
|
265
|
+
raise GitOperationError(f"Failed to commit: {stderr}")
|
|
266
|
+
|
|
267
|
+
return True
|
|
268
|
+
|
|
269
|
+
def push(
|
|
270
|
+
self, repo_path: Path, branch_name: str, set_upstream: bool = True
|
|
271
|
+
) -> bool:
|
|
272
|
+
"""
|
|
273
|
+
Push branch to remote.
|
|
274
|
+
|
|
275
|
+
Args:
|
|
276
|
+
repo_path: Repository path
|
|
277
|
+
branch_name: Branch name to push
|
|
278
|
+
set_upstream: Set upstream tracking (default: True)
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
True if successful
|
|
282
|
+
|
|
283
|
+
Raises:
|
|
284
|
+
GitOperationError: If push fails
|
|
285
|
+
GitAuthenticationError: If authentication fails
|
|
286
|
+
|
|
287
|
+
Example:
|
|
288
|
+
>>> service = GitOperationsService()
|
|
289
|
+
>>> service.push(Path("~/.claude-mpm/cache/remote-agents"), "improve/research-memory")
|
|
290
|
+
True
|
|
291
|
+
"""
|
|
292
|
+
self._validate_repo(repo_path)
|
|
293
|
+
|
|
294
|
+
cmd = ["git", "push"]
|
|
295
|
+
if set_upstream:
|
|
296
|
+
cmd.extend(["-u", "origin", branch_name])
|
|
297
|
+
else:
|
|
298
|
+
cmd.extend(["origin", branch_name])
|
|
299
|
+
|
|
300
|
+
returncode, _stdout, stderr = self._run_git_command(cmd, cwd=repo_path)
|
|
301
|
+
|
|
302
|
+
if returncode != 0:
|
|
303
|
+
# Check for authentication errors
|
|
304
|
+
if any(
|
|
305
|
+
keyword in stderr.lower()
|
|
306
|
+
for keyword in ["authentication", "permission denied", "403"]
|
|
307
|
+
):
|
|
308
|
+
raise GitAuthenticationError(
|
|
309
|
+
f"Git authentication failed. Please configure SSH keys or credentials: {stderr}"
|
|
310
|
+
)
|
|
311
|
+
raise GitOperationError(f"Failed to push branch: {stderr}")
|
|
312
|
+
|
|
313
|
+
return True
|
|
314
|
+
|
|
315
|
+
def pull(self, repo_path: Path, branch: str = "main") -> bool:
|
|
316
|
+
"""
|
|
317
|
+
Pull latest changes from remote.
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
repo_path: Repository path
|
|
321
|
+
branch: Branch name to pull
|
|
322
|
+
|
|
323
|
+
Returns:
|
|
324
|
+
True if successful
|
|
325
|
+
|
|
326
|
+
Raises:
|
|
327
|
+
GitOperationError: If pull fails
|
|
328
|
+
GitConflictError: If merge conflicts detected
|
|
329
|
+
"""
|
|
330
|
+
self._validate_repo(repo_path)
|
|
331
|
+
|
|
332
|
+
returncode, _stdout, stderr = self._run_git_command(
|
|
333
|
+
["git", "pull", "origin", branch], cwd=repo_path
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
if returncode != 0:
|
|
337
|
+
# Check for merge conflicts
|
|
338
|
+
if "conflict" in stderr.lower():
|
|
339
|
+
raise GitConflictError(
|
|
340
|
+
f"Merge conflicts detected when pulling {branch}: {stderr}"
|
|
341
|
+
)
|
|
342
|
+
raise GitOperationError(f"Failed to pull {branch}: {stderr}")
|
|
343
|
+
|
|
344
|
+
return True
|
|
345
|
+
|
|
346
|
+
def checkout_branch(self, repo_path: Path, branch_name: str) -> bool:
|
|
347
|
+
"""
|
|
348
|
+
Checkout existing branch.
|
|
349
|
+
|
|
350
|
+
Args:
|
|
351
|
+
repo_path: Repository path
|
|
352
|
+
branch_name: Branch name to checkout
|
|
353
|
+
|
|
354
|
+
Returns:
|
|
355
|
+
True if successful
|
|
356
|
+
|
|
357
|
+
Raises:
|
|
358
|
+
GitOperationError: If checkout fails
|
|
359
|
+
"""
|
|
360
|
+
self._validate_repo(repo_path)
|
|
361
|
+
|
|
362
|
+
returncode, _stdout, stderr = self._run_git_command(
|
|
363
|
+
["git", "checkout", branch_name], cwd=repo_path
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
if returncode != 0:
|
|
367
|
+
raise GitOperationError(f"Failed to checkout {branch_name}: {stderr}")
|
|
368
|
+
|
|
369
|
+
return True
|
|
370
|
+
|
|
371
|
+
def get_remote_url(self, repo_path: Path) -> Optional[str]:
|
|
372
|
+
"""
|
|
373
|
+
Get remote origin URL.
|
|
374
|
+
|
|
375
|
+
Args:
|
|
376
|
+
repo_path: Repository path
|
|
377
|
+
|
|
378
|
+
Returns:
|
|
379
|
+
Remote URL or None if not configured
|
|
380
|
+
|
|
381
|
+
Raises:
|
|
382
|
+
GitOperationError: If command fails
|
|
383
|
+
"""
|
|
384
|
+
self._validate_repo(repo_path)
|
|
385
|
+
|
|
386
|
+
returncode, stdout, _stderr = self._run_git_command(
|
|
387
|
+
["git", "config", "--get", "remote.origin.url"], cwd=repo_path
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
if returncode != 0:
|
|
391
|
+
return None
|
|
392
|
+
|
|
393
|
+
return stdout.strip()
|
|
394
|
+
|
|
395
|
+
def validate_repo(self, repo_path: Path) -> Tuple[bool, str]:
|
|
396
|
+
"""
|
|
397
|
+
Validate repository configuration.
|
|
398
|
+
|
|
399
|
+
Args:
|
|
400
|
+
repo_path: Repository path
|
|
401
|
+
|
|
402
|
+
Returns:
|
|
403
|
+
Tuple of (is_valid, message)
|
|
404
|
+
|
|
405
|
+
Example:
|
|
406
|
+
>>> service = GitOperationsService()
|
|
407
|
+
>>> valid, msg = service.validate_repo(Path("~/.claude-mpm/cache/remote-agents"))
|
|
408
|
+
>>> if not valid:
|
|
409
|
+
... print(f"Repository invalid: {msg}")
|
|
410
|
+
"""
|
|
411
|
+
try:
|
|
412
|
+
if not repo_path.exists():
|
|
413
|
+
return False, f"Path does not exist: {repo_path}"
|
|
414
|
+
|
|
415
|
+
if not self.is_git_repo(repo_path):
|
|
416
|
+
return False, f"Not a git repository: {repo_path}"
|
|
417
|
+
|
|
418
|
+
remote_url = self.get_remote_url(repo_path)
|
|
419
|
+
if not remote_url:
|
|
420
|
+
return False, "No remote origin configured"
|
|
421
|
+
|
|
422
|
+
return True, "Repository is valid"
|
|
423
|
+
|
|
424
|
+
except Exception as e:
|
|
425
|
+
return False, f"Validation failed: {e}"
|
|
426
|
+
|
|
427
|
+
def rollback_changes(self, repo_path: Path, original_branch: str) -> bool:
|
|
428
|
+
"""
|
|
429
|
+
Rollback uncommitted changes and return to original branch.
|
|
430
|
+
|
|
431
|
+
Args:
|
|
432
|
+
repo_path: Repository path
|
|
433
|
+
original_branch: Branch to return to
|
|
434
|
+
|
|
435
|
+
Returns:
|
|
436
|
+
True if successful (best effort)
|
|
437
|
+
"""
|
|
438
|
+
try:
|
|
439
|
+
# Discard uncommitted changes
|
|
440
|
+
self._run_git_command(["git", "reset", "--hard"], cwd=repo_path)
|
|
441
|
+
|
|
442
|
+
# Checkout original branch
|
|
443
|
+
self._run_git_command(["git", "checkout", original_branch], cwd=repo_path)
|
|
444
|
+
|
|
445
|
+
return True
|
|
446
|
+
|
|
447
|
+
except Exception:
|
|
448
|
+
return False
|
|
449
|
+
|
|
450
|
+
def _validate_repo(self, repo_path: Path) -> None:
|
|
451
|
+
"""
|
|
452
|
+
Validate repository exists and is a git repo.
|
|
453
|
+
|
|
454
|
+
Args:
|
|
455
|
+
repo_path: Repository path
|
|
456
|
+
|
|
457
|
+
Raises:
|
|
458
|
+
GitOperationError: If validation fails
|
|
459
|
+
"""
|
|
460
|
+
if not repo_path.exists():
|
|
461
|
+
raise GitOperationError(f"Repository path does not exist: {repo_path}")
|
|
462
|
+
|
|
463
|
+
if not self.is_git_repo(repo_path):
|
|
464
|
+
raise GitOperationError(f"Not a git repository: {repo_path}")
|
|
465
|
+
|
|
466
|
+
def _run_git_command(self, command: List[str], cwd: Path) -> Tuple[int, str, str]:
|
|
467
|
+
"""
|
|
468
|
+
Run git command and return result.
|
|
469
|
+
|
|
470
|
+
Args:
|
|
471
|
+
command: Command and arguments
|
|
472
|
+
cwd: Working directory
|
|
473
|
+
|
|
474
|
+
Returns:
|
|
475
|
+
Tuple of (returncode, stdout, stderr)
|
|
476
|
+
"""
|
|
477
|
+
try:
|
|
478
|
+
result = subprocess.run(
|
|
479
|
+
command,
|
|
480
|
+
check=False,
|
|
481
|
+
cwd=cwd,
|
|
482
|
+
capture_output=True,
|
|
483
|
+
text=True,
|
|
484
|
+
timeout=self.timeout,
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
return result.returncode, result.stdout, result.stderr
|
|
488
|
+
|
|
489
|
+
except subprocess.TimeoutExpired as e:
|
|
490
|
+
raise GitOperationError(
|
|
491
|
+
f"Git command timed out after {self.timeout} seconds: {' '.join(command)}"
|
|
492
|
+
) from e
|
|
493
|
+
except Exception as e:
|
|
494
|
+
raise GitOperationError(f"Failed to run git command: {e}") from e
|