claude-mpm 4.20.3__py3-none-any.whl → 5.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_PM.md +35 -6
- claude_mpm/agents/OUTPUT_STYLE.md +3 -48
- claude_mpm/agents/PM_INSTRUCTIONS.md +1241 -667
- claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +1322 -0
- claude_mpm/agents/WORKFLOW.md +75 -2
- claude_mpm/agents/__init__.py +6 -0
- claude_mpm/agents/agent_loader.py +1 -4
- claude_mpm/agents/base_agent.json +6 -3
- claude_mpm/agents/base_agent_loader.py +10 -35
- claude_mpm/agents/frontmatter_validator.py +1 -1
- claude_mpm/agents/templates/circuit-breakers.md +1254 -0
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -0
- claude_mpm/agents/templates/structured-questions-examples.md +615 -0
- claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
- claude_mpm/agents/templates/ticketing-examples.md +277 -0
- claude_mpm/cli/__init__.py +37 -2
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +188 -30
- claude_mpm/cli/commands/agents.py +959 -36
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/analyze.py +3 -3
- claude_mpm/cli/commands/auto_configure.py +537 -239
- claude_mpm/cli/commands/cleanup.py +1 -1
- claude_mpm/cli/commands/config.py +7 -4
- claude_mpm/cli/commands/configure.py +924 -45
- claude_mpm/cli/commands/configure_agent_display.py +4 -4
- claude_mpm/cli/commands/configure_navigation.py +63 -46
- claude_mpm/cli/commands/debug.py +12 -12
- claude_mpm/cli/commands/doctor.py +10 -2
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/local_deploy.py +1 -4
- claude_mpm/cli/commands/mcp_install_commands.py +1 -1
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +573 -0
- claude_mpm/cli/commands/mpm_init/display.py +341 -0
- claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
- claude_mpm/cli/commands/mpm_init/modes.py +397 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
- claude_mpm/cli/commands/mpm_init_cli.py +396 -0
- claude_mpm/cli/commands/mpm_init_handler.py +67 -1
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/run.py +125 -167
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +835 -44
- claude_mpm/cli/executor.py +78 -3
- claude_mpm/cli/interactive/agent_wizard.py +1032 -47
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +256 -4
- claude_mpm/cli/parsers/auto_configure_parser.py +13 -0
- claude_mpm/cli/parsers/base_parser.py +53 -0
- claude_mpm/cli/parsers/config_parser.py +96 -43
- claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +145 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/startup.py +564 -108
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/cli_module/commands.py +1 -1
- claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
- claude_mpm/commands/mpm-agents-detect.md +9 -0
- claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
- claude_mpm/commands/mpm-agents-recommend.md +9 -0
- claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
- claude_mpm/commands/mpm-doctor.md +9 -0
- claude_mpm/commands/mpm-help.md +17 -2
- claude_mpm/commands/mpm-init.md +28 -3
- claude_mpm/commands/mpm-monitor.md +9 -0
- claude_mpm/commands/mpm-postmortem.md +123 -0
- claude_mpm/commands/mpm-session-resume.md +381 -0
- claude_mpm/commands/mpm-status.md +9 -0
- claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
- claude_mpm/commands/mpm-ticket-view.md +552 -0
- claude_mpm/commands/mpm-version.md +9 -0
- claude_mpm/commands/mpm.md +11 -0
- claude_mpm/config/agent_presets.py +488 -0
- claude_mpm/config/agent_sources.py +325 -0
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/constants.py +13 -0
- claude_mpm/core/api_validator.py +1 -1
- claude_mpm/core/claude_runner.py +19 -35
- claude_mpm/core/config.py +24 -0
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/framework/__init__.py +3 -16
- claude_mpm/core/framework/loaders/file_loader.py +54 -101
- claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
- claude_mpm/core/framework/processors/metadata_processor.py +1 -1
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +131 -10
- claude_mpm/core/interfaces.py +56 -1
- claude_mpm/core/logger.py +3 -1
- claude_mpm/core/oneshot_session.py +110 -8
- claude_mpm/core/protocols/__init__.py +23 -0
- claude_mpm/core/protocols/runner_protocol.py +103 -0
- claude_mpm/core/protocols/session_protocol.py +131 -0
- claude_mpm/core/shared/singleton_manager.py +11 -4
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/unified_config.py +22 -0
- claude_mpm/dashboard/static/css/activity.css +69 -69
- claude_mpm/dashboard/static/css/connection-status.css +10 -10
- claude_mpm/dashboard/static/css/dashboard.css +15 -15
- claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
- claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
- claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
- claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
- claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
- claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
- claude_mpm/dashboard/static/js/connection-manager.js +76 -76
- claude_mpm/dashboard/static/js/dashboard.js +76 -58
- claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/js/socket-client.js +138 -121
- claude_mpm/dashboard/templates/code_simple.html +23 -23
- claude_mpm/dashboard/templates/index.html +18 -18
- claude_mpm/experimental/cli_enhancements.py +1 -5
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
- claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
- claude_mpm/hooks/claude_hooks/installer.py +45 -0
- claude_mpm/hooks/claude_hooks/memory_integration.py +12 -1
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
- claude_mpm/hooks/failure_learning/__init__.py +2 -8
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
- claude_mpm/hooks/kuzu_response_hook.py +1 -5
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/scripts/claude-hook-handler.sh +3 -3
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/agent_builder.py +45 -9
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -0
- claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
- claude_mpm/services/agents/cache_git_manager.py +621 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
- claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
- claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
- claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
- claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
- claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
- claude_mpm/services/agents/git_source_manager.py +629 -0
- claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
- claude_mpm/services/agents/local_template_manager.py +50 -10
- claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
- claude_mpm/services/agents/sources/__init__.py +13 -0
- claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
- claude_mpm/services/agents/startup_sync.py +239 -0
- claude_mpm/services/agents/toolchain_detector.py +474 -0
- claude_mpm/services/analysis/__init__.py +25 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +36 -16
- claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
- claude_mpm/services/command_deployment_service.py +200 -6
- claude_mpm/services/core/base.py +31 -11
- claude_mpm/services/core/interfaces/__init__.py +1 -3
- claude_mpm/services/core/interfaces/health.py +1 -4
- claude_mpm/services/core/interfaces.py +56 -1
- claude_mpm/services/core/models/__init__.py +2 -11
- claude_mpm/services/core/models/agent_config.py +3 -0
- claude_mpm/services/core/models/process.py +4 -0
- claude_mpm/services/diagnostics/checks/__init__.py +4 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
- claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
- claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
- claude_mpm/services/diagnostics/models.py +21 -0
- claude_mpm/services/event_bus/direct_relay.py +3 -3
- claude_mpm/services/event_bus/event_bus.py +36 -3
- claude_mpm/services/event_bus/relay.py +23 -7
- claude_mpm/services/events/consumers/logging.py +1 -2
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +494 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
- claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
- claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
- claude_mpm/services/instructions/__init__.py +9 -0
- claude_mpm/services/instructions/instruction_cache_service.py +374 -0
- claude_mpm/services/local_ops/__init__.py +5 -13
- claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
- claude_mpm/services/local_ops/health_manager.py +1 -4
- claude_mpm/services/local_ops/process_manager.py +1 -1
- claude_mpm/services/local_ops/resource_monitor.py +2 -2
- claude_mpm/services/mcp_config_manager.py +75 -145
- claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
- claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
- claude_mpm/services/mcp_gateway/core/process_pool.py +41 -26
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
- claude_mpm/services/mcp_service_verifier.py +6 -3
- claude_mpm/services/memory/failure_tracker.py +19 -4
- claude_mpm/services/memory/optimizer.py +1 -1
- claude_mpm/services/model/model_router.py +8 -9
- claude_mpm/services/monitor/daemon.py +29 -9
- claude_mpm/services/monitor/daemon_manager.py +96 -19
- claude_mpm/services/monitor/server.py +2 -2
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/port_manager.py +1 -1
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/project/documentation_manager.py +2 -1
- claude_mpm/services/project/project_organizer.py +4 -0
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +17 -3
- claude_mpm/services/self_upgrade_service.py +165 -7
- claude_mpm/services/session_management_service.py +16 -4
- claude_mpm/services/skills/__init__.py +18 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +955 -0
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/git.py +2 -2
- claude_mpm/services/socketio/server/core.py +1 -4
- claude_mpm/services/socketio/server/main.py +1 -3
- claude_mpm/services/system_instructions_service.py +1 -3
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
- claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
- claude_mpm/services/unified/unified_deployment.py +1 -5
- claude_mpm/services/version_control/conflict_resolution.py +6 -4
- claude_mpm/services/visualization/__init__.py +1 -5
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/__init__.py +3 -3
- claude_mpm/skills/agent_skills_injector.py +42 -49
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +17 -10
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +92 -39
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +13 -12
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +5 -3
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +19 -12
- claude_mpm/skills/bundled/performance-profiling.md +6 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +6 -6
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +13 -9
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +8 -8
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +37 -15
- claude_mpm/skills/skills_registry.py +44 -48
- claude_mpm/skills/skills_service.py +117 -108
- claude_mpm/templates/questions/__init__.py +38 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +311 -0
- claude_mpm/templates/questions/project_init.py +385 -0
- claude_mpm/templates/questions/ticket_mgmt.py +394 -0
- claude_mpm/tools/__main__.py +8 -8
- claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
- claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
- claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
- claude_mpm/tools/code_tree_analyzer/core.py +380 -0
- claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
- claude_mpm/tools/code_tree_analyzer/events.py +168 -0
- claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
- claude_mpm/tools/code_tree_analyzer/models.py +39 -0
- claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
- claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
- claude_mpm/utils/agent_dependency_loader.py +80 -13
- claude_mpm/utils/agent_filters.py +288 -0
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +244 -0
- claude_mpm/utils/log_cleanup.py +3 -3
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/progress.py +387 -0
- claude_mpm/utils/robust_installer.py +3 -5
- claude_mpm/utils/structured_questions.py +619 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/METADATA +496 -65
- {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/RECORD +328 -416
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
- claude_mpm/agents/templates/agent-manager.json +0 -273
- claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
- claude_mpm/agents/templates/api_qa.json +0 -180
- claude_mpm/agents/templates/circuit_breakers.md +0 -638
- claude_mpm/agents/templates/clerk-ops.json +0 -235
- claude_mpm/agents/templates/code_analyzer.json +0 -101
- claude_mpm/agents/templates/content-agent.json +0 -358
- claude_mpm/agents/templates/dart_engineer.json +0 -307
- claude_mpm/agents/templates/data_engineer.json +0 -225
- claude_mpm/agents/templates/documentation.json +0 -211
- claude_mpm/agents/templates/engineer.json +0 -210
- claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
- claude_mpm/agents/templates/golang_engineer.json +0 -270
- claude_mpm/agents/templates/imagemagick.json +0 -264
- claude_mpm/agents/templates/java_engineer.json +0 -346
- claude_mpm/agents/templates/local_ops_agent.json +0 -1840
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
- claude_mpm/agents/templates/memory_manager.json +0 -158
- claude_mpm/agents/templates/nextjs_engineer.json +0 -285
- claude_mpm/agents/templates/ops.json +0 -185
- claude_mpm/agents/templates/php-engineer.json +0 -281
- claude_mpm/agents/templates/product_owner.json +0 -338
- claude_mpm/agents/templates/project_organizer.json +0 -140
- claude_mpm/agents/templates/prompt-engineer.json +0 -737
- claude_mpm/agents/templates/python_engineer.json +0 -387
- claude_mpm/agents/templates/qa.json +0 -242
- claude_mpm/agents/templates/react_engineer.json +0 -238
- claude_mpm/agents/templates/refactoring_engineer.json +0 -276
- claude_mpm/agents/templates/research.json +0 -188
- claude_mpm/agents/templates/ruby-engineer.json +0 -280
- claude_mpm/agents/templates/rust_engineer.json +0 -275
- claude_mpm/agents/templates/security.json +0 -202
- claude_mpm/agents/templates/svelte-engineer.json +0 -225
- claude_mpm/agents/templates/ticketing.json +0 -177
- claude_mpm/agents/templates/typescript_engineer.json +0 -285
- claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
- claude_mpm/agents/templates/version_control.json +0 -157
- claude_mpm/agents/templates/web_qa.json +0 -399
- claude_mpm/agents/templates/web_ui.json +0 -189
- claude_mpm/cli/commands/mpm_init.py +0 -2093
- claude_mpm/commands/mpm-tickets.md +0 -102
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
- claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
- claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
- claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
- claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
- claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
- claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
- claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
- claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
- claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
- claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
- claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/built/connection-manager.js +0 -536
- claude_mpm/dashboard/static/built/dashboard.js +0 -2
- claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/built/react/events.js +0 -30
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
- claude_mpm/dashboard/static/built/shared/logger.js +0 -385
- claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/built/socket-client.js +0 -2
- claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/dist/dashboard.js +0 -2
- claude_mpm/dashboard/static/dist/react/events.js +0 -30
- claude_mpm/dashboard/static/dist/socket-client.js +0 -2
- claude_mpm/dashboard/static/events.html +0 -607
- claude_mpm/dashboard/static/index.html +0 -635
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/js/shared/logger.js +0 -385
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
- claude_mpm/dashboard/static/legacy/activity.html +0 -736
- claude_mpm/dashboard/static/legacy/agents.html +0 -786
- claude_mpm/dashboard/static/legacy/files.html +0 -747
- claude_mpm/dashboard/static/legacy/tools.html +0 -831
- claude_mpm/dashboard/static/monitors.html +0 -431
- claude_mpm/dashboard/static/production/events.html +0 -659
- claude_mpm/dashboard/static/production/main.html +0 -698
- claude_mpm/dashboard/static/production/monitors.html +0 -483
- claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
- claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
- claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
- claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
- claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -75
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -184
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -107
- claude_mpm/skills/bundled/collaboration/requesting-code-review/code-reviewer.md +0 -146
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -118
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -177
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -175
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/common-failures.md +0 -213
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -314
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -227
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -74
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -32
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -328
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -209
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -123
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -304
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -96
- claude_mpm/tools/code_tree_analyzer.py +0 -1825
- /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
- /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
- /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
- /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/WHEEL +0 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Agent filtering utilities for claude-mpm.
|
|
3
|
+
|
|
4
|
+
WHY: This module provides centralized filtering logic to remove non-deployable
|
|
5
|
+
agents (BASE_AGENT) and already-deployed agents from user-facing displays.
|
|
6
|
+
|
|
7
|
+
DESIGN DECISIONS:
|
|
8
|
+
- BASE_AGENT is a build tool, not a deployable agent - filter everywhere
|
|
9
|
+
- Deployed agent detection supports both new (.claude-mpm/agents/) and
|
|
10
|
+
legacy (.claude/agents/)
|
|
11
|
+
- Case-insensitive BASE_AGENT detection for robustness
|
|
12
|
+
- Pure functions for easy testing and reuse
|
|
13
|
+
|
|
14
|
+
IMPLEMENTATION NOTES:
|
|
15
|
+
- Related to ticket 1M-502 Phase 1: UX improvements for agent filtering
|
|
16
|
+
- Addresses user confusion from seeing BASE_AGENT and deployed agents in lists
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import Dict, List, Optional, Set
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def is_base_agent(agent_id: str) -> bool:
|
|
24
|
+
"""Check if agent is BASE_AGENT (build tool, not deployable).
|
|
25
|
+
|
|
26
|
+
BASE_AGENT is an internal build tool used to construct other agents.
|
|
27
|
+
It should never appear in user-facing agent lists or deployment menus.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
agent_id: Agent identifier to check (may include path like "qa/BASE-AGENT")
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
True if agent is BASE_AGENT (case-insensitive), False otherwise
|
|
34
|
+
|
|
35
|
+
Examples:
|
|
36
|
+
>>> is_base_agent("BASE_AGENT")
|
|
37
|
+
True
|
|
38
|
+
>>> is_base_agent("base-agent")
|
|
39
|
+
True
|
|
40
|
+
>>> is_base_agent("qa/BASE-AGENT")
|
|
41
|
+
True
|
|
42
|
+
>>> is_base_agent("ENGINEER")
|
|
43
|
+
False
|
|
44
|
+
"""
|
|
45
|
+
if not agent_id:
|
|
46
|
+
return False
|
|
47
|
+
|
|
48
|
+
# Extract filename from path (handle cases like "qa/BASE-AGENT")
|
|
49
|
+
# 1M-502: Remote agents may have path prefixes like "qa/", "pm/", etc.
|
|
50
|
+
agent_name = agent_id.split("/")[-1]
|
|
51
|
+
|
|
52
|
+
normalized_id = agent_name.lower().replace("-", "").replace("_", "")
|
|
53
|
+
return normalized_id == "baseagent"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def filter_base_agents(agents: List[Dict]) -> List[Dict]:
|
|
57
|
+
"""Remove BASE_AGENT from agent list.
|
|
58
|
+
|
|
59
|
+
Filters out any agent with agent_id matching BASE_AGENT (case-insensitive).
|
|
60
|
+
This prevents users from seeing or selecting the internal build tool.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
agents: List of agent dictionaries, each containing at least 'agent_id' key
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Filtered list with BASE_AGENT removed
|
|
67
|
+
|
|
68
|
+
Examples:
|
|
69
|
+
>>> agents = [
|
|
70
|
+
... {"agent_id": "ENGINEER", "name": "Engineer"},
|
|
71
|
+
... {"agent_id": "BASE_AGENT", "name": "Base Agent"},
|
|
72
|
+
... {"agent_id": "PM", "name": "PM"}
|
|
73
|
+
... ]
|
|
74
|
+
>>> filtered = filter_base_agents(agents)
|
|
75
|
+
>>> len(filtered)
|
|
76
|
+
2
|
|
77
|
+
>>> "BASE_AGENT" in [a["agent_id"] for a in filtered]
|
|
78
|
+
False
|
|
79
|
+
"""
|
|
80
|
+
return [a for a in agents if not is_base_agent(a.get("agent_id", ""))]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def get_deployed_agent_ids(project_dir: Optional[Path] = None) -> Set[str]:
|
|
84
|
+
"""Get set of currently deployed agent IDs.
|
|
85
|
+
|
|
86
|
+
Checks virtual deployment state (.mpm_deployment_state) first, then falls back
|
|
87
|
+
to physical .md files for backward compatibility. This ensures agents are detected
|
|
88
|
+
whether deployed virtually or as physical files.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
project_dir: Project directory to check, defaults to current working directory
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
Set of deployed agent IDs (leaf names like "python-engineer", "qa")
|
|
95
|
+
|
|
96
|
+
Examples:
|
|
97
|
+
>>> deployed = get_deployed_agent_ids()
|
|
98
|
+
>>> "python-engineer" in deployed # If agent exists in deployment state
|
|
99
|
+
True
|
|
100
|
+
>>> "ENGINEER" in deployed # If ENGINEER.md exists
|
|
101
|
+
True
|
|
102
|
+
|
|
103
|
+
Design Rationale:
|
|
104
|
+
- Primary detection: Virtual deployment state (.mpm_deployment_state)
|
|
105
|
+
- Fallback detection: Physical .md files (.claude-mpm/agents/, .claude/agents/)
|
|
106
|
+
- Returns leaf names for consistent comparison with agent_id formats
|
|
107
|
+
- Combines both detection methods for complete coverage
|
|
108
|
+
- Graceful error handling for malformed or missing state files
|
|
109
|
+
|
|
110
|
+
Related:
|
|
111
|
+
- Fixes checkbox interface showing all agents as "○ [Available]" instead of "● [Installed]"
|
|
112
|
+
- Matches detection logic from _is_agent_deployed() in agent_state_manager.py
|
|
113
|
+
- Related to ticket 1M-502: Virtual deployment state detection
|
|
114
|
+
"""
|
|
115
|
+
deployed = set()
|
|
116
|
+
|
|
117
|
+
# Track if project_dir was explicitly provided
|
|
118
|
+
explicit_project_dir = project_dir is not None
|
|
119
|
+
|
|
120
|
+
if project_dir is None:
|
|
121
|
+
project_dir = Path.cwd()
|
|
122
|
+
|
|
123
|
+
# NEW: Check virtual deployment state (primary method)
|
|
124
|
+
# This is the current deployment model used by Claude Code
|
|
125
|
+
deployment_state_paths = [
|
|
126
|
+
project_dir / ".claude" / "agents" / ".mpm_deployment_state",
|
|
127
|
+
]
|
|
128
|
+
|
|
129
|
+
# Only check user-level state if using default project directory
|
|
130
|
+
# This prevents test isolation issues when explicit project_dir is provided
|
|
131
|
+
if not explicit_project_dir:
|
|
132
|
+
deployment_state_paths.append(
|
|
133
|
+
Path.home() / ".claude" / "agents" / ".mpm_deployment_state"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
for state_path in deployment_state_paths:
|
|
137
|
+
if state_path.exists():
|
|
138
|
+
try:
|
|
139
|
+
import json
|
|
140
|
+
|
|
141
|
+
with state_path.open() as f:
|
|
142
|
+
state = json.load(f)
|
|
143
|
+
|
|
144
|
+
# Extract agent IDs from deployment state
|
|
145
|
+
# Agent IDs are leaf names (e.g., "python-engineer", "qa")
|
|
146
|
+
agents = state.get("last_check_results", {}).get("agents", {})
|
|
147
|
+
deployed.update(agents.keys())
|
|
148
|
+
|
|
149
|
+
except (json.JSONDecodeError, KeyError) as e:
|
|
150
|
+
# Log error but continue - don't break if state file is malformed
|
|
151
|
+
import logging
|
|
152
|
+
|
|
153
|
+
logger = logging.getLogger(__name__)
|
|
154
|
+
logger.debug(f"Failed to read deployment state from {state_path}: {e}")
|
|
155
|
+
continue
|
|
156
|
+
except Exception as e:
|
|
157
|
+
# Catch unexpected errors - fail gracefully
|
|
158
|
+
import logging
|
|
159
|
+
|
|
160
|
+
logger = logging.getLogger(__name__)
|
|
161
|
+
logger.debug(f"Unexpected error reading deployment state: {e}")
|
|
162
|
+
continue
|
|
163
|
+
|
|
164
|
+
# EXISTING: Check physical .md files (fallback for backward compatibility)
|
|
165
|
+
# Check new architecture
|
|
166
|
+
new_agents_dir = project_dir / ".claude-mpm" / "agents"
|
|
167
|
+
if new_agents_dir.exists():
|
|
168
|
+
for file in new_agents_dir.glob("*.md"):
|
|
169
|
+
if file.stem not in {"BASE-AGENT", ".DS_Store"}:
|
|
170
|
+
deployed.add(file.stem)
|
|
171
|
+
|
|
172
|
+
# Check legacy architecture
|
|
173
|
+
legacy_agents_dir = project_dir / ".claude" / "agents"
|
|
174
|
+
if legacy_agents_dir.exists():
|
|
175
|
+
for file in legacy_agents_dir.glob("*.md"):
|
|
176
|
+
if file.stem not in {"BASE-AGENT", ".DS_Store"}:
|
|
177
|
+
deployed.add(file.stem)
|
|
178
|
+
|
|
179
|
+
# Check .claude/templates/ directory (where agents are actually deployed)
|
|
180
|
+
templates_dir = project_dir / ".claude" / "templates"
|
|
181
|
+
if templates_dir.exists():
|
|
182
|
+
for file in templates_dir.glob("*.md"):
|
|
183
|
+
if file.stem not in {
|
|
184
|
+
"BASE-AGENT",
|
|
185
|
+
".DS_Store",
|
|
186
|
+
"README",
|
|
187
|
+
"circuit-breakers",
|
|
188
|
+
}:
|
|
189
|
+
# Skip template/example files
|
|
190
|
+
if not any(x in file.stem for x in ["example", "template", "pm-"]):
|
|
191
|
+
deployed.add(file.stem)
|
|
192
|
+
|
|
193
|
+
# Check user-level directory only if using default project directory
|
|
194
|
+
# This prevents test isolation issues when explicit project_dir is provided
|
|
195
|
+
if not explicit_project_dir:
|
|
196
|
+
user_agents_dir = Path.home() / ".claude" / "agents"
|
|
197
|
+
if user_agents_dir.exists():
|
|
198
|
+
for file in user_agents_dir.glob("*.md"):
|
|
199
|
+
if file.stem not in {"BASE-AGENT", ".DS_Store"}:
|
|
200
|
+
deployed.add(file.stem)
|
|
201
|
+
|
|
202
|
+
return deployed
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def filter_deployed_agents(
|
|
206
|
+
agents: List[Dict], project_dir: Optional[Path] = None
|
|
207
|
+
) -> List[Dict]:
|
|
208
|
+
"""Remove already-deployed agents from list.
|
|
209
|
+
|
|
210
|
+
Filters agent list to show only agents that are not currently deployed.
|
|
211
|
+
This prevents users from attempting to re-deploy existing agents and
|
|
212
|
+
reduces confusion in deployment menus.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
agents: List of agent dictionaries, each containing at least 'agent_id' key
|
|
216
|
+
project_dir: Project directory to check, defaults to current working directory
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
Filtered list containing only non-deployed agents
|
|
220
|
+
|
|
221
|
+
Examples:
|
|
222
|
+
>>> agents = [
|
|
223
|
+
... {"agent_id": "ENGINEER", "name": "Engineer"},
|
|
224
|
+
... {"agent_id": "PM", "name": "PM"},
|
|
225
|
+
... {"agent_id": "QA", "name": "QA"}
|
|
226
|
+
... ]
|
|
227
|
+
>>> # Assuming ENGINEER is deployed
|
|
228
|
+
>>> filtered = filter_deployed_agents(agents)
|
|
229
|
+
>>> "ENGINEER" not in [a["agent_id"] for a in filtered]
|
|
230
|
+
True
|
|
231
|
+
|
|
232
|
+
Design Rationale:
|
|
233
|
+
- Checks filesystem for actual deployed files (source of truth)
|
|
234
|
+
- Supports both new and legacy agent directory structures
|
|
235
|
+
- Preserves agent order for consistent UX
|
|
236
|
+
"""
|
|
237
|
+
deployed_ids = get_deployed_agent_ids(project_dir)
|
|
238
|
+
return [a for a in agents if a.get("agent_id") not in deployed_ids]
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def apply_all_filters(
|
|
242
|
+
agents: List[Dict],
|
|
243
|
+
project_dir: Optional[Path] = None,
|
|
244
|
+
filter_base: bool = True,
|
|
245
|
+
filter_deployed: bool = False,
|
|
246
|
+
) -> List[Dict]:
|
|
247
|
+
"""Apply multiple filters to agent list in correct order.
|
|
248
|
+
|
|
249
|
+
Convenience function to apply common filtering combinations. Filters are
|
|
250
|
+
applied in this order:
|
|
251
|
+
1. BASE_AGENT filtering (if enabled)
|
|
252
|
+
2. Deployed agent filtering (if enabled)
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
agents: List of agent dictionaries to filter
|
|
256
|
+
project_dir: Project directory for deployment checks
|
|
257
|
+
filter_base: Remove BASE_AGENT from list (default: True)
|
|
258
|
+
filter_deployed: Remove deployed agents from list (default: False)
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
Filtered agent list
|
|
262
|
+
|
|
263
|
+
Examples:
|
|
264
|
+
>>> agents = get_all_agents()
|
|
265
|
+
>>> # For display/info purposes - remove only BASE_AGENT
|
|
266
|
+
>>> filtered = apply_all_filters(
|
|
267
|
+
... agents, filter_base=True, filter_deployed=False
|
|
268
|
+
... )
|
|
269
|
+
>>> # For deployment menus - remove BASE_AGENT and deployed agents
|
|
270
|
+
>>> deployable = apply_all_filters(
|
|
271
|
+
... agents, filter_base=True, filter_deployed=True
|
|
272
|
+
... )
|
|
273
|
+
|
|
274
|
+
Usage Guidelines:
|
|
275
|
+
- Use filter_base=True (default) for all user-facing displays
|
|
276
|
+
- Use filter_deployed=True when showing deployment options
|
|
277
|
+
- Use filter_deployed=False when showing all available agents
|
|
278
|
+
(info/list commands)
|
|
279
|
+
"""
|
|
280
|
+
result = agents
|
|
281
|
+
|
|
282
|
+
if filter_base:
|
|
283
|
+
result = filter_base_agents(result)
|
|
284
|
+
|
|
285
|
+
if filter_deployed:
|
|
286
|
+
result = filter_deployed_agents(result, project_dir)
|
|
287
|
+
|
|
288
|
+
return result
|
|
@@ -333,7 +333,9 @@ class SmartDependencyChecker:
|
|
|
333
333
|
return True, "No valid cache, checking needed"
|
|
334
334
|
|
|
335
335
|
def get_or_check_dependencies(
|
|
336
|
-
self,
|
|
336
|
+
self,
|
|
337
|
+
loader,
|
|
338
|
+
force_check: bool = False, # AgentDependencyLoader instance
|
|
337
339
|
) -> Tuple[Dict, bool]:
|
|
338
340
|
"""
|
|
339
341
|
Get dependency results from cache or perform check.
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
"""GitIgnore management utilities.
|
|
2
|
+
|
|
3
|
+
This module provides functionality to safely manage .gitignore entries,
|
|
4
|
+
ensuring claude-mpm configuration directories are excluded from version control.
|
|
5
|
+
|
|
6
|
+
Design Decisions:
|
|
7
|
+
- In-memory set for duplicate detection (O(1) lookups)
|
|
8
|
+
- Preserves existing file formatting and comments
|
|
9
|
+
- Adds section headers for clarity
|
|
10
|
+
- Handles edge cases (missing newlines, empty files, etc.)
|
|
11
|
+
|
|
12
|
+
Trade-offs:
|
|
13
|
+
- Simplicity: File append vs. full parse/rewrite (chosen append for safety)
|
|
14
|
+
- Performance: Read entire file vs. streaming (file is small, simplicity wins)
|
|
15
|
+
- Safety: Non-destructive append only, never modifies existing entries
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from typing import List, Set, Tuple
|
|
20
|
+
|
|
21
|
+
from claude_mpm.core.logging_utils import get_logger
|
|
22
|
+
|
|
23
|
+
logger = get_logger(__name__)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class GitIgnoreManager:
|
|
27
|
+
"""Manages .gitignore file updates safely and non-destructively.
|
|
28
|
+
|
|
29
|
+
Design Pattern: Builder pattern for fluent API
|
|
30
|
+
- Initialize with project directory
|
|
31
|
+
- Call ensure_entries() to add patterns
|
|
32
|
+
- Returns summary of changes made
|
|
33
|
+
|
|
34
|
+
Performance:
|
|
35
|
+
- Time Complexity: O(n) where n = existing .gitignore lines
|
|
36
|
+
- Space Complexity: O(n) for storing unique entries in set
|
|
37
|
+
- Expected Performance: <1ms for typical .gitignore files (<1000 lines)
|
|
38
|
+
|
|
39
|
+
Error Handling:
|
|
40
|
+
- FileNotFoundError: Creates new .gitignore if missing
|
|
41
|
+
- PermissionError: Propagated to caller for appropriate handling
|
|
42
|
+
- UnicodeDecodeError: Logged and treated as binary file (skip)
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def __init__(self, project_dir: Path):
|
|
46
|
+
"""Initialize with project directory.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
project_dir: Path to project root (where .gitignore lives)
|
|
50
|
+
"""
|
|
51
|
+
self.project_dir = Path(project_dir)
|
|
52
|
+
self.gitignore_path = self.project_dir / ".gitignore"
|
|
53
|
+
|
|
54
|
+
def ensure_entries(self, entries: List[str]) -> Tuple[List[str], List[str]]:
|
|
55
|
+
"""Ensure specified entries exist in .gitignore.
|
|
56
|
+
|
|
57
|
+
Non-destructive operation that:
|
|
58
|
+
1. Reads existing entries (if file exists)
|
|
59
|
+
2. Identifies which entries are missing
|
|
60
|
+
3. Appends only missing entries with section header
|
|
61
|
+
4. Preserves all existing content and formatting
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
entries: List of gitignore patterns to add (e.g., [".claude-mpm/"])
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
Tuple of (added_entries, existing_entries)
|
|
68
|
+
- added_entries: Patterns that were added to .gitignore
|
|
69
|
+
- existing_entries: Patterns that were already present
|
|
70
|
+
|
|
71
|
+
Example:
|
|
72
|
+
>>> manager = GitIgnoreManager(Path("."))
|
|
73
|
+
>>> added, existing = manager.ensure_entries([".claude-mpm/"])
|
|
74
|
+
>>> print(f"Added: {added}, Already present: {existing}")
|
|
75
|
+
Added: ['.claude-mpm/'], Already present: []
|
|
76
|
+
"""
|
|
77
|
+
# Read existing entries
|
|
78
|
+
existing = self._read_existing_entries()
|
|
79
|
+
|
|
80
|
+
# Determine what needs to be added
|
|
81
|
+
to_add = [e for e in entries if e not in existing]
|
|
82
|
+
already_present = [e for e in entries if e in existing]
|
|
83
|
+
|
|
84
|
+
if to_add:
|
|
85
|
+
self._append_entries(to_add)
|
|
86
|
+
logger.info(f"Added {len(to_add)} entries to .gitignore: {to_add}")
|
|
87
|
+
|
|
88
|
+
if already_present:
|
|
89
|
+
logger.debug(f"Entries already in .gitignore: {already_present}")
|
|
90
|
+
|
|
91
|
+
return to_add, already_present
|
|
92
|
+
|
|
93
|
+
def _read_existing_entries(self) -> Set[str]:
|
|
94
|
+
"""Read existing .gitignore entries.
|
|
95
|
+
|
|
96
|
+
Parses .gitignore file and extracts all non-comment, non-blank patterns.
|
|
97
|
+
Handles edge cases:
|
|
98
|
+
- File doesn't exist -> returns empty set
|
|
99
|
+
- File is binary -> logs warning, returns empty set
|
|
100
|
+
- File has no newline at end -> handled correctly
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
Set of existing gitignore patterns (stripped, normalized)
|
|
104
|
+
"""
|
|
105
|
+
if not self.gitignore_path.exists():
|
|
106
|
+
logger.debug(".gitignore does not exist, will create new file")
|
|
107
|
+
return set()
|
|
108
|
+
|
|
109
|
+
try:
|
|
110
|
+
with open(self.gitignore_path, encoding="utf-8") as f:
|
|
111
|
+
# Strip whitespace and comments, filter blanks
|
|
112
|
+
entries = {
|
|
113
|
+
line.strip()
|
|
114
|
+
for line in f
|
|
115
|
+
if line.strip() and not line.strip().startswith("#")
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
logger.debug(f"Found {len(entries)} existing entries in .gitignore")
|
|
119
|
+
return entries
|
|
120
|
+
|
|
121
|
+
except UnicodeDecodeError:
|
|
122
|
+
logger.warning(
|
|
123
|
+
f".gitignore appears to be binary, cannot parse: {self.gitignore_path}"
|
|
124
|
+
)
|
|
125
|
+
return set()
|
|
126
|
+
except Exception as e:
|
|
127
|
+
logger.error(f"Error reading .gitignore: {e}")
|
|
128
|
+
raise
|
|
129
|
+
|
|
130
|
+
def _append_entries(self, entries: List[str]) -> None:
|
|
131
|
+
"""Append entries to .gitignore with proper formatting.
|
|
132
|
+
|
|
133
|
+
Handles formatting edge cases:
|
|
134
|
+
- Ensures blank line before new section (if file exists and isn't empty)
|
|
135
|
+
- Adds section header comment for clarity
|
|
136
|
+
- Ensures each entry on its own line
|
|
137
|
+
- Handles missing trailing newline in existing file
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
entries: List of patterns to append
|
|
141
|
+
|
|
142
|
+
Raises:
|
|
143
|
+
PermissionError: If cannot write to .gitignore
|
|
144
|
+
OSError: If disk is full or other I/O error
|
|
145
|
+
"""
|
|
146
|
+
mode = "a" if self.gitignore_path.exists() else "w"
|
|
147
|
+
|
|
148
|
+
try:
|
|
149
|
+
with open(self.gitignore_path, mode, encoding="utf-8") as f:
|
|
150
|
+
# Add blank line before entries if file exists and isn't empty
|
|
151
|
+
if mode == "a" and self.gitignore_path.stat().st_size > 0:
|
|
152
|
+
# Check if last line has newline
|
|
153
|
+
with open(self.gitignore_path, "rb") as check:
|
|
154
|
+
check.seek(-1, 2) # Seek to last byte
|
|
155
|
+
last_byte = check.read(1)
|
|
156
|
+
if last_byte != b"\n":
|
|
157
|
+
f.write("\n")
|
|
158
|
+
|
|
159
|
+
f.write("\n# Claude MPM configuration\n")
|
|
160
|
+
else:
|
|
161
|
+
# New file or empty file - add header without extra blank line
|
|
162
|
+
f.write("# Claude MPM configuration\n")
|
|
163
|
+
|
|
164
|
+
for entry in entries:
|
|
165
|
+
f.write(f"{entry}\n")
|
|
166
|
+
|
|
167
|
+
logger.info(f"Updated .gitignore at {self.gitignore_path}")
|
|
168
|
+
|
|
169
|
+
except PermissionError:
|
|
170
|
+
logger.error(
|
|
171
|
+
f"Permission denied writing to .gitignore: {self.gitignore_path}"
|
|
172
|
+
)
|
|
173
|
+
raise
|
|
174
|
+
except OSError as e:
|
|
175
|
+
logger.error(f"I/O error writing to .gitignore: {e}")
|
|
176
|
+
raise
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def ensure_claude_mpm_gitignore(project_dir: str = ".") -> dict:
|
|
180
|
+
"""Ensure claude-mpm directories are in .gitignore.
|
|
181
|
+
|
|
182
|
+
Convenience function that wraps GitIgnoreManager to add standard
|
|
183
|
+
claude-mpm configuration directories to .gitignore.
|
|
184
|
+
|
|
185
|
+
Standard Entries Added:
|
|
186
|
+
- .claude-mpm/: Main configuration directory
|
|
187
|
+
- .claude/agents/: Agent runtime files
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
project_dir: Project directory path (default: current directory)
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
Dictionary with operation results:
|
|
194
|
+
- added: List of patterns that were added
|
|
195
|
+
- existing: List of patterns that were already present
|
|
196
|
+
- gitignore_path: Path to the .gitignore file
|
|
197
|
+
|
|
198
|
+
Example:
|
|
199
|
+
>>> result = ensure_claude_mpm_gitignore()
|
|
200
|
+
>>> if result["added"]:
|
|
201
|
+
... print(f"Added {len(result['added'])} entries to .gitignore")
|
|
202
|
+
|
|
203
|
+
Error Handling:
|
|
204
|
+
- PermissionError: Returns error dict with status="error"
|
|
205
|
+
- FileNotFoundError on parent dir: Returns error dict
|
|
206
|
+
- All other exceptions: Propagated to caller
|
|
207
|
+
"""
|
|
208
|
+
try:
|
|
209
|
+
manager = GitIgnoreManager(Path(project_dir))
|
|
210
|
+
|
|
211
|
+
# Standard claude-mpm entries
|
|
212
|
+
entries_to_add = [
|
|
213
|
+
".claude-mpm/",
|
|
214
|
+
".claude/agents/",
|
|
215
|
+
".mcp.json",
|
|
216
|
+
".claude.json",
|
|
217
|
+
".claude/",
|
|
218
|
+
]
|
|
219
|
+
|
|
220
|
+
added, existing = manager.ensure_entries(entries_to_add)
|
|
221
|
+
|
|
222
|
+
return {
|
|
223
|
+
"status": "success",
|
|
224
|
+
"added": added,
|
|
225
|
+
"existing": existing,
|
|
226
|
+
"gitignore_path": str(manager.gitignore_path),
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
except PermissionError as e:
|
|
230
|
+
logger.error(f"Permission denied updating .gitignore: {e}")
|
|
231
|
+
return {
|
|
232
|
+
"status": "error",
|
|
233
|
+
"error": f"Permission denied: {e}",
|
|
234
|
+
"added": [],
|
|
235
|
+
"existing": [],
|
|
236
|
+
}
|
|
237
|
+
except FileNotFoundError as e:
|
|
238
|
+
logger.error(f"Project directory not found: {e}")
|
|
239
|
+
return {
|
|
240
|
+
"status": "error",
|
|
241
|
+
"error": f"Directory not found: {e}",
|
|
242
|
+
"added": [],
|
|
243
|
+
"existing": [],
|
|
244
|
+
}
|
claude_mpm/utils/log_cleanup.py
CHANGED
|
@@ -496,15 +496,15 @@ class LogCleanupUtility:
|
|
|
496
496
|
}
|
|
497
497
|
|
|
498
498
|
# Cleanup operations
|
|
499
|
-
|
|
499
|
+
_sessions_removed, _sessions_space = self.cleanup_old_sessions(
|
|
500
500
|
session_max_age_days, dry_run
|
|
501
501
|
)
|
|
502
502
|
|
|
503
|
-
|
|
503
|
+
_archives_removed, _archives_space = self.cleanup_archived_logs(
|
|
504
504
|
archive_max_age_days, dry_run
|
|
505
505
|
)
|
|
506
506
|
|
|
507
|
-
|
|
507
|
+
_logs_removed, _logs_space = self.cleanup_old_logs(log_max_age_days, dry_run)
|
|
508
508
|
|
|
509
509
|
# Optional compression
|
|
510
510
|
if compress_age_days is not None:
|