claude-mpm 4.16.0__py3-none-any.whl → 4.25.10__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_ENGINEER.md +286 -0
- claude_mpm/agents/BASE_PM.md +272 -23
- claude_mpm/agents/OUTPUT_STYLE.md +3 -48
- claude_mpm/agents/PM_INSTRUCTIONS.md +1821 -32
- claude_mpm/agents/WORKFLOW.md +75 -2
- claude_mpm/agents/agent_loader.py +4 -4
- claude_mpm/agents/base_agent.json +6 -3
- claude_mpm/agents/frontmatter_validator.py +1 -1
- claude_mpm/agents/templates/api_qa.json +5 -2
- claude_mpm/agents/templates/circuit_breakers.md +108 -2
- claude_mpm/agents/templates/documentation.json +33 -6
- claude_mpm/agents/templates/engineer.json +5 -1
- claude_mpm/agents/templates/javascript_engineer_agent.json +380 -0
- claude_mpm/agents/templates/php-engineer.json +10 -4
- claude_mpm/agents/templates/pm_red_flags.md +89 -19
- claude_mpm/agents/templates/project_organizer.json +7 -3
- claude_mpm/agents/templates/python_engineer.json +8 -3
- claude_mpm/agents/templates/qa.json +2 -1
- claude_mpm/agents/templates/react_engineer.json +1 -0
- claude_mpm/agents/templates/research.json +82 -12
- claude_mpm/agents/templates/rust_engineer.json +12 -7
- claude_mpm/agents/templates/security.json +4 -4
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/agents/templates/tauri_engineer.json +274 -0
- claude_mpm/agents/templates/ticketing.json +10 -6
- claude_mpm/agents/templates/version_control.json +4 -2
- claude_mpm/agents/templates/web_qa.json +2 -1
- claude_mpm/cli/README.md +253 -0
- claude_mpm/cli/__init__.py +11 -1
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/analyze.py +3 -3
- claude_mpm/cli/commands/cleanup.py +1 -1
- claude_mpm/cli/commands/configure_agent_display.py +4 -4
- claude_mpm/cli/commands/debug.py +12 -12
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/mcp_install_commands.py +1 -1
- claude_mpm/cli/commands/mcp_install_commands.py.backup +284 -0
- claude_mpm/cli/commands/mpm_init/README.md +365 -0
- 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/run.py +124 -128
- claude_mpm/cli/commands/skills.py +922 -0
- claude_mpm/cli/executor.py +58 -0
- claude_mpm/cli/interactive/agent_wizard.py +5 -5
- claude_mpm/cli/parsers/base_parser.py +35 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
- claude_mpm/cli/parsers/skills_parser.py +275 -0
- claude_mpm/cli/startup.py +168 -8
- 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/cli_module/refactoring_guide.md +253 -0
- claude_mpm/commands/mpm-auto-configure.md +52 -0
- claude_mpm/commands/mpm-help.md +6 -0
- claude_mpm/commands/mpm-init.md +130 -8
- claude_mpm/commands/mpm-resume.md +372 -0
- claude_mpm/commands/mpm-tickets.md +56 -7
- claude_mpm/commands/mpm-version.md +113 -0
- claude_mpm/commands/mpm.md +2 -0
- claude_mpm/config/agent_capabilities.yaml +658 -0
- claude_mpm/config/agent_config.py +2 -2
- claude_mpm/config/async_logging_config.yaml +145 -0
- claude_mpm/constants.py +24 -0
- claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +34 -0
- claude_mpm/core/api_validator.py +1 -1
- claude_mpm/core/claude_runner.py +14 -1
- claude_mpm/core/config.py +50 -0
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/factories.py +1 -1
- 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 +48 -3
- claude_mpm/core/interfaces.py +56 -1
- claude_mpm/core/logger.py +3 -1
- claude_mpm/core/oneshot_session.py +39 -0
- claude_mpm/core/optimized_agent_loader.py +3 -3
- claude_mpm/d2/.gitignore +22 -0
- claude_mpm/d2/ARCHITECTURE_COMPARISON.md +273 -0
- claude_mpm/d2/FLASK_INTEGRATION.md +156 -0
- claude_mpm/d2/IMPLEMENTATION_SUMMARY.md +452 -0
- claude_mpm/d2/QUICKSTART.md +186 -0
- claude_mpm/d2/README.md +232 -0
- claude_mpm/d2/STORE_FIX_SUMMARY.md +167 -0
- claude_mpm/d2/SVELTE5_STORES_GUIDE.md +180 -0
- claude_mpm/d2/TESTING.md +288 -0
- claude_mpm/d2/index.html +118 -0
- claude_mpm/d2/package.json +19 -0
- claude_mpm/d2/src/App.svelte +110 -0
- claude_mpm/d2/src/components/Header.svelte +153 -0
- claude_mpm/d2/src/components/MainContent.svelte +74 -0
- claude_mpm/d2/src/components/Sidebar.svelte +85 -0
- claude_mpm/d2/src/components/tabs/EventsTab.svelte +326 -0
- claude_mpm/d2/src/lib/socketio.js +144 -0
- claude_mpm/d2/src/main.js +7 -0
- claude_mpm/d2/src/stores/events.js +114 -0
- claude_mpm/d2/src/stores/socket.js +108 -0
- claude_mpm/d2/src/stores/theme.js +65 -0
- claude_mpm/d2/svelte.config.js +12 -0
- claude_mpm/d2/vite.config.js +15 -0
- claude_mpm/dashboard/.claude-mpm/memories/README.md +36 -0
- claude_mpm/dashboard/BUILD_NUMBER +1 -0
- claude_mpm/dashboard/README.md +121 -0
- claude_mpm/dashboard/VERSION +1 -0
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.tsx +273 -0
- claude_mpm/dashboard/react/components/ErrorBoundary.tsx +75 -0
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.tsx +141 -0
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.tsx +36 -0
- claude_mpm/dashboard/react/components/shared/FilterBar.tsx +89 -0
- claude_mpm/dashboard/react/contexts/DashboardContext.tsx +215 -0
- claude_mpm/dashboard/react/entries/events.tsx +165 -0
- claude_mpm/dashboard/react/hooks/useEvents.ts +191 -0
- claude_mpm/dashboard/react/hooks/useSocket.ts +225 -0
- claude_mpm/dashboard/static/built/REFACTORING_SUMMARY.md +170 -0
- claude_mpm/dashboard/static/built/components/activity-tree.js.map +1 -0
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/built/components/agent-inference.js.map +1 -0
- claude_mpm/dashboard/static/built/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/built/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +29 -29
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +24 -24
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +27 -27
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +25 -25
- claude_mpm/dashboard/static/built/components/code-tree.js.map +1 -0
- claude_mpm/dashboard/static/built/components/code-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/built/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/built/components/event-processor.js.map +1 -0
- claude_mpm/dashboard/static/built/components/event-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/export-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js.map +1 -0
- claude_mpm/dashboard/static/built/components/file-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/hud-library-loader.js.map +1 -0
- claude_mpm/dashboard/static/built/components/hud-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/hud-visualizer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/module-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/session-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/socket-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/ui-state-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/working-directory.js.map +1 -0
- claude_mpm/dashboard/static/built/connection-manager.js +76 -76
- claude_mpm/dashboard/static/built/dashboard.js.map +1 -0
- claude_mpm/dashboard/static/built/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/built/react/events.js.map +1 -0
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +9 -9
- claude_mpm/dashboard/static/built/shared/event-bus.js +5 -5
- claude_mpm/dashboard/static/built/shared/logger.js +16 -16
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +6 -6
- claude_mpm/dashboard/static/built/socket-client.js.map +1 -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/index.html +22 -22
- claude_mpm/dashboard/static/js/REFACTORING_SUMMARY.md +170 -0
- 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/shared/dom-helpers.js +9 -9
- claude_mpm/dashboard/static/js/shared/event-bus.js +5 -5
- claude_mpm/dashboard/static/js/shared/logger.js +16 -16
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +6 -6
- claude_mpm/dashboard/static/js/socket-client.js +138 -121
- claude_mpm/dashboard/static/navigation-test-results.md +118 -0
- claude_mpm/dashboard/static/production/main.html +21 -21
- claude_mpm/dashboard/static/test-archive/dashboard.html +22 -22
- claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +36 -0
- claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +39 -0
- claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +38 -0
- claude_mpm/dashboard/templates/code_simple.html +23 -23
- claude_mpm/dashboard/templates/index.html +18 -18
- claude_mpm/hooks/README.md +143 -0
- claude_mpm/hooks/__init__.py +8 -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/response_tracking.py +35 -1
- claude_mpm/hooks/session_resume_hook.py +121 -0
- claude_mpm/hooks/templates/README.md +180 -0
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/hooks/templates/settings.json.example +147 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/schemas/agent_schema.json +596 -0
- claude_mpm/schemas/frontmatter_schema.json +165 -0
- claude_mpm/scripts/claude-hook-handler.sh +3 -3
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/auto_config_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
- 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/facade/deployment_facade.py +3 -3
- claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
- claude_mpm/services/agents/loading/framework_agent_loader.py +8 -8
- claude_mpm/services/agents/local_template_manager.py +4 -2
- claude_mpm/services/agents/recommender.py +47 -0
- 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/cli/unified_dashboard_manager.py +1 -1
- claude_mpm/services/core/base.py +26 -11
- claude_mpm/services/core/interfaces.py +56 -1
- claude_mpm/services/core/models/agent_config.py +3 -0
- claude_mpm/services/core/models/process.py +4 -0
- claude_mpm/services/core/path_resolver.py +1 -1
- claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
- 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/monitor_check.py +0 -1
- claude_mpm/services/diagnostics/doctor_reporter.py +6 -4
- claude_mpm/services/diagnostics/models.py +21 -0
- claude_mpm/services/event_bus/README.md +244 -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/README.md +303 -0
- claude_mpm/services/events/consumers/logging.py +1 -2
- claude_mpm/services/framework_claude_md_generator/README.md +119 -0
- claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/local_ops/__init__.py +2 -0
- 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 +7 -131
- claude_mpm/services/mcp_gateway/README.md +185 -0
- 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 +19 -10
- 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/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 +1 -1
- 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/project/documentation_manager.py +2 -1
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +1 -0
- claude_mpm/services/self_upgrade_service.py +165 -7
- claude_mpm/services/session_manager.py +205 -1
- 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/connection.py.backup +217 -0
- claude_mpm/services/socketio/handlers/git.py +2 -2
- claude_mpm/services/socketio/handlers/hook.py.backup +154 -0
- claude_mpm/services/static/.gitkeep +2 -0
- 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/local.py +1 -1
- claude_mpm/services/version_control/VERSION +1 -0
- claude_mpm/services/version_control/conflict_resolution.py +6 -4
- claude_mpm/services/version_service.py +104 -1
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/__init__.py +21 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/.gitkeep +2 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -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/git-worktrees.md +317 -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/stacked-prs.md +251 -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/find-polluter.sh +63 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/main/artifacts-builder/LICENSE.txt +202 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/artifacts-builder/scripts/bundle-artifact.sh +54 -0
- claude_mpm/skills/bundled/main/artifacts-builder/scripts/init-artifact.sh +322 -0
- claude_mpm/skills/bundled/main/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- claude_mpm/skills/bundled/main/internal-comms/LICENSE.txt +202 -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/LICENSE.txt +202 -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/mcp-builder/scripts/example_evaluation.xml +22 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/requirements.txt +2 -0
- claude_mpm/skills/bundled/main/skill-creator/LICENSE.txt +202 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +573 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/react/flexlayout-react.md +742 -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/tauri/tauri-async-patterns.md +495 -0
- claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
- claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
- claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
- claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
- claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
- claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
- claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
- claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
- claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
- claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -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/example.ts +158 -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/test-quality-inspector/SKILL.md +458 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -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/LICENSE.txt +202 -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 +97 -9
- claude_mpm/skills/skills_registry.py +347 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/templates/questions/EXAMPLES.md +501 -0
- claude_mpm/templates/questions/__init__.py +43 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +314 -0
- claude_mpm/templates/questions/project_init.py +388 -0
- claude_mpm/templates/questions/ticket_mgmt.py +397 -0
- claude_mpm/tools/README_SOCKETIO_DEBUG.md +224 -0
- claude_mpm/tools/__main__.py +8 -8
- claude_mpm/tools/code_tree_analyzer/README.md +64 -0
- claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
- claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
- claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
- claude_mpm/tools/code_tree_analyzer/core.py +380 -0
- claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
- claude_mpm/tools/code_tree_analyzer/events.py +168 -0
- claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
- claude_mpm/tools/code_tree_analyzer/models.py +39 -0
- claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
- claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
- claude_mpm/utils/agent_dependency_loader.py +5 -5
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +241 -0
- claude_mpm/utils/log_cleanup.py +3 -3
- claude_mpm/utils/robust_installer.py +3 -5
- claude_mpm/utils/structured_questions.py +619 -0
- claude_mpm-4.25.10.dist-info/METADATA +789 -0
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/RECORD +485 -240
- claude_mpm/agents/INSTRUCTIONS_OLD_DEPRECATED.md +0 -602
- 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/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/cli/commands/mpm_init.py +0 -2008
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- 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/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/test-archive/test_debug.html +0 -25
- claude_mpm/tools/code_tree_analyzer.py +0 -1825
- claude_mpm-4.16.0.dist-info/METADATA +0 -453
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/WHEEL +0 -0
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.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
|
|
@@ -392,7 +392,7 @@ class UnifiedDashboardManager(IUnifiedDashboardManager):
|
|
|
392
392
|
port = self.find_available_port()
|
|
393
393
|
|
|
394
394
|
# Use force_restart to ensure we're using the latest code
|
|
395
|
-
success,
|
|
395
|
+
success, _browser_opened = self.start_dashboard(
|
|
396
396
|
port=port, background=True, open_browser=False, force_restart=force_restart
|
|
397
397
|
)
|
|
398
398
|
|
claude_mpm/services/core/base.py
CHANGED
|
@@ -9,6 +9,7 @@ and lifecycle management.
|
|
|
9
9
|
Part of TSK-0046: Service Layer Architecture Reorganization
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
|
+
import threading
|
|
12
13
|
from abc import ABC, abstractmethod
|
|
13
14
|
from typing import Any, Dict, Optional
|
|
14
15
|
|
|
@@ -221,29 +222,43 @@ class SingletonService(SyncBaseService):
|
|
|
221
222
|
"""
|
|
222
223
|
Base class for singleton services.
|
|
223
224
|
|
|
224
|
-
Ensures only one instance of the service exists.
|
|
225
|
+
Ensures only one instance of the service exists with thread-safe initialization.
|
|
226
|
+
Uses double-checked locking pattern to prevent race conditions.
|
|
225
227
|
"""
|
|
226
228
|
|
|
227
229
|
_instances: Dict[type, "SingletonService"] = {}
|
|
230
|
+
_lock = threading.Lock()
|
|
228
231
|
|
|
229
232
|
def __new__(cls, *args, **kwargs):
|
|
230
|
-
"""Ensure only one instance exists."""
|
|
233
|
+
"""Ensure only one instance exists with thread-safe initialization."""
|
|
234
|
+
# Fast path - check without lock
|
|
231
235
|
if cls not in cls._instances:
|
|
232
|
-
|
|
236
|
+
# Slow path - acquire lock and double-check
|
|
237
|
+
with cls._lock:
|
|
238
|
+
if cls not in cls._instances:
|
|
239
|
+
cls._instances[cls] = super().__new__(cls)
|
|
233
240
|
return cls._instances[cls]
|
|
234
241
|
|
|
235
242
|
@classmethod
|
|
236
243
|
def get_instance(cls) -> "SingletonService":
|
|
237
|
-
"""Get the singleton instance."""
|
|
244
|
+
"""Get the singleton instance with thread-safe initialization."""
|
|
245
|
+
# Fast path - check without lock
|
|
238
246
|
if cls not in cls._instances:
|
|
239
|
-
|
|
247
|
+
# Slow path - acquire lock and double-check
|
|
248
|
+
with cls._lock:
|
|
249
|
+
if cls not in cls._instances:
|
|
250
|
+
cls._instances[cls] = cls()
|
|
240
251
|
return cls._instances[cls]
|
|
241
252
|
|
|
242
253
|
@classmethod
|
|
243
254
|
def clear_instance(cls) -> None:
|
|
244
|
-
"""Clear the singleton instance (useful for testing).
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
255
|
+
"""Clear the singleton instance (useful for testing).
|
|
256
|
+
|
|
257
|
+
Thread-safe implementation ensures proper cleanup.
|
|
258
|
+
"""
|
|
259
|
+
with cls._lock:
|
|
260
|
+
if cls in cls._instances:
|
|
261
|
+
instance = cls._instances[cls]
|
|
262
|
+
if hasattr(instance, "shutdown") and not instance.is_shutdown:
|
|
263
|
+
instance.shutdown()
|
|
264
|
+
del cls._instances[cls]
|
|
@@ -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
|
|
@@ -19,6 +19,9 @@ from typing import Any, Dict, List, Optional
|
|
|
19
19
|
|
|
20
20
|
from ....core.enums import OperationResult, ValidationSeverity
|
|
21
21
|
|
|
22
|
+
# Backward compatibility alias (consolidated in Phase 3A Batch 25)
|
|
23
|
+
ConfigurationStatus = OperationResult
|
|
24
|
+
|
|
22
25
|
|
|
23
26
|
class AgentSpecialization(str, Enum):
|
|
24
27
|
"""Agent specialization categories.
|
|
@@ -25,6 +25,9 @@ from typing import Any, Dict, List, Optional
|
|
|
25
25
|
|
|
26
26
|
from claude_mpm.core.enums import ServiceState
|
|
27
27
|
|
|
28
|
+
# Backward compatibility alias (consolidated in Phase 3A Batch 24)
|
|
29
|
+
ProcessStatus = ServiceState
|
|
30
|
+
|
|
28
31
|
|
|
29
32
|
@dataclass
|
|
30
33
|
class DeploymentState:
|
|
@@ -230,6 +233,7 @@ __all__ = [
|
|
|
230
233
|
"PROTECTED_PORT_RANGES",
|
|
231
234
|
"DeploymentState",
|
|
232
235
|
"ProcessInfo",
|
|
236
|
+
"ProcessStatus", # Backward compatibility alias for ServiceState
|
|
233
237
|
"StartConfig",
|
|
234
238
|
"is_port_protected",
|
|
235
239
|
]
|
|
@@ -281,7 +281,7 @@ class PathResolver(IPathResolver):
|
|
|
281
281
|
|
|
282
282
|
if agents_dir and agents_dir.exists():
|
|
283
283
|
discovered_agents_dir = agents_dir
|
|
284
|
-
self.logger.
|
|
284
|
+
self.logger.debug(f"Using custom agents directory: {discovered_agents_dir}")
|
|
285
285
|
elif framework_path and framework_path != Path("__PACKAGED__"):
|
|
286
286
|
# Prioritize templates directory over main agents directory
|
|
287
287
|
templates_dir = (
|
|
@@ -188,7 +188,6 @@ class AgentCheck(BaseDiagnosticCheck):
|
|
|
188
188
|
def _check_agent_versions(self) -> DiagnosticResult:
|
|
189
189
|
"""Check if deployed agents are up-to-date."""
|
|
190
190
|
try:
|
|
191
|
-
|
|
192
191
|
from ....services.agents.deployment.agent_version_manager import (
|
|
193
192
|
AgentVersionManager,
|
|
194
193
|
)
|
|
@@ -258,7 +257,6 @@ class AgentCheck(BaseDiagnosticCheck):
|
|
|
258
257
|
def _validate_agents(self) -> DiagnosticResult:
|
|
259
258
|
"""Validate agent configurations."""
|
|
260
259
|
try:
|
|
261
|
-
|
|
262
260
|
from ....services.agents.deployment.agent_validator import AgentValidator
|
|
263
261
|
|
|
264
262
|
AgentValidator()
|
|
@@ -220,8 +220,7 @@ class InstructionsCheck(BaseDiagnosticCheck):
|
|
|
220
220
|
files_str = ", ".join(str(path) for path, _ in occurrences)
|
|
221
221
|
snippet = occurrences[0][1]
|
|
222
222
|
duplicates.append(
|
|
223
|
-
f"Duplicate content found in: {files_str}\n"
|
|
224
|
-
f" Snippet: {snippet}..."
|
|
223
|
+
f"Duplicate content found in: {files_str}\n Snippet: {snippet}..."
|
|
225
224
|
)
|
|
226
225
|
|
|
227
226
|
if duplicates:
|
|
@@ -271,15 +271,17 @@ class DoctorReporter:
|
|
|
271
271
|
+ summary.skipped_count
|
|
272
272
|
)
|
|
273
273
|
if total > 0:
|
|
274
|
-
print(f"| ✅ OK | {summary.ok_count} | {summary.ok_count*100//total}% |")
|
|
275
274
|
print(
|
|
276
|
-
f"|
|
|
275
|
+
f"| ✅ OK | {summary.ok_count} | {summary.ok_count * 100 // total}% |"
|
|
277
276
|
)
|
|
278
277
|
print(
|
|
279
|
-
f"|
|
|
278
|
+
f"| ⚠️ Warning | {summary.warning_count} | {summary.warning_count * 100 // total}% |"
|
|
280
279
|
)
|
|
281
280
|
print(
|
|
282
|
-
f"|
|
|
281
|
+
f"| ❌ Error | {summary.error_count} | {summary.error_count * 100 // total}% |"
|
|
282
|
+
)
|
|
283
|
+
print(
|
|
284
|
+
f"| ⏭️ Skipped | {summary.skipped_count} | {summary.skipped_count * 100 // total}% |"
|
|
283
285
|
)
|
|
284
286
|
print()
|
|
285
287
|
|
|
@@ -6,11 +6,32 @@ consistency across all checks and reporting.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
from dataclasses import dataclass, field
|
|
9
|
+
from enum import Enum
|
|
9
10
|
from typing import Any, Dict, List, Optional, Union
|
|
10
11
|
|
|
11
12
|
from ...core.enums import OperationResult, ValidationSeverity
|
|
12
13
|
|
|
13
14
|
|
|
15
|
+
class DiagnosticStatus(str, Enum):
|
|
16
|
+
"""Backward compatibility wrapper for diagnostic status values.
|
|
17
|
+
|
|
18
|
+
WHY: Provides backward compatibility for tests and code that use
|
|
19
|
+
DiagnosticStatus instead of the consolidated OperationResult/ValidationSeverity.
|
|
20
|
+
|
|
21
|
+
DESIGN DECISION: Maps to the appropriate consolidated enum values:
|
|
22
|
+
- OK → OperationResult.SUCCESS
|
|
23
|
+
- WARNING → ValidationSeverity.WARNING
|
|
24
|
+
- ERROR → ValidationSeverity.ERROR
|
|
25
|
+
|
|
26
|
+
Note: This is a compatibility layer. New code should use OperationResult
|
|
27
|
+
and ValidationSeverity directly.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
OK = "success" # Maps to OperationResult.SUCCESS
|
|
31
|
+
WARNING = "warning" # Maps to ValidationSeverity.WARNING
|
|
32
|
+
ERROR = "error" # Maps to ValidationSeverity.ERROR
|
|
33
|
+
|
|
34
|
+
|
|
14
35
|
@dataclass
|
|
15
36
|
class DiagnosticResult:
|
|
16
37
|
"""Result from a diagnostic check.
|