claude-mpm 4.14.6__py3-none-any.whl → 4.21.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_ENGINEER.md +286 -0
- claude_mpm/agents/BASE_PM.md +272 -23
- claude_mpm/agents/OUTPUT_STYLE.md +48 -3
- claude_mpm/agents/PM_INSTRUCTIONS.md +49 -0
- claude_mpm/agents/agent_loader.py +17 -5
- claude_mpm/agents/frontmatter_validator.py +284 -253
- claude_mpm/agents/templates/agentic-coder-optimizer.json +9 -2
- claude_mpm/agents/templates/api_qa.json +7 -1
- claude_mpm/agents/templates/clerk-ops.json +8 -1
- claude_mpm/agents/templates/code_analyzer.json +4 -1
- claude_mpm/agents/templates/dart_engineer.json +11 -1
- claude_mpm/agents/templates/data_engineer.json +11 -1
- claude_mpm/agents/templates/documentation.json +6 -1
- claude_mpm/agents/templates/engineer.json +18 -1
- claude_mpm/agents/templates/gcp_ops_agent.json +8 -1
- claude_mpm/agents/templates/golang_engineer.json +11 -1
- claude_mpm/agents/templates/java_engineer.json +12 -2
- claude_mpm/agents/templates/local_ops_agent.json +216 -37
- claude_mpm/agents/templates/nextjs_engineer.json +11 -1
- claude_mpm/agents/templates/ops.json +8 -1
- claude_mpm/agents/templates/php-engineer.json +20 -4
- claude_mpm/agents/templates/project_organizer.json +10 -3
- claude_mpm/agents/templates/prompt-engineer.json +5 -1
- claude_mpm/agents/templates/python_engineer.json +19 -4
- claude_mpm/agents/templates/qa.json +7 -1
- claude_mpm/agents/templates/react_engineer.json +11 -1
- claude_mpm/agents/templates/refactoring_engineer.json +8 -1
- claude_mpm/agents/templates/research.json +4 -1
- claude_mpm/agents/templates/ruby-engineer.json +11 -1
- claude_mpm/agents/templates/rust_engineer.json +23 -8
- claude_mpm/agents/templates/security.json +6 -1
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/agents/templates/ticketing.json +6 -1
- claude_mpm/agents/templates/typescript_engineer.json +11 -1
- claude_mpm/agents/templates/vercel_ops_agent.json +8 -1
- claude_mpm/agents/templates/version_control.json +8 -1
- claude_mpm/agents/templates/web_qa.json +7 -1
- claude_mpm/agents/templates/web_ui.json +11 -1
- claude_mpm/cli/__init__.py +34 -740
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/agent_manager.py +25 -12
- claude_mpm/cli/commands/agent_state_manager.py +186 -0
- claude_mpm/cli/commands/agents.py +204 -148
- claude_mpm/cli/commands/aggregate.py +7 -3
- claude_mpm/cli/commands/analyze.py +9 -4
- claude_mpm/cli/commands/analyze_code.py +7 -2
- claude_mpm/cli/commands/auto_configure.py +7 -9
- claude_mpm/cli/commands/config.py +47 -13
- claude_mpm/cli/commands/configure.py +294 -1788
- claude_mpm/cli/commands/configure_agent_display.py +261 -0
- claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
- claude_mpm/cli/commands/configure_hook_manager.py +225 -0
- claude_mpm/cli/commands/configure_models.py +18 -0
- claude_mpm/cli/commands/configure_navigation.py +167 -0
- claude_mpm/cli/commands/configure_paths.py +104 -0
- claude_mpm/cli/commands/configure_persistence.py +254 -0
- claude_mpm/cli/commands/configure_startup_manager.py +646 -0
- claude_mpm/cli/commands/configure_template_editor.py +497 -0
- claude_mpm/cli/commands/configure_validators.py +73 -0
- claude_mpm/cli/commands/local_deploy.py +3 -2
- claude_mpm/cli/commands/memory.py +54 -20
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +525 -0
- claude_mpm/cli/commands/mpm_init/display.py +341 -0
- claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
- claude_mpm/cli/commands/mpm_init/modes.py +397 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
- claude_mpm/cli/commands/mpm_init_cli.py +396 -0
- claude_mpm/cli/commands/mpm_init_handler.py +75 -4
- claude_mpm/cli/commands/skills.py +488 -0
- claude_mpm/cli/executor.py +204 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +3 -0
- claude_mpm/cli/interactive/skills_wizard.py +491 -0
- claude_mpm/cli/parsers/base_parser.py +7 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
- claude_mpm/cli/parsers/skills_parser.py +137 -0
- claude_mpm/cli/shared/output_formatters.py +28 -19
- claude_mpm/cli/startup.py +538 -0
- claude_mpm/commands/mpm-auto-configure.md +52 -0
- claude_mpm/commands/mpm-help.md +3 -0
- claude_mpm/commands/mpm-init.md +112 -6
- claude_mpm/commands/mpm-version.md +113 -0
- claude_mpm/commands/mpm.md +1 -0
- claude_mpm/config/agent_config.py +2 -2
- claude_mpm/constants.py +12 -0
- claude_mpm/core/base_service.py +13 -12
- claude_mpm/core/config.py +42 -0
- claude_mpm/core/enums.py +452 -0
- claude_mpm/core/factories.py +1 -1
- claude_mpm/core/instruction_reinforcement_hook.py +2 -1
- claude_mpm/core/interactive_session.py +6 -3
- claude_mpm/core/interfaces.py +56 -1
- claude_mpm/core/logging_config.py +6 -2
- claude_mpm/core/oneshot_session.py +8 -4
- claude_mpm/core/optimized_agent_loader.py +3 -3
- claude_mpm/core/output_style_manager.py +12 -192
- claude_mpm/core/service_registry.py +5 -1
- claude_mpm/core/types.py +2 -9
- claude_mpm/core/typing_utils.py +7 -6
- claude_mpm/dashboard/static/js/dashboard.js +0 -14
- claude_mpm/dashboard/templates/index.html +3 -41
- claude_mpm/hooks/__init__.py +8 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
- claude_mpm/hooks/instruction_reinforcement.py +7 -2
- claude_mpm/hooks/session_resume_hook.py +121 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/services/agents/auto_config_manager.py +10 -11
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
- claude_mpm/services/agents/deployment/agent_validator.py +17 -1
- claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
- claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
- claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +7 -6
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +5 -3
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
- claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
- claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
- claude_mpm/services/agents/local_template_manager.py +1 -1
- claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
- claude_mpm/services/agents/recommender.py +47 -0
- claude_mpm/services/agents/registry/modification_tracker.py +5 -2
- claude_mpm/services/cli/resume_service.py +617 -0
- claude_mpm/services/cli/session_manager.py +87 -0
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +372 -0
- claude_mpm/services/command_handler_service.py +11 -5
- claude_mpm/services/core/interfaces/process.py +6 -6
- claude_mpm/services/core/interfaces.py +56 -1
- claude_mpm/services/core/models/__init__.py +0 -2
- claude_mpm/services/core/models/agent_config.py +15 -28
- claude_mpm/services/core/models/health.py +1 -28
- claude_mpm/services/core/models/process.py +22 -41
- claude_mpm/services/core/path_resolver.py +1 -1
- claude_mpm/services/diagnostics/__init__.py +2 -2
- claude_mpm/services/diagnostics/checks/agent_check.py +25 -24
- claude_mpm/services/diagnostics/checks/claude_code_check.py +24 -23
- claude_mpm/services/diagnostics/checks/common_issues_check.py +25 -24
- claude_mpm/services/diagnostics/checks/configuration_check.py +24 -23
- claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
- claude_mpm/services/diagnostics/checks/installation_check.py +30 -29
- claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
- claude_mpm/services/diagnostics/checks/mcp_check.py +50 -36
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +36 -31
- claude_mpm/services/diagnostics/checks/monitor_check.py +23 -22
- claude_mpm/services/diagnostics/checks/startup_log_check.py +9 -8
- claude_mpm/services/diagnostics/diagnostic_runner.py +6 -5
- claude_mpm/services/diagnostics/doctor_reporter.py +28 -25
- claude_mpm/services/diagnostics/models.py +37 -21
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
- claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
- claude_mpm/services/infrastructure/monitoring/base.py +5 -13
- claude_mpm/services/infrastructure/monitoring/network.py +7 -6
- claude_mpm/services/infrastructure/monitoring/process.py +13 -12
- claude_mpm/services/infrastructure/monitoring/resources.py +7 -6
- claude_mpm/services/infrastructure/monitoring/service.py +16 -15
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/local_ops/__init__.py +5 -3
- claude_mpm/services/local_ops/crash_detector.py +1 -1
- claude_mpm/services/local_ops/health_checks/http_check.py +2 -1
- claude_mpm/services/local_ops/health_checks/process_check.py +2 -1
- claude_mpm/services/local_ops/health_checks/resource_check.py +2 -1
- claude_mpm/services/local_ops/health_manager.py +1 -1
- claude_mpm/services/local_ops/process_manager.py +12 -12
- claude_mpm/services/local_ops/restart_manager.py +1 -1
- claude_mpm/services/local_ops/state_manager.py +6 -5
- claude_mpm/services/local_ops/unified_manager.py +2 -2
- claude_mpm/services/mcp_config_manager.py +7 -126
- claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
- claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
- claude_mpm/services/mcp_gateway/core/base.py +18 -31
- claude_mpm/services/mcp_gateway/core/process_pool.py +19 -10
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +97 -45
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +30 -28
- claude_mpm/services/memory_hook_service.py +4 -1
- claude_mpm/services/monitor/daemon_manager.py +3 -2
- claude_mpm/services/monitor/handlers/dashboard.py +2 -1
- claude_mpm/services/monitor/handlers/hooks.py +2 -1
- claude_mpm/services/monitor/management/lifecycle.py +3 -2
- claude_mpm/services/monitor/server.py +2 -1
- claude_mpm/services/session_management_service.py +3 -2
- claude_mpm/services/session_manager.py +205 -1
- claude_mpm/services/shared/async_service_base.py +16 -27
- claude_mpm/services/shared/lifecycle_service_base.py +1 -14
- claude_mpm/services/socketio/handlers/__init__.py +5 -2
- claude_mpm/services/socketio/handlers/hook.py +13 -2
- claude_mpm/services/socketio/handlers/registry.py +4 -2
- claude_mpm/services/socketio/server/main.py +10 -8
- claude_mpm/services/subprocess_launcher_service.py +14 -5
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +8 -7
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +6 -5
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +8 -7
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +7 -6
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +5 -4
- claude_mpm/services/unified/config_strategies/validation_strategy.py +13 -9
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +10 -3
- claude_mpm/services/unified/deployment_strategies/local.py +6 -5
- claude_mpm/services/unified/deployment_strategies/utils.py +6 -5
- claude_mpm/services/unified/deployment_strategies/vercel.py +7 -6
- claude_mpm/services/unified/interfaces.py +3 -1
- claude_mpm/services/unified/unified_analyzer.py +14 -10
- claude_mpm/services/unified/unified_config.py +2 -1
- claude_mpm/services/unified/unified_deployment.py +9 -4
- claude_mpm/services/version_service.py +104 -1
- claude_mpm/skills/__init__.py +42 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
- claude_mpm/skills/bundled/__init__.py +6 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +567 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/security-scanning.md +327 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +286 -0
- claude_mpm/skills/skill_manager.py +310 -0
- claude_mpm/skills/skills_registry.py +348 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/tools/code_tree_analyzer.py +177 -141
- claude_mpm/tools/code_tree_events.py +4 -2
- claude_mpm/utils/agent_dependency_loader.py +2 -2
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.21.0.dist-info}/METADATA +211 -33
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.21.0.dist-info}/RECORD +339 -199
- claude_mpm/agents/INSTRUCTIONS_OLD_DEPRECATED.md +0 -602
- claude_mpm/cli/commands/mpm_init.py +0 -1994
- claude_mpm/dashboard/static/css/code-tree.css +0 -1639
- claude_mpm/dashboard/static/js/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/js/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/js/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/js/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/js/components/code-tree.js +0 -5869
- claude_mpm/dashboard/static/js/components/code-viewer.js +0 -1386
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
- claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1041
- claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
- claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
- claude_mpm/services/project/analyzer_refactored.py +0 -450
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.21.0.dist-info}/WHEEL +0 -0
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.21.0.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.21.0.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.14.6.dist-info → claude_mpm-4.21.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
"""Session Resume Helper Service.
|
|
2
|
+
|
|
3
|
+
WHY: This service provides automatic session resume detection and prompting for PM startup.
|
|
4
|
+
It detects paused sessions, calculates git changes since pause, and presents resumption
|
|
5
|
+
context to users.
|
|
6
|
+
|
|
7
|
+
DESIGN DECISIONS:
|
|
8
|
+
- Project-specific session storage (.claude-mpm/sessions/)
|
|
9
|
+
- Backward compatibility with legacy .claude-mpm/sessions/pause/ location
|
|
10
|
+
- Non-blocking detection with graceful degradation
|
|
11
|
+
- Git change detection for context updates
|
|
12
|
+
- User-friendly prompts with time elapsed information
|
|
13
|
+
- Integration with existing SessionManager infrastructure
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import json
|
|
17
|
+
import subprocess
|
|
18
|
+
from datetime import datetime, timezone
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
21
|
+
|
|
22
|
+
from claude_mpm.core.logger import get_logger
|
|
23
|
+
|
|
24
|
+
logger = get_logger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SessionResumeHelper:
|
|
28
|
+
"""Helper for automatic session resume detection and prompting."""
|
|
29
|
+
|
|
30
|
+
def __init__(self, project_path: Optional[Path] = None):
|
|
31
|
+
"""Initialize session resume helper.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
project_path: Project root path (default: current directory)
|
|
35
|
+
"""
|
|
36
|
+
self.project_path = project_path or Path.cwd()
|
|
37
|
+
# Primary location: flattened structure
|
|
38
|
+
self.pause_dir = self.project_path / ".claude-mpm" / "sessions"
|
|
39
|
+
# Legacy location for backward compatibility
|
|
40
|
+
self.legacy_pause_dir = self.project_path / ".claude-mpm" / "sessions" / "pause"
|
|
41
|
+
|
|
42
|
+
def has_paused_sessions(self) -> bool:
|
|
43
|
+
"""Check if there are any paused sessions.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
True if paused sessions exist, False otherwise
|
|
47
|
+
"""
|
|
48
|
+
# Check both primary and legacy locations
|
|
49
|
+
session_files = []
|
|
50
|
+
|
|
51
|
+
if self.pause_dir.exists():
|
|
52
|
+
session_files.extend(list(self.pause_dir.glob("session-*.json")))
|
|
53
|
+
|
|
54
|
+
if self.legacy_pause_dir.exists():
|
|
55
|
+
session_files.extend(list(self.legacy_pause_dir.glob("session-*.json")))
|
|
56
|
+
|
|
57
|
+
return len(session_files) > 0
|
|
58
|
+
|
|
59
|
+
def get_most_recent_session(self) -> Optional[Dict[str, Any]]:
|
|
60
|
+
"""Get the most recent paused session.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
Session data dictionary or None if no sessions found
|
|
64
|
+
"""
|
|
65
|
+
# Find all session files from both locations
|
|
66
|
+
session_files = []
|
|
67
|
+
|
|
68
|
+
if self.pause_dir.exists():
|
|
69
|
+
session_files.extend(list(self.pause_dir.glob("session-*.json")))
|
|
70
|
+
|
|
71
|
+
if self.legacy_pause_dir.exists():
|
|
72
|
+
session_files.extend(list(self.legacy_pause_dir.glob("session-*.json")))
|
|
73
|
+
|
|
74
|
+
if not session_files:
|
|
75
|
+
return None
|
|
76
|
+
|
|
77
|
+
# Sort by modification time (most recent first)
|
|
78
|
+
session_files.sort(key=lambda p: p.stat().st_mtime, reverse=True)
|
|
79
|
+
|
|
80
|
+
# Load the most recent session
|
|
81
|
+
try:
|
|
82
|
+
with session_files[0].open("r") as f:
|
|
83
|
+
session_data = json.load(f)
|
|
84
|
+
session_data["file_path"] = session_files[0]
|
|
85
|
+
return session_data
|
|
86
|
+
except Exception as e:
|
|
87
|
+
logger.error(f"Failed to load session file {session_files[0]}: {e}")
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
def get_git_changes_since_pause(
|
|
91
|
+
self, paused_at: str, recent_commits: List[Dict[str, str]]
|
|
92
|
+
) -> Tuple[int, List[Dict[str, str]]]:
|
|
93
|
+
"""Calculate git changes since session was paused.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
paused_at: ISO-8601 timestamp when session was paused
|
|
97
|
+
recent_commits: List of recent commits from session data
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Tuple of (new_commit_count, new_commits_list)
|
|
101
|
+
"""
|
|
102
|
+
try:
|
|
103
|
+
# Parse pause timestamp
|
|
104
|
+
pause_time = datetime.fromisoformat(paused_at)
|
|
105
|
+
|
|
106
|
+
# Get commits since pause time
|
|
107
|
+
cmd = [
|
|
108
|
+
"git",
|
|
109
|
+
"log",
|
|
110
|
+
f'--since="{pause_time.isoformat()}"',
|
|
111
|
+
"--pretty=format:%h|%an|%ai|%s",
|
|
112
|
+
"--all",
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
result = subprocess.run(
|
|
116
|
+
cmd,
|
|
117
|
+
cwd=self.project_path,
|
|
118
|
+
capture_output=True,
|
|
119
|
+
text=True,
|
|
120
|
+
check=False,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
if result.returncode != 0:
|
|
124
|
+
logger.warning(f"Git log command failed: {result.stderr}")
|
|
125
|
+
return 0, []
|
|
126
|
+
|
|
127
|
+
# Parse commit output
|
|
128
|
+
new_commits = []
|
|
129
|
+
for line in result.stdout.strip().split("\n"):
|
|
130
|
+
if line:
|
|
131
|
+
parts = line.split("|", 3)
|
|
132
|
+
if len(parts) == 4:
|
|
133
|
+
new_commits.append(
|
|
134
|
+
{
|
|
135
|
+
"sha": parts[0],
|
|
136
|
+
"author": parts[1],
|
|
137
|
+
"timestamp": parts[2],
|
|
138
|
+
"message": parts[3],
|
|
139
|
+
}
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
return len(new_commits), new_commits
|
|
143
|
+
|
|
144
|
+
except Exception as e:
|
|
145
|
+
logger.error(f"Failed to get git changes: {e}")
|
|
146
|
+
return 0, []
|
|
147
|
+
|
|
148
|
+
def get_time_elapsed(self, paused_at: str) -> str:
|
|
149
|
+
"""Calculate human-readable time elapsed since pause.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
paused_at: ISO-8601 timestamp when session was paused
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
Human-readable time string (e.g., "2 hours ago", "3 days ago")
|
|
156
|
+
"""
|
|
157
|
+
try:
|
|
158
|
+
pause_time = datetime.fromisoformat(paused_at)
|
|
159
|
+
now = datetime.now(timezone.utc)
|
|
160
|
+
|
|
161
|
+
# Ensure pause_time is timezone-aware
|
|
162
|
+
if pause_time.tzinfo is None:
|
|
163
|
+
pause_time = pause_time.replace(tzinfo=timezone.utc)
|
|
164
|
+
|
|
165
|
+
delta = now - pause_time
|
|
166
|
+
|
|
167
|
+
# Calculate time components
|
|
168
|
+
days = delta.days
|
|
169
|
+
hours = delta.seconds // 3600
|
|
170
|
+
minutes = (delta.seconds % 3600) // 60
|
|
171
|
+
|
|
172
|
+
# Format human-readable string
|
|
173
|
+
if days > 0:
|
|
174
|
+
if days == 1:
|
|
175
|
+
return "1 day ago"
|
|
176
|
+
return f"{days} days ago"
|
|
177
|
+
if hours > 0:
|
|
178
|
+
if hours == 1:
|
|
179
|
+
return "1 hour ago"
|
|
180
|
+
return f"{hours} hours ago"
|
|
181
|
+
if minutes > 0:
|
|
182
|
+
if minutes == 1:
|
|
183
|
+
return "1 minute ago"
|
|
184
|
+
return f"{minutes} minutes ago"
|
|
185
|
+
return "just now"
|
|
186
|
+
|
|
187
|
+
except Exception as e:
|
|
188
|
+
logger.error(f"Failed to calculate time elapsed: {e}")
|
|
189
|
+
return "unknown time ago"
|
|
190
|
+
|
|
191
|
+
def format_resume_prompt(self, session_data: Dict[str, Any]) -> str:
|
|
192
|
+
"""Format a user-friendly resume prompt.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
session_data: Session data dictionary
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
Formatted prompt string for display
|
|
199
|
+
"""
|
|
200
|
+
try:
|
|
201
|
+
# Extract session information
|
|
202
|
+
paused_at = session_data.get("paused_at", "")
|
|
203
|
+
conversation = session_data.get("conversation", {})
|
|
204
|
+
git_context = session_data.get("git_context", {})
|
|
205
|
+
|
|
206
|
+
summary = conversation.get("summary", "No summary available")
|
|
207
|
+
accomplishments = conversation.get("accomplishments", [])
|
|
208
|
+
next_steps = conversation.get("next_steps", [])
|
|
209
|
+
|
|
210
|
+
# Calculate time elapsed
|
|
211
|
+
time_ago = self.get_time_elapsed(paused_at)
|
|
212
|
+
|
|
213
|
+
# Get git changes
|
|
214
|
+
recent_commits = git_context.get("recent_commits", [])
|
|
215
|
+
new_commit_count, new_commits = self.get_git_changes_since_pause(
|
|
216
|
+
paused_at, recent_commits
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
# Build prompt
|
|
220
|
+
lines = []
|
|
221
|
+
lines.append("\n" + "=" * 80)
|
|
222
|
+
lines.append("📋 PAUSED SESSION FOUND")
|
|
223
|
+
lines.append("=" * 80)
|
|
224
|
+
lines.append(f"\nPaused: {time_ago}")
|
|
225
|
+
lines.append(f"\nLast working on: {summary}")
|
|
226
|
+
|
|
227
|
+
if accomplishments:
|
|
228
|
+
lines.append("\nCompleted:")
|
|
229
|
+
for item in accomplishments[:5]: # Limit to first 5
|
|
230
|
+
lines.append(f" ✓ {item}")
|
|
231
|
+
if len(accomplishments) > 5:
|
|
232
|
+
lines.append(f" ... and {len(accomplishments) - 5} more")
|
|
233
|
+
|
|
234
|
+
if next_steps:
|
|
235
|
+
lines.append("\nNext steps:")
|
|
236
|
+
for item in next_steps[:5]: # Limit to first 5
|
|
237
|
+
lines.append(f" • {item}")
|
|
238
|
+
if len(next_steps) > 5:
|
|
239
|
+
lines.append(f" ... and {len(next_steps) - 5} more")
|
|
240
|
+
|
|
241
|
+
# Git changes information
|
|
242
|
+
if new_commit_count > 0:
|
|
243
|
+
lines.append(f"\nGit changes since pause: {new_commit_count} commits")
|
|
244
|
+
if new_commits:
|
|
245
|
+
lines.append("\nRecent commits:")
|
|
246
|
+
for commit in new_commits[:3]: # Show first 3
|
|
247
|
+
lines.append(
|
|
248
|
+
f" {commit['sha']} - {commit['message']} ({commit['author']})"
|
|
249
|
+
)
|
|
250
|
+
if len(new_commits) > 3:
|
|
251
|
+
lines.append(f" ... and {len(new_commits) - 3} more")
|
|
252
|
+
else:
|
|
253
|
+
lines.append("\nNo git changes since pause")
|
|
254
|
+
|
|
255
|
+
lines.append("\n" + "=" * 80)
|
|
256
|
+
lines.append(
|
|
257
|
+
"Use this context to resume work, or start fresh if not relevant."
|
|
258
|
+
)
|
|
259
|
+
lines.append("=" * 80 + "\n")
|
|
260
|
+
|
|
261
|
+
return "\n".join(lines)
|
|
262
|
+
|
|
263
|
+
except Exception as e:
|
|
264
|
+
logger.error(f"Failed to format resume prompt: {e}")
|
|
265
|
+
return "\n📋 Paused session found, but failed to format details.\n"
|
|
266
|
+
|
|
267
|
+
def check_and_display_resume_prompt(self) -> Optional[Dict[str, Any]]:
|
|
268
|
+
"""Check for paused sessions and display resume prompt if found.
|
|
269
|
+
|
|
270
|
+
This is the main entry point for PM startup integration.
|
|
271
|
+
|
|
272
|
+
Returns:
|
|
273
|
+
Session data if found and user should resume, None otherwise
|
|
274
|
+
"""
|
|
275
|
+
if not self.has_paused_sessions():
|
|
276
|
+
logger.debug("No paused sessions found")
|
|
277
|
+
return None
|
|
278
|
+
|
|
279
|
+
# Get most recent session
|
|
280
|
+
session_data = self.get_most_recent_session()
|
|
281
|
+
if not session_data:
|
|
282
|
+
logger.debug("Failed to load paused session data")
|
|
283
|
+
return None
|
|
284
|
+
|
|
285
|
+
# Display resume prompt
|
|
286
|
+
prompt_text = self.format_resume_prompt(session_data)
|
|
287
|
+
print(prompt_text)
|
|
288
|
+
|
|
289
|
+
# Return session data for PM to use
|
|
290
|
+
return session_data
|
|
291
|
+
|
|
292
|
+
def clear_session(self, session_data: Dict[str, Any]) -> bool:
|
|
293
|
+
"""Clear a paused session after successful resume.
|
|
294
|
+
|
|
295
|
+
Args:
|
|
296
|
+
session_data: Session data dictionary with 'file_path' key
|
|
297
|
+
|
|
298
|
+
Returns:
|
|
299
|
+
True if successfully cleared, False otherwise
|
|
300
|
+
"""
|
|
301
|
+
try:
|
|
302
|
+
file_path = session_data.get("file_path")
|
|
303
|
+
if not file_path or not isinstance(file_path, Path):
|
|
304
|
+
logger.error("Invalid session file path")
|
|
305
|
+
return False
|
|
306
|
+
|
|
307
|
+
if file_path.exists():
|
|
308
|
+
file_path.unlink()
|
|
309
|
+
logger.info(f"Cleared paused session: {file_path}")
|
|
310
|
+
|
|
311
|
+
# Also remove SHA256 checksum file if exists
|
|
312
|
+
sha_file = file_path.parent / f".{file_path.name}.sha256"
|
|
313
|
+
if sha_file.exists():
|
|
314
|
+
sha_file.unlink()
|
|
315
|
+
logger.debug(f"Cleared session checksum: {sha_file}")
|
|
316
|
+
|
|
317
|
+
return True
|
|
318
|
+
logger.warning(f"Session file not found: {file_path}")
|
|
319
|
+
return False
|
|
320
|
+
|
|
321
|
+
except Exception as e:
|
|
322
|
+
logger.error(f"Failed to clear session: {e}")
|
|
323
|
+
return False
|
|
324
|
+
|
|
325
|
+
def get_session_count(self) -> int:
|
|
326
|
+
"""Get count of paused sessions.
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
Number of paused sessions
|
|
330
|
+
"""
|
|
331
|
+
session_files = []
|
|
332
|
+
|
|
333
|
+
if self.pause_dir.exists():
|
|
334
|
+
session_files.extend(list(self.pause_dir.glob("session-*.json")))
|
|
335
|
+
|
|
336
|
+
if self.legacy_pause_dir.exists():
|
|
337
|
+
session_files.extend(list(self.legacy_pause_dir.glob("session-*.json")))
|
|
338
|
+
|
|
339
|
+
return len(session_files)
|
|
340
|
+
|
|
341
|
+
def list_all_sessions(self) -> List[Dict[str, Any]]:
|
|
342
|
+
"""List all paused sessions sorted by most recent.
|
|
343
|
+
|
|
344
|
+
Returns:
|
|
345
|
+
List of session data dictionaries
|
|
346
|
+
"""
|
|
347
|
+
session_files = []
|
|
348
|
+
|
|
349
|
+
if self.pause_dir.exists():
|
|
350
|
+
session_files.extend(list(self.pause_dir.glob("session-*.json")))
|
|
351
|
+
|
|
352
|
+
if self.legacy_pause_dir.exists():
|
|
353
|
+
session_files.extend(list(self.legacy_pause_dir.glob("session-*.json")))
|
|
354
|
+
|
|
355
|
+
if not session_files:
|
|
356
|
+
return []
|
|
357
|
+
|
|
358
|
+
# Sort by modification time (most recent first)
|
|
359
|
+
session_files.sort(key=lambda p: p.stat().st_mtime, reverse=True)
|
|
360
|
+
|
|
361
|
+
sessions = []
|
|
362
|
+
for session_file in session_files:
|
|
363
|
+
try:
|
|
364
|
+
with session_file.open("r") as f:
|
|
365
|
+
session_data = json.load(f)
|
|
366
|
+
session_data["file_path"] = session_file
|
|
367
|
+
sessions.append(session_data)
|
|
368
|
+
except Exception as e:
|
|
369
|
+
logger.error(f"Failed to load session {session_file}: {e}")
|
|
370
|
+
continue
|
|
371
|
+
|
|
372
|
+
return sessions
|
|
@@ -12,6 +12,7 @@ Extracted from ClaudeRunner to follow Single Responsibility Principle.
|
|
|
12
12
|
from typing import Any, Dict, List
|
|
13
13
|
|
|
14
14
|
from claude_mpm.core.base_service import BaseService
|
|
15
|
+
from claude_mpm.core.enums import OperationResult
|
|
15
16
|
from claude_mpm.services.core.interfaces import CommandHandlerInterface
|
|
16
17
|
|
|
17
18
|
|
|
@@ -169,7 +170,7 @@ class CommandHandlerService(BaseService, CommandHandlerInterface):
|
|
|
169
170
|
if command == "test":
|
|
170
171
|
success = self._handle_test_command(args)
|
|
171
172
|
return {
|
|
172
|
-
|
|
173
|
+
OperationResult.SUCCESS.value: success,
|
|
173
174
|
"command": command,
|
|
174
175
|
"args": args,
|
|
175
176
|
"message": (
|
|
@@ -179,7 +180,7 @@ class CommandHandlerService(BaseService, CommandHandlerInterface):
|
|
|
179
180
|
if command == "agents":
|
|
180
181
|
success = self._handle_agents_command(args)
|
|
181
182
|
return {
|
|
182
|
-
|
|
183
|
+
OperationResult.SUCCESS.value: success,
|
|
183
184
|
"command": command,
|
|
184
185
|
"args": args,
|
|
185
186
|
"message": (
|
|
@@ -189,14 +190,19 @@ class CommandHandlerService(BaseService, CommandHandlerInterface):
|
|
|
189
190
|
),
|
|
190
191
|
}
|
|
191
192
|
return {
|
|
192
|
-
|
|
193
|
+
OperationResult.SUCCESS.value: False,
|
|
193
194
|
"command": command,
|
|
194
195
|
"args": args,
|
|
195
|
-
|
|
196
|
+
OperationResult.ERROR.value: f"Unknown command: {command}",
|
|
196
197
|
"available_commands": self.get_available_commands(),
|
|
197
198
|
}
|
|
198
199
|
except Exception as e:
|
|
199
|
-
return {
|
|
200
|
+
return {
|
|
201
|
+
OperationResult.SUCCESS.value: False,
|
|
202
|
+
"command": command,
|
|
203
|
+
"args": args,
|
|
204
|
+
OperationResult.ERROR.value: str(e),
|
|
205
|
+
}
|
|
200
206
|
|
|
201
207
|
def get_command_help(self, command: str) -> str:
|
|
202
208
|
"""Get help text for a specific command.
|
|
@@ -32,10 +32,10 @@ USAGE:
|
|
|
32
32
|
from abc import ABC, abstractmethod
|
|
33
33
|
from typing import Dict, List, Optional
|
|
34
34
|
|
|
35
|
+
from claude_mpm.core.enums import ServiceState
|
|
35
36
|
from claude_mpm.services.core.models.process import (
|
|
36
37
|
DeploymentState,
|
|
37
38
|
ProcessInfo,
|
|
38
|
-
ProcessStatus,
|
|
39
39
|
StartConfig,
|
|
40
40
|
)
|
|
41
41
|
|
|
@@ -102,12 +102,12 @@ class IDeploymentStateManager(ABC):
|
|
|
102
102
|
"""
|
|
103
103
|
|
|
104
104
|
@abstractmethod
|
|
105
|
-
def get_deployments_by_status(self, status:
|
|
105
|
+
def get_deployments_by_status(self, status: ServiceState) -> List[DeploymentState]:
|
|
106
106
|
"""
|
|
107
107
|
Get all deployments with a specific status.
|
|
108
108
|
|
|
109
109
|
Args:
|
|
110
|
-
status:
|
|
110
|
+
status: ServiceState to filter by
|
|
111
111
|
|
|
112
112
|
Returns:
|
|
113
113
|
List of matching DeploymentState objects
|
|
@@ -168,14 +168,14 @@ class IDeploymentStateManager(ABC):
|
|
|
168
168
|
|
|
169
169
|
@abstractmethod
|
|
170
170
|
def update_deployment_status(
|
|
171
|
-
self, deployment_id: str, status:
|
|
171
|
+
self, deployment_id: str, status: ServiceState
|
|
172
172
|
) -> bool:
|
|
173
173
|
"""
|
|
174
174
|
Update the status of a deployment.
|
|
175
175
|
|
|
176
176
|
Args:
|
|
177
177
|
deployment_id: Unique deployment identifier
|
|
178
|
-
status: New
|
|
178
|
+
status: New ServiceState
|
|
179
179
|
|
|
180
180
|
Returns:
|
|
181
181
|
True if updated, False if deployment not found
|
|
@@ -290,7 +290,7 @@ class ILocalProcessManager(ABC):
|
|
|
290
290
|
|
|
291
291
|
@abstractmethod
|
|
292
292
|
def list_processes(
|
|
293
|
-
self, status_filter: Optional[
|
|
293
|
+
self, status_filter: Optional[ServiceState] = None
|
|
294
294
|
) -> List[ProcessInfo]:
|
|
295
295
|
"""
|
|
296
296
|
List all managed processes.
|
|
@@ -20,7 +20,62 @@ focused modules for better maintainability and testing.
|
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
22
|
# Re-export everything from the new modular structure for backward compatibility
|
|
23
|
-
from .interfaces import
|
|
23
|
+
from .interfaces import ( # noqa: F401
|
|
24
|
+
AgentCapabilitiesInterface,
|
|
25
|
+
AgentDeploymentInterface,
|
|
26
|
+
AgentMetadata,
|
|
27
|
+
CacheEntry,
|
|
28
|
+
CommandHandlerInterface,
|
|
29
|
+
HealthStatus,
|
|
30
|
+
HookServiceInterface,
|
|
31
|
+
IAgentRecommender,
|
|
32
|
+
IAgentRegistry,
|
|
33
|
+
IAutoConfigManager,
|
|
34
|
+
ICacheService,
|
|
35
|
+
IConfigurationManager,
|
|
36
|
+
IConfigurationService,
|
|
37
|
+
ICrashDetector,
|
|
38
|
+
IDeploymentStateManager,
|
|
39
|
+
IErrorHandler,
|
|
40
|
+
IEventBus,
|
|
41
|
+
IHealthCheck,
|
|
42
|
+
IHealthCheckManager,
|
|
43
|
+
IHealthMonitor,
|
|
44
|
+
ILocalProcessManager,
|
|
45
|
+
ILogMonitor,
|
|
46
|
+
IMemoryLeakDetector,
|
|
47
|
+
IModelProvider,
|
|
48
|
+
IModelRouter,
|
|
49
|
+
InterfaceRegistry,
|
|
50
|
+
IPerformanceMonitor,
|
|
51
|
+
IPromptCache,
|
|
52
|
+
IResourceMonitor,
|
|
53
|
+
IRestartManager,
|
|
54
|
+
IRestartPolicy,
|
|
55
|
+
IServiceContainer,
|
|
56
|
+
IServiceFactory,
|
|
57
|
+
IServiceLifecycle,
|
|
58
|
+
IStructuredLogger,
|
|
59
|
+
ITemplateManager,
|
|
60
|
+
IToolchainAnalyzer,
|
|
61
|
+
MemoryHookInterface,
|
|
62
|
+
MemoryServiceInterface,
|
|
63
|
+
ModelCapability,
|
|
64
|
+
ModelProvider,
|
|
65
|
+
ModelResponse,
|
|
66
|
+
ProjectAnalyzerInterface,
|
|
67
|
+
RunnerConfigurationInterface,
|
|
68
|
+
ServiceType,
|
|
69
|
+
SessionManagementInterface,
|
|
70
|
+
SocketIOServiceInterface,
|
|
71
|
+
SubprocessLauncherInterface,
|
|
72
|
+
SystemInstructionsInterface,
|
|
73
|
+
T,
|
|
74
|
+
TemplateRenderContext,
|
|
75
|
+
TicketManagerInterface,
|
|
76
|
+
UtilityServiceInterface,
|
|
77
|
+
VersionServiceInterface,
|
|
78
|
+
)
|
|
24
79
|
|
|
25
80
|
# All interface definitions have been moved to the interfaces/ package
|
|
26
81
|
# This file now serves as a compatibility layer that delegates to the modular structure
|
|
@@ -24,7 +24,6 @@ from .process import (
|
|
|
24
24
|
PROTECTED_PORT_RANGES,
|
|
25
25
|
DeploymentState,
|
|
26
26
|
ProcessInfo,
|
|
27
|
-
ProcessStatus,
|
|
28
27
|
StartConfig,
|
|
29
28
|
is_port_protected,
|
|
30
29
|
)
|
|
@@ -63,7 +62,6 @@ __all__ = [ # noqa: RUF022 - Grouped by category with comments for clarity
|
|
|
63
62
|
"ValidationResult",
|
|
64
63
|
"ConfigurationPreview",
|
|
65
64
|
# Process management models
|
|
66
|
-
"ProcessStatus",
|
|
67
65
|
"DeploymentState",
|
|
68
66
|
"ProcessInfo",
|
|
69
67
|
"StartConfig",
|
|
@@ -17,6 +17,11 @@ from dataclasses import dataclass, field
|
|
|
17
17
|
from enum import Enum
|
|
18
18
|
from typing import Any, Dict, List, Optional
|
|
19
19
|
|
|
20
|
+
from ....core.enums import OperationResult, ValidationSeverity
|
|
21
|
+
|
|
22
|
+
# Backward compatibility alias (consolidated in Phase 3A Batch 25)
|
|
23
|
+
ConfigurationStatus = OperationResult
|
|
24
|
+
|
|
20
25
|
|
|
21
26
|
class AgentSpecialization(str, Enum):
|
|
22
27
|
"""Agent specialization categories.
|
|
@@ -154,20 +159,6 @@ class AgentRecommendation:
|
|
|
154
159
|
}
|
|
155
160
|
|
|
156
161
|
|
|
157
|
-
class ConfigurationStatus(str, Enum):
|
|
158
|
-
"""Status of configuration operation.
|
|
159
|
-
|
|
160
|
-
WHY: Configuration can succeed, fail, or partially succeed. This enum
|
|
161
|
-
provides a standardized way to communicate operation outcomes.
|
|
162
|
-
"""
|
|
163
|
-
|
|
164
|
-
SUCCESS = "success"
|
|
165
|
-
PARTIAL_SUCCESS = "partial_success"
|
|
166
|
-
FAILURE = "failure"
|
|
167
|
-
VALIDATION_ERROR = "validation_error"
|
|
168
|
-
USER_CANCELLED = "user_cancelled"
|
|
169
|
-
|
|
170
|
-
|
|
171
162
|
@dataclass
|
|
172
163
|
class ConfigurationResult:
|
|
173
164
|
"""Result of automated configuration operation.
|
|
@@ -179,9 +170,17 @@ class ConfigurationResult:
|
|
|
179
170
|
DESIGN DECISION: Separates successful and failed deployments to enable
|
|
180
171
|
proper error handling. Includes validation results and user-facing
|
|
181
172
|
messages for transparency.
|
|
173
|
+
|
|
174
|
+
NOTE: Uses core OperationResult enum (consolidated from ConfigurationStatus
|
|
175
|
+
in Phase 3A Batch 25). Mappings:
|
|
176
|
+
- SUCCESS → OperationResult.SUCCESS
|
|
177
|
+
- PARTIAL_SUCCESS → OperationResult.WARNING (partial success with issues)
|
|
178
|
+
- FAILURE → OperationResult.FAILED
|
|
179
|
+
- VALIDATION_ERROR → OperationResult.ERROR
|
|
180
|
+
- USER_CANCELLED → OperationResult.CANCELLED
|
|
182
181
|
"""
|
|
183
182
|
|
|
184
|
-
status:
|
|
183
|
+
status: OperationResult
|
|
185
184
|
deployed_agents: List[str] = field(default_factory=list)
|
|
186
185
|
failed_agents: List[str] = field(default_factory=list)
|
|
187
186
|
validation_warnings: List[str] = field(default_factory=list)
|
|
@@ -193,7 +192,7 @@ class ConfigurationResult:
|
|
|
193
192
|
@property
|
|
194
193
|
def is_successful(self) -> bool:
|
|
195
194
|
"""Check if configuration was completely successful."""
|
|
196
|
-
return self.status ==
|
|
195
|
+
return self.status == OperationResult.SUCCESS
|
|
197
196
|
|
|
198
197
|
@property
|
|
199
198
|
def has_failures(self) -> bool:
|
|
@@ -223,18 +222,6 @@ class ConfigurationResult:
|
|
|
223
222
|
}
|
|
224
223
|
|
|
225
224
|
|
|
226
|
-
class ValidationSeverity(str, Enum):
|
|
227
|
-
"""Severity level for validation issues.
|
|
228
|
-
|
|
229
|
-
WHY: Not all validation issues are equally critical. This enum enables
|
|
230
|
-
categorization of issues by severity to support appropriate handling.
|
|
231
|
-
"""
|
|
232
|
-
|
|
233
|
-
ERROR = "error" # Blocks deployment
|
|
234
|
-
WARNING = "warning" # Should be reviewed but doesn't block
|
|
235
|
-
INFO = "info" # Informational only
|
|
236
|
-
|
|
237
|
-
|
|
238
225
|
@dataclass
|
|
239
226
|
class ValidationIssue:
|
|
240
227
|
"""Represents a validation issue.
|
|
@@ -16,36 +16,9 @@ ARCHITECTURE:
|
|
|
16
16
|
|
|
17
17
|
from dataclasses import asdict, dataclass, field
|
|
18
18
|
from datetime import datetime
|
|
19
|
-
from enum import Enum
|
|
20
19
|
from typing import Any, Dict, List
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
class HealthStatus(Enum):
|
|
24
|
-
"""
|
|
25
|
-
Health status levels.
|
|
26
|
-
|
|
27
|
-
WHY: Provides granular health states to distinguish between different
|
|
28
|
-
levels of service degradation.
|
|
29
|
-
|
|
30
|
-
States:
|
|
31
|
-
HEALTHY: All checks passing, process operating normally
|
|
32
|
-
DEGRADED: Process running but with issues (high resource usage, slow responses)
|
|
33
|
-
UNHEALTHY: Critical failure (process dead, crashed, or unresponsive)
|
|
34
|
-
UNKNOWN: Cannot determine health status
|
|
35
|
-
"""
|
|
36
|
-
|
|
37
|
-
HEALTHY = "healthy"
|
|
38
|
-
DEGRADED = "degraded"
|
|
39
|
-
UNHEALTHY = "unhealthy"
|
|
40
|
-
UNKNOWN = "unknown"
|
|
41
|
-
|
|
42
|
-
def is_operational(self) -> bool:
|
|
43
|
-
"""Check if status indicates operational service."""
|
|
44
|
-
return self in (HealthStatus.HEALTHY, HealthStatus.DEGRADED)
|
|
45
|
-
|
|
46
|
-
def is_critical(self) -> bool:
|
|
47
|
-
"""Check if status indicates critical failure."""
|
|
48
|
-
return self == HealthStatus.UNHEALTHY
|
|
21
|
+
from ....core.enums import HealthStatus
|
|
49
22
|
|
|
50
23
|
|
|
51
24
|
@dataclass
|