claude-mpm 5.0.9__py3-none-any.whl → 5.6.23__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/__init__.py +4 -0
- claude_mpm/agents/BASE_AGENT.md +164 -0
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +115 -0
- claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +186 -0
- claude_mpm/agents/MEMORY.md +1 -1
- claude_mpm/agents/PM_INSTRUCTIONS.md +479 -616
- claude_mpm/agents/WORKFLOW.md +6 -253
- claude_mpm/agents/agent_loader.py +13 -44
- claude_mpm/agents/base_agent.json +1 -1
- claude_mpm/agents/frontmatter_validator.py +70 -2
- claude_mpm/agents/templates/circuit-breakers.md +457 -62
- claude_mpm/cli/__init__.py +5 -2
- claude_mpm/cli/__main__.py +4 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/agent_state_manager.py +18 -27
- claude_mpm/cli/commands/agents.py +177 -41
- claude_mpm/cli/commands/agents_reconcile.py +197 -0
- claude_mpm/cli/commands/auto_configure.py +723 -236
- claude_mpm/cli/commands/autotodos.py +566 -0
- claude_mpm/cli/commands/commander.py +216 -0
- claude_mpm/cli/commands/config.py +88 -2
- claude_mpm/cli/commands/configure.py +1874 -170
- claude_mpm/cli/commands/configure_agent_display.py +27 -6
- claude_mpm/cli/commands/hook_errors.py +60 -60
- claude_mpm/cli/commands/monitor.py +2 -2
- claude_mpm/cli/commands/mpm_init/core.py +232 -46
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +280 -0
- claude_mpm/cli/commands/postmortem.py +1 -1
- claude_mpm/cli/commands/profile.py +276 -0
- claude_mpm/cli/commands/run.py +35 -3
- claude_mpm/cli/commands/skill_source.py +51 -2
- claude_mpm/cli/commands/skills.py +379 -204
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/executor.py +141 -19
- claude_mpm/cli/interactive/__init__.py +10 -0
- claude_mpm/cli/interactive/agent_wizard.py +115 -60
- claude_mpm/cli/interactive/questionary_styles.py +65 -0
- claude_mpm/cli/interactive/skill_selector.py +481 -0
- claude_mpm/cli/parsers/agents_parser.py +54 -9
- claude_mpm/cli/parsers/auto_configure_parser.py +13 -138
- claude_mpm/cli/parsers/base_parser.py +88 -1
- claude_mpm/cli/parsers/commander_parser.py +116 -0
- claude_mpm/cli/parsers/config_parser.py +153 -83
- claude_mpm/cli/parsers/profile_parser.py +147 -0
- claude_mpm/cli/parsers/run_parser.py +10 -0
- claude_mpm/cli/parsers/skill_source_parser.py +4 -0
- claude_mpm/cli/parsers/skills_parser.py +1 -1
- claude_mpm/cli/startup.py +1017 -266
- claude_mpm/cli/startup_display.py +74 -6
- claude_mpm/cli/startup_logging.py +2 -2
- claude_mpm/cli/utils.py +7 -3
- claude_mpm/commander/__init__.py +78 -0
- claude_mpm/commander/adapters/__init__.py +60 -0
- claude_mpm/commander/adapters/auggie.py +260 -0
- claude_mpm/commander/adapters/base.py +288 -0
- claude_mpm/commander/adapters/claude_code.py +392 -0
- claude_mpm/commander/adapters/codex.py +237 -0
- claude_mpm/commander/adapters/communication.py +366 -0
- claude_mpm/commander/adapters/example_usage.py +310 -0
- claude_mpm/commander/adapters/mpm.py +389 -0
- claude_mpm/commander/adapters/registry.py +204 -0
- claude_mpm/commander/api/__init__.py +16 -0
- claude_mpm/commander/api/app.py +121 -0
- claude_mpm/commander/api/errors.py +133 -0
- claude_mpm/commander/api/routes/__init__.py +8 -0
- claude_mpm/commander/api/routes/events.py +184 -0
- claude_mpm/commander/api/routes/inbox.py +171 -0
- claude_mpm/commander/api/routes/messages.py +148 -0
- claude_mpm/commander/api/routes/projects.py +271 -0
- claude_mpm/commander/api/routes/sessions.py +226 -0
- claude_mpm/commander/api/routes/work.py +296 -0
- claude_mpm/commander/api/schemas.py +186 -0
- claude_mpm/commander/chat/__init__.py +7 -0
- claude_mpm/commander/chat/cli.py +146 -0
- claude_mpm/commander/chat/commands.py +96 -0
- claude_mpm/commander/chat/repl.py +310 -0
- claude_mpm/commander/config.py +51 -0
- claude_mpm/commander/config_loader.py +115 -0
- claude_mpm/commander/core/__init__.py +10 -0
- claude_mpm/commander/core/block_manager.py +325 -0
- claude_mpm/commander/core/response_manager.py +323 -0
- claude_mpm/commander/daemon.py +603 -0
- claude_mpm/commander/env_loader.py +59 -0
- claude_mpm/commander/events/__init__.py +26 -0
- claude_mpm/commander/events/manager.py +332 -0
- claude_mpm/commander/frameworks/__init__.py +12 -0
- claude_mpm/commander/frameworks/base.py +146 -0
- claude_mpm/commander/frameworks/claude_code.py +58 -0
- claude_mpm/commander/frameworks/mpm.py +62 -0
- claude_mpm/commander/inbox/__init__.py +16 -0
- claude_mpm/commander/inbox/dedup.py +128 -0
- claude_mpm/commander/inbox/inbox.py +224 -0
- claude_mpm/commander/inbox/models.py +70 -0
- claude_mpm/commander/instance_manager.py +450 -0
- claude_mpm/commander/llm/__init__.py +6 -0
- claude_mpm/commander/llm/openrouter_client.py +167 -0
- claude_mpm/commander/llm/summarizer.py +70 -0
- claude_mpm/commander/memory/__init__.py +45 -0
- claude_mpm/commander/memory/compression.py +347 -0
- claude_mpm/commander/memory/embeddings.py +230 -0
- claude_mpm/commander/memory/entities.py +310 -0
- claude_mpm/commander/memory/example_usage.py +290 -0
- claude_mpm/commander/memory/integration.py +325 -0
- claude_mpm/commander/memory/search.py +381 -0
- claude_mpm/commander/memory/store.py +657 -0
- claude_mpm/commander/models/__init__.py +18 -0
- claude_mpm/commander/models/events.py +121 -0
- claude_mpm/commander/models/project.py +162 -0
- claude_mpm/commander/models/work.py +214 -0
- claude_mpm/commander/parsing/__init__.py +20 -0
- claude_mpm/commander/parsing/extractor.py +132 -0
- claude_mpm/commander/parsing/output_parser.py +270 -0
- claude_mpm/commander/parsing/patterns.py +100 -0
- claude_mpm/commander/persistence/__init__.py +11 -0
- claude_mpm/commander/persistence/event_store.py +274 -0
- claude_mpm/commander/persistence/state_store.py +309 -0
- claude_mpm/commander/persistence/work_store.py +164 -0
- claude_mpm/commander/polling/__init__.py +13 -0
- claude_mpm/commander/polling/event_detector.py +104 -0
- claude_mpm/commander/polling/output_buffer.py +49 -0
- claude_mpm/commander/polling/output_poller.py +153 -0
- claude_mpm/commander/project_session.py +268 -0
- claude_mpm/commander/proxy/__init__.py +12 -0
- claude_mpm/commander/proxy/formatter.py +89 -0
- claude_mpm/commander/proxy/output_handler.py +191 -0
- claude_mpm/commander/proxy/relay.py +155 -0
- claude_mpm/commander/registry.py +410 -0
- claude_mpm/commander/runtime/__init__.py +10 -0
- claude_mpm/commander/runtime/executor.py +191 -0
- claude_mpm/commander/runtime/monitor.py +346 -0
- claude_mpm/commander/session/__init__.py +6 -0
- claude_mpm/commander/session/context.py +81 -0
- claude_mpm/commander/session/manager.py +59 -0
- claude_mpm/commander/tmux_orchestrator.py +361 -0
- claude_mpm/commander/web/__init__.py +1 -0
- claude_mpm/commander/work/__init__.py +30 -0
- claude_mpm/commander/work/executor.py +207 -0
- claude_mpm/commander/work/queue.py +405 -0
- claude_mpm/commander/workflow/__init__.py +27 -0
- claude_mpm/commander/workflow/event_handler.py +241 -0
- claude_mpm/commander/workflow/notifier.py +146 -0
- claude_mpm/commands/mpm-config.md +36 -0
- claude_mpm/commands/mpm-doctor.md +16 -21
- claude_mpm/commands/mpm-help.md +12 -286
- claude_mpm/commands/mpm-init.md +88 -506
- claude_mpm/commands/mpm-monitor.md +22 -401
- claude_mpm/commands/mpm-organize.md +128 -0
- claude_mpm/commands/mpm-postmortem.md +13 -107
- claude_mpm/commands/mpm-session-resume.md +20 -363
- claude_mpm/commands/mpm-status.md +13 -69
- claude_mpm/commands/mpm-ticket-view.md +60 -495
- claude_mpm/commands/mpm-version.md +13 -107
- claude_mpm/commands/mpm.md +8 -0
- claude_mpm/config/agent_presets.py +8 -7
- claude_mpm/config/agent_sources.py +27 -0
- claude_mpm/config/skill_sources.py +16 -0
- claude_mpm/constants.py +1 -0
- claude_mpm/core/claude_runner.py +154 -2
- claude_mpm/core/config.py +37 -26
- claude_mpm/core/config_constants.py +74 -9
- claude_mpm/core/constants.py +56 -12
- claude_mpm/core/framework/formatters/content_formatter.py +3 -13
- claude_mpm/core/framework/loaders/agent_loader.py +8 -5
- claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
- claude_mpm/core/framework_loader.py +4 -2
- claude_mpm/core/hook_manager.py +51 -3
- claude_mpm/core/interactive_session.py +12 -11
- claude_mpm/core/logger.py +39 -9
- claude_mpm/core/logging_utils.py +35 -11
- claude_mpm/core/network_config.py +148 -0
- claude_mpm/core/oneshot_session.py +7 -6
- claude_mpm/core/optimized_startup.py +61 -0
- claude_mpm/core/output_style_manager.py +219 -44
- claude_mpm/core/shared/config_loader.py +3 -1
- claude_mpm/core/socketio_pool.py +16 -8
- claude_mpm/core/unified_agent_registry.py +134 -16
- claude_mpm/core/unified_config.py +76 -8
- claude_mpm/core/unified_paths.py +95 -90
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DR8nis88.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.RgBboRvH.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
- claude_mpm/experimental/cli_enhancements.py +2 -1
- claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
- claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
- claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +479 -128
- claude_mpm/hooks/claude_hooks/hook_handler.py +254 -83
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
- claude_mpm/hooks/claude_hooks/installer.py +149 -18
- claude_mpm/hooks/claude_hooks/memory_integration.py +67 -19
- claude_mpm/hooks/claude_hooks/response_tracking.py +44 -62
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +69 -30
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +36 -103
- claude_mpm/hooks/claude_hooks/services/state_manager.py +23 -36
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +73 -75
- claude_mpm/hooks/kuzu_memory_hook.py +5 -5
- claude_mpm/hooks/memory_integration_hook.py +46 -1
- claude_mpm/hooks/session_resume_hook.py +89 -1
- claude_mpm/hooks/templates/pre_tool_use_template.py +10 -2
- claude_mpm/init.py +276 -19
- claude_mpm/models/agent_definition.py +7 -0
- claude_mpm/models/git_repository.py +3 -3
- claude_mpm/scripts/claude-hook-handler.sh +87 -20
- claude_mpm/scripts/launch_monitor.py +93 -13
- claude_mpm/scripts/start_activity_logging.py +0 -0
- claude_mpm/services/agents/agent_builder.py +3 -3
- claude_mpm/services/agents/agent_recommendation_service.py +278 -0
- claude_mpm/services/agents/agent_review_service.py +280 -0
- claude_mpm/services/agents/agent_selection_service.py +2 -2
- claude_mpm/services/agents/cache_git_manager.py +7 -7
- claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
- claude_mpm/services/agents/deployment/agent_discovery_service.py +6 -5
- claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
- claude_mpm/services/agents/deployment/agent_template_builder.py +42 -20
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
- claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
- claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
- claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +348 -29
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +570 -68
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/git_source_manager.py +57 -4
- claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
- claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
- claude_mpm/services/agents/recommender.py +5 -3
- claude_mpm/services/agents/single_tier_deployment_service.py +6 -6
- claude_mpm/services/agents/sources/git_source_sync_service.py +129 -11
- claude_mpm/services/agents/startup_sync.py +27 -4
- claude_mpm/services/agents/toolchain_detector.py +10 -6
- claude_mpm/services/analysis/__init__.py +11 -1
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- claude_mpm/services/cli/__init__.py +3 -0
- claude_mpm/services/cli/incremental_pause_manager.py +561 -0
- claude_mpm/services/cli/session_resume_helper.py +10 -2
- claude_mpm/services/command_deployment_service.py +81 -10
- claude_mpm/services/delegation_detector.py +175 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +31 -1
- claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
- claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
- claude_mpm/services/diagnostics/models.py +14 -1
- claude_mpm/services/event_bus/config.py +3 -1
- claude_mpm/services/event_log.py +325 -0
- claude_mpm/services/git/git_operations_service.py +101 -16
- claude_mpm/services/infrastructure/__init__.py +4 -0
- claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
- claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
- claude_mpm/services/monitor/daemon.py +9 -2
- claude_mpm/services/monitor/daemon_manager.py +54 -7
- claude_mpm/services/monitor/management/lifecycle.py +15 -3
- claude_mpm/services/monitor/server.py +796 -30
- claude_mpm/services/pm_skills_deployer.py +884 -0
- claude_mpm/services/profile_manager.py +337 -0
- claude_mpm/services/project/project_organizer.py +4 -0
- claude_mpm/services/self_upgrade_service.py +120 -12
- claude_mpm/services/skills/__init__.py +3 -0
- claude_mpm/services/skills/git_skill_source_manager.py +303 -12
- claude_mpm/services/skills/selective_skill_deployer.py +869 -0
- claude_mpm/services/skills/skill_discovery_service.py +74 -4
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_deployer.py +294 -55
- claude_mpm/services/socketio/dashboard_server.py +1 -0
- claude_mpm/services/socketio/event_normalizer.py +51 -6
- claude_mpm/services/socketio/handlers/hook.py +14 -7
- claude_mpm/services/socketio/server/core.py +386 -108
- claude_mpm/services/socketio/server/main.py +12 -4
- claude_mpm/services/version_control/git_operations.py +103 -0
- claude_mpm/skills/__init__.py +2 -1
- 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/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/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/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/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/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/pm/mpm/SKILL.md +38 -0
- claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
- claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
- claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
- claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
- claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
- claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
- claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
- claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
- claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
- claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
- claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
- claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
- claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
- claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
- claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
- claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
- claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
- claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
- claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
- claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
- claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
- claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
- claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
- claude_mpm/skills/bundled/react/flexlayout-react.md +742 -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 +112 -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/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/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/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -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/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/skills/registry.py +295 -90
- claude_mpm/skills/skill_manager.py +98 -3
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/utils/agent_dependency_loader.py +115 -4
- claude_mpm/utils/agent_filters.py +17 -44
- claude_mpm/utils/gitignore.py +3 -0
- claude_mpm/utils/migration.py +4 -4
- claude_mpm/utils/robust_installer.py +86 -21
- claude_mpm-5.6.23.dist-info/METADATA +393 -0
- {claude_mpm-5.0.9.dist-info → claude_mpm-5.6.23.dist-info}/RECORD +508 -261
- claude_mpm-5.6.23.dist-info/entry_points.txt +5 -0
- claude_mpm-5.6.23.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.6.23.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
- claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
- claude_mpm/agents/BASE_OPS.md +0 -219
- claude_mpm/agents/BASE_PM.md +0 -480
- claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
- claude_mpm/agents/BASE_QA.md +0 -167
- claude_mpm/agents/BASE_RESEARCH.md +0 -53
- claude_mpm/agents/OUTPUT_STYLE.md +0 -290
- claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +0 -1322
- claude_mpm/agents/base_agent_loader.py +0 -601
- claude_mpm/cli/commands/agents_detect.py +0 -380
- claude_mpm/cli/commands/agents_recommend.py +0 -309
- claude_mpm/cli/ticket_cli.py +0 -35
- claude_mpm/commands/mpm-agents-auto-configure.md +0 -278
- claude_mpm/commands/mpm-agents-detect.md +0 -177
- claude_mpm/commands/mpm-agents-list.md +0 -131
- claude_mpm/commands/mpm-agents-recommend.md +0 -223
- claude_mpm/commands/mpm-config-view.md +0 -150
- claude_mpm/commands/mpm-ticket-organize.md +0 -304
- claude_mpm/dashboard/analysis_runner.py +0 -455
- claude_mpm/dashboard/index.html +0 -13
- claude_mpm/dashboard/open_dashboard.py +0 -66
- claude_mpm/dashboard/static/css/activity.css +0 -1958
- claude_mpm/dashboard/static/css/connection-status.css +0 -370
- claude_mpm/dashboard/static/css/dashboard.css +0 -4701
- claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
- claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
- claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
- claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
- claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
- claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
- claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
- claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
- claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
- claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
- claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
- claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
- claude_mpm/dashboard/static/js/connection-manager.js +0 -536
- claude_mpm/dashboard/static/js/dashboard.js +0 -1914
- claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/js/socket-client.js +0 -1474
- claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/socket.io.min.js +0 -7
- claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
- claude_mpm/dashboard/templates/code_simple.html +0 -153
- claude_mpm/dashboard/templates/index.html +0 -606
- claude_mpm/dashboard/test_dashboard.html +0 -372
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
- claude_mpm/scripts/mcp_server.py +0 -75
- claude_mpm/scripts/mcp_wrapper.py +0 -39
- claude_mpm/services/mcp_gateway/__init__.py +0 -159
- claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
- claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
- claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
- claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
- claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
- claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
- claude_mpm/services/mcp_gateway/core/base.py +0 -312
- claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
- claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
- claude_mpm/services/mcp_gateway/core/process_pool.py +0 -977
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
- claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
- claude_mpm/services/mcp_gateway/main.py +0 -589
- claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
- claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
- claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -414
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -712
- claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
- claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -555
- claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
- claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
- claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
- claude_mpm-5.0.9.dist-info/METADATA +0 -1028
- claude_mpm-5.0.9.dist-info/entry_points.txt +0 -10
- claude_mpm-5.0.9.dist-info/licenses/LICENSE +0 -21
- {claude_mpm-5.0.9.dist-info → claude_mpm-5.6.23.dist-info}/WHEEL +0 -0
- {claude_mpm-5.0.9.dist-info → claude_mpm-5.6.23.dist-info}/top_level.txt +0 -0
|
@@ -5,6 +5,7 @@ Services specifically for CLI command support and utilities.
|
|
|
5
5
|
|
|
6
6
|
from .agent_dependency_service import AgentDependencyService, IAgentDependencyService
|
|
7
7
|
from .agent_validation_service import AgentValidationService, IAgentValidationService
|
|
8
|
+
from .incremental_pause_manager import IncrementalPauseManager, PauseAction
|
|
8
9
|
from .startup_checker import IStartupChecker, StartupCheckerService, StartupWarning
|
|
9
10
|
|
|
10
11
|
__all__ = [
|
|
@@ -13,6 +14,8 @@ __all__ = [
|
|
|
13
14
|
"IAgentDependencyService",
|
|
14
15
|
"IAgentValidationService",
|
|
15
16
|
"IStartupChecker",
|
|
17
|
+
"IncrementalPauseManager",
|
|
18
|
+
"PauseAction",
|
|
16
19
|
"StartupCheckerService",
|
|
17
20
|
"StartupWarning",
|
|
18
21
|
]
|
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
"""Incremental Pause Manager Service.
|
|
2
|
+
|
|
3
|
+
WHY: Captures actions incrementally after auto-pause threshold (90%) is crossed to
|
|
4
|
+
record the "wind-down" period before session ends. Uses append-only JSONL format
|
|
5
|
+
for efficient incremental capture with crash safety.
|
|
6
|
+
|
|
7
|
+
DESIGN DECISIONS:
|
|
8
|
+
- JSONL format for append-only writes (one action per line)
|
|
9
|
+
- Atomic appends using file locking for concurrent safety
|
|
10
|
+
- Delegates to SessionPauseManager for final snapshot generation
|
|
11
|
+
- Tracks pause lifecycle: start -> append actions -> finalize/discard
|
|
12
|
+
- Session ID matches pattern from SessionPauseManager for consistency
|
|
13
|
+
|
|
14
|
+
USAGE:
|
|
15
|
+
manager = IncrementalPauseManager()
|
|
16
|
+
|
|
17
|
+
# Start incremental pause at 90% threshold
|
|
18
|
+
session_id = manager.start_incremental_pause(
|
|
19
|
+
context_percentage=0.90,
|
|
20
|
+
initial_state=tracker.get_current_state().__dict__
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
# Record actions during wind-down
|
|
24
|
+
manager.append_action(
|
|
25
|
+
action_type="tool_call",
|
|
26
|
+
action_data={"tool": "Read", "path": "/some/file.py"},
|
|
27
|
+
context_percentage=0.92
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Finalize when session ends
|
|
31
|
+
final_path = manager.finalize_pause()
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
import json
|
|
35
|
+
from dataclasses import asdict, dataclass
|
|
36
|
+
from datetime import datetime, timezone
|
|
37
|
+
from pathlib import Path
|
|
38
|
+
from typing import Any, Dict, List, Optional
|
|
39
|
+
|
|
40
|
+
from claude_mpm.core.logger import get_logger
|
|
41
|
+
from claude_mpm.services.cli.session_pause_manager import SessionPauseManager
|
|
42
|
+
|
|
43
|
+
logger = get_logger(__name__)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class PauseAction:
|
|
48
|
+
"""Single action recorded during incremental pause.
|
|
49
|
+
|
|
50
|
+
Attributes:
|
|
51
|
+
type: Action type ('tool_call', 'assistant_response', 'user_message',
|
|
52
|
+
'system_event', 'pause_started', 'pause_finalized')
|
|
53
|
+
timestamp: ISO format timestamp
|
|
54
|
+
session_id: Unique session identifier
|
|
55
|
+
data: Action-specific data dictionary
|
|
56
|
+
context_percentage: Context usage when action recorded (0.0-1.0)
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
type: str
|
|
60
|
+
timestamp: str
|
|
61
|
+
session_id: str
|
|
62
|
+
data: Dict[str, Any]
|
|
63
|
+
context_percentage: float
|
|
64
|
+
|
|
65
|
+
def to_json_line(self) -> str:
|
|
66
|
+
"""Convert to JSON line for JSONL format.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
JSON string with newline appended
|
|
70
|
+
"""
|
|
71
|
+
return json.dumps(asdict(self), ensure_ascii=False, default=str) + "\n"
|
|
72
|
+
|
|
73
|
+
@classmethod
|
|
74
|
+
def from_json_line(cls, line: str) -> "PauseAction":
|
|
75
|
+
"""Parse from JSON line.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
line: JSON string (with or without newline)
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
PauseAction instance
|
|
82
|
+
|
|
83
|
+
Raises:
|
|
84
|
+
json.JSONDecodeError: If line is not valid JSON
|
|
85
|
+
ValueError: If required fields are missing
|
|
86
|
+
"""
|
|
87
|
+
data = json.loads(line.strip())
|
|
88
|
+
return cls(**data)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class IncrementalPauseManager:
|
|
92
|
+
"""Manages incremental capture of actions during auto-pause wind-down.
|
|
93
|
+
|
|
94
|
+
Features:
|
|
95
|
+
- Append-only JSONL file for efficient incremental writes
|
|
96
|
+
- Atomic file operations with file locking
|
|
97
|
+
- Session lifecycle tracking (start -> append -> finalize/discard)
|
|
98
|
+
- Integration with SessionPauseManager for final snapshots
|
|
99
|
+
- Crash-safe recording (each action appended atomically)
|
|
100
|
+
|
|
101
|
+
The incremental pause captures the "tail" of a session after the 90%
|
|
102
|
+
threshold is crossed, allowing us to record final actions before the
|
|
103
|
+
user decides to pause or continue.
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
ACTIVE_PAUSE_FILE = "ACTIVE-PAUSE.jsonl"
|
|
107
|
+
|
|
108
|
+
def __init__(self, project_path: Optional[Path] = None):
|
|
109
|
+
"""Initialize incremental pause manager.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
project_path: Project root path (default: current directory)
|
|
113
|
+
"""
|
|
114
|
+
self.project_path = (project_path or Path.cwd()).resolve()
|
|
115
|
+
self.sessions_dir = self.project_path / ".claude-mpm" / "sessions"
|
|
116
|
+
self.sessions_dir.mkdir(parents=True, exist_ok=True)
|
|
117
|
+
self.active_pause_path = self.sessions_dir / self.ACTIVE_PAUSE_FILE
|
|
118
|
+
|
|
119
|
+
logger.debug(f"IncrementalPauseManager initialized: {self.active_pause_path}")
|
|
120
|
+
|
|
121
|
+
def is_pause_active(self) -> bool:
|
|
122
|
+
"""Check if there's an active incremental pause in progress.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
True if ACTIVE-PAUSE.jsonl exists
|
|
126
|
+
"""
|
|
127
|
+
return self.active_pause_path.exists()
|
|
128
|
+
|
|
129
|
+
def start_incremental_pause(
|
|
130
|
+
self, context_percentage: float, initial_state: Dict[str, Any]
|
|
131
|
+
) -> str:
|
|
132
|
+
"""Start a new incremental pause session.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
context_percentage: Current context usage (e.g., 0.90 for 90%)
|
|
136
|
+
initial_state: Initial context snapshot (from ContextUsageTracker)
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
session_id: Unique identifier for this pause session
|
|
140
|
+
|
|
141
|
+
Raises:
|
|
142
|
+
RuntimeError: If pause is already active
|
|
143
|
+
"""
|
|
144
|
+
if self.is_pause_active():
|
|
145
|
+
logger.warning("Incremental pause already active, cannot start new pause")
|
|
146
|
+
raise RuntimeError(
|
|
147
|
+
"An incremental pause is already active. "
|
|
148
|
+
"Call finalize_pause() or discard_pause() first."
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# Generate session ID matching SessionPauseManager pattern
|
|
152
|
+
session_id = f"session-{datetime.now(timezone.utc).strftime('%Y%m%d-%H%M%S')}"
|
|
153
|
+
|
|
154
|
+
# Create initial pause_started action
|
|
155
|
+
start_action = PauseAction(
|
|
156
|
+
type="pause_started",
|
|
157
|
+
timestamp=datetime.now(timezone.utc).isoformat(),
|
|
158
|
+
session_id=session_id,
|
|
159
|
+
data={
|
|
160
|
+
"context_percentage": context_percentage,
|
|
161
|
+
"initial_state": initial_state,
|
|
162
|
+
"reason": "Auto-pause threshold exceeded (90%+)",
|
|
163
|
+
},
|
|
164
|
+
context_percentage=context_percentage,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
# Write initial action to file
|
|
168
|
+
try:
|
|
169
|
+
with self.active_pause_path.open("w") as f:
|
|
170
|
+
f.write(start_action.to_json_line())
|
|
171
|
+
|
|
172
|
+
logger.info(
|
|
173
|
+
f"Incremental pause started: {session_id} "
|
|
174
|
+
f"(context: {context_percentage:.1%})"
|
|
175
|
+
)
|
|
176
|
+
return session_id
|
|
177
|
+
|
|
178
|
+
except Exception as e:
|
|
179
|
+
logger.error(f"Failed to start incremental pause: {e}")
|
|
180
|
+
# Clean up partial file if created
|
|
181
|
+
if self.active_pause_path.exists():
|
|
182
|
+
self.active_pause_path.unlink()
|
|
183
|
+
raise RuntimeError(f"Failed to start incremental pause: {e}") from e
|
|
184
|
+
|
|
185
|
+
def append_action(
|
|
186
|
+
self, action_type: str, action_data: Dict[str, Any], context_percentage: float
|
|
187
|
+
) -> None:
|
|
188
|
+
"""Append an action to the active pause file.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
action_type: Type of action ('tool_call', 'assistant_response',
|
|
192
|
+
'user_message', 'system_event')
|
|
193
|
+
action_data: Action-specific data to record
|
|
194
|
+
context_percentage: Current context usage (0.0-1.0)
|
|
195
|
+
|
|
196
|
+
Raises:
|
|
197
|
+
RuntimeError: If no active pause session exists
|
|
198
|
+
"""
|
|
199
|
+
if not self.is_pause_active():
|
|
200
|
+
logger.warning(
|
|
201
|
+
f"Cannot append action '{action_type}': no active pause session"
|
|
202
|
+
)
|
|
203
|
+
raise RuntimeError(
|
|
204
|
+
"No active pause session. Call start_incremental_pause() first."
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
# Get session ID from first line
|
|
208
|
+
try:
|
|
209
|
+
session_id = self._get_session_id()
|
|
210
|
+
|
|
211
|
+
action = PauseAction(
|
|
212
|
+
type=action_type,
|
|
213
|
+
timestamp=datetime.now(timezone.utc).isoformat(),
|
|
214
|
+
session_id=session_id,
|
|
215
|
+
data=action_data,
|
|
216
|
+
context_percentage=context_percentage,
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
# Append to file atomically
|
|
220
|
+
with self.active_pause_path.open("a") as f:
|
|
221
|
+
f.write(action.to_json_line())
|
|
222
|
+
f.flush() # Ensure data is written to disk
|
|
223
|
+
|
|
224
|
+
logger.debug(
|
|
225
|
+
f"Appended action '{action_type}' to pause session "
|
|
226
|
+
f"(context: {context_percentage:.1%})"
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
except Exception as e:
|
|
230
|
+
logger.error(f"Failed to append action to pause session: {e}")
|
|
231
|
+
raise RuntimeError(f"Failed to append action: {e}") from e
|
|
232
|
+
|
|
233
|
+
def get_recorded_actions(self) -> List[PauseAction]:
|
|
234
|
+
"""Read all actions from the current pause session.
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
List of PauseAction objects in chronological order
|
|
238
|
+
|
|
239
|
+
Raises:
|
|
240
|
+
RuntimeError: If no active pause session exists
|
|
241
|
+
"""
|
|
242
|
+
if not self.is_pause_active():
|
|
243
|
+
raise RuntimeError("No active pause session")
|
|
244
|
+
|
|
245
|
+
try:
|
|
246
|
+
actions = []
|
|
247
|
+
with self.active_pause_path.open("r") as f:
|
|
248
|
+
for line in f:
|
|
249
|
+
if line.strip():
|
|
250
|
+
actions.append(PauseAction.from_json_line(line))
|
|
251
|
+
|
|
252
|
+
logger.debug(f"Read {len(actions)} actions from pause session")
|
|
253
|
+
return actions
|
|
254
|
+
|
|
255
|
+
except Exception as e:
|
|
256
|
+
logger.error(f"Failed to read recorded actions: {e}")
|
|
257
|
+
raise RuntimeError(f"Failed to read actions: {e}") from e
|
|
258
|
+
|
|
259
|
+
def finalize_pause(self, create_full_snapshot: bool = True) -> Optional[Path]:
|
|
260
|
+
"""Finalize the incremental pause into a complete session snapshot.
|
|
261
|
+
|
|
262
|
+
This method:
|
|
263
|
+
1. Appends a 'pause_finalized' action
|
|
264
|
+
2. Optionally delegates to SessionPauseManager to create JSON/YAML/MD files
|
|
265
|
+
3. Removes the ACTIVE-PAUSE.jsonl file
|
|
266
|
+
4. Returns path to the finalized session file
|
|
267
|
+
|
|
268
|
+
Args:
|
|
269
|
+
create_full_snapshot: If True, use SessionPauseManager to create
|
|
270
|
+
complete session files
|
|
271
|
+
|
|
272
|
+
Returns:
|
|
273
|
+
Path to the finalized session file, or None if no active pause
|
|
274
|
+
|
|
275
|
+
Raises:
|
|
276
|
+
RuntimeError: If finalization fails
|
|
277
|
+
"""
|
|
278
|
+
if not self.is_pause_active():
|
|
279
|
+
logger.warning("No active pause session to finalize")
|
|
280
|
+
return None
|
|
281
|
+
|
|
282
|
+
try:
|
|
283
|
+
# Read all recorded actions
|
|
284
|
+
actions = self.get_recorded_actions()
|
|
285
|
+
|
|
286
|
+
if not actions:
|
|
287
|
+
logger.warning("No actions recorded in pause session, discarding")
|
|
288
|
+
self.discard_pause()
|
|
289
|
+
return None
|
|
290
|
+
|
|
291
|
+
# Get session metadata from first action (pause_started)
|
|
292
|
+
first_action = actions[0]
|
|
293
|
+
if first_action.type != "pause_started":
|
|
294
|
+
raise RuntimeError("First action is not 'pause_started'")
|
|
295
|
+
|
|
296
|
+
session_id = first_action.session_id
|
|
297
|
+
initial_state = first_action.data.get("initial_state", {})
|
|
298
|
+
|
|
299
|
+
# Calculate final statistics
|
|
300
|
+
total_actions = len(actions)
|
|
301
|
+
final_percentage = actions[-1].context_percentage
|
|
302
|
+
pause_started_at = first_action.timestamp
|
|
303
|
+
pause_finalized_at = datetime.now(timezone.utc).isoformat()
|
|
304
|
+
|
|
305
|
+
# Append finalization action
|
|
306
|
+
self.append_action(
|
|
307
|
+
action_type="pause_finalized",
|
|
308
|
+
action_data={
|
|
309
|
+
"total_actions": total_actions,
|
|
310
|
+
"final_percentage": final_percentage,
|
|
311
|
+
"pause_started_at": pause_started_at,
|
|
312
|
+
"duration_seconds": self._calculate_duration(
|
|
313
|
+
pause_started_at, pause_finalized_at
|
|
314
|
+
),
|
|
315
|
+
},
|
|
316
|
+
context_percentage=final_percentage,
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
# Create full snapshot if requested
|
|
320
|
+
if create_full_snapshot:
|
|
321
|
+
logger.info("Creating full session snapshot via SessionPauseManager")
|
|
322
|
+
pause_manager = SessionPauseManager(self.project_path)
|
|
323
|
+
|
|
324
|
+
# Build enriched state from initial_state and recorded actions
|
|
325
|
+
enriched_state = self._build_enriched_state(
|
|
326
|
+
initial_state, actions, session_id
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
# Use SessionPauseManager's internal method to save state
|
|
330
|
+
# (we'll build the state dict ourselves)
|
|
331
|
+
session_path = self.sessions_dir / f"{session_id}.json"
|
|
332
|
+
pause_manager.storage.write_json(
|
|
333
|
+
enriched_state, session_path, atomic=True
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
# Also create YAML and Markdown
|
|
337
|
+
yaml_path = self.sessions_dir / f"{session_id}.yaml"
|
|
338
|
+
pause_manager._save_yaml(enriched_state, yaml_path)
|
|
339
|
+
|
|
340
|
+
md_path = self.sessions_dir / f"{session_id}.md"
|
|
341
|
+
md_content = pause_manager._generate_markdown(enriched_state)
|
|
342
|
+
md_path.write_text(md_content)
|
|
343
|
+
|
|
344
|
+
# Update LATEST-SESSION pointer
|
|
345
|
+
pause_manager._update_latest_pointer(session_id)
|
|
346
|
+
|
|
347
|
+
logger.info(f"Full session snapshot created: {session_path}")
|
|
348
|
+
|
|
349
|
+
# Archive the JSONL file (rename instead of delete for debugging)
|
|
350
|
+
archive_path = self.sessions_dir / f"{session_id}-incremental.jsonl"
|
|
351
|
+
self.active_pause_path.rename(archive_path)
|
|
352
|
+
|
|
353
|
+
logger.info(
|
|
354
|
+
f"Incremental pause finalized: {session_id} "
|
|
355
|
+
f"({total_actions} actions, {final_percentage:.1%} context)"
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
return session_path if create_full_snapshot else archive_path
|
|
359
|
+
|
|
360
|
+
except Exception as e:
|
|
361
|
+
logger.error(f"Failed to finalize pause session: {e}")
|
|
362
|
+
raise RuntimeError(f"Failed to finalize pause: {e}") from e
|
|
363
|
+
|
|
364
|
+
def discard_pause(self) -> bool:
|
|
365
|
+
"""Discard the current incremental pause without finalizing.
|
|
366
|
+
|
|
367
|
+
Returns:
|
|
368
|
+
True if pause was discarded, False if no active pause
|
|
369
|
+
|
|
370
|
+
Raises:
|
|
371
|
+
RuntimeError: If discard operation fails
|
|
372
|
+
"""
|
|
373
|
+
if not self.is_pause_active():
|
|
374
|
+
logger.debug("No active pause session to discard")
|
|
375
|
+
return False
|
|
376
|
+
|
|
377
|
+
try:
|
|
378
|
+
session_id = self._get_session_id()
|
|
379
|
+
self.active_pause_path.unlink()
|
|
380
|
+
|
|
381
|
+
logger.info(f"Incremental pause discarded: {session_id}")
|
|
382
|
+
return True
|
|
383
|
+
|
|
384
|
+
except Exception as e:
|
|
385
|
+
logger.error(f"Failed to discard pause session: {e}")
|
|
386
|
+
raise RuntimeError(f"Failed to discard pause: {e}") from e
|
|
387
|
+
|
|
388
|
+
def get_pause_summary(self) -> Optional[Dict[str, Any]]:
|
|
389
|
+
"""Get summary of current pause session.
|
|
390
|
+
|
|
391
|
+
Returns:
|
|
392
|
+
Summary dictionary with:
|
|
393
|
+
- session_id: Session identifier
|
|
394
|
+
- action_count: Number of recorded actions
|
|
395
|
+
- duration_seconds: Time since pause started
|
|
396
|
+
- context_range: (start_percentage, current_percentage)
|
|
397
|
+
- pause_started_at: ISO timestamp
|
|
398
|
+
Returns None if no active pause
|
|
399
|
+
|
|
400
|
+
Raises:
|
|
401
|
+
RuntimeError: If reading summary fails
|
|
402
|
+
"""
|
|
403
|
+
if not self.is_pause_active():
|
|
404
|
+
return None
|
|
405
|
+
|
|
406
|
+
try:
|
|
407
|
+
actions = self.get_recorded_actions()
|
|
408
|
+
|
|
409
|
+
if not actions:
|
|
410
|
+
return None
|
|
411
|
+
|
|
412
|
+
first_action = actions[0]
|
|
413
|
+
last_action = actions[-1]
|
|
414
|
+
|
|
415
|
+
pause_started_at = first_action.timestamp
|
|
416
|
+
current_time = datetime.now(timezone.utc).isoformat()
|
|
417
|
+
|
|
418
|
+
return {
|
|
419
|
+
"session_id": first_action.session_id,
|
|
420
|
+
"action_count": len(actions),
|
|
421
|
+
"duration_seconds": self._calculate_duration(
|
|
422
|
+
pause_started_at, current_time
|
|
423
|
+
),
|
|
424
|
+
"context_range": (
|
|
425
|
+
first_action.context_percentage,
|
|
426
|
+
last_action.context_percentage,
|
|
427
|
+
),
|
|
428
|
+
"pause_started_at": pause_started_at,
|
|
429
|
+
"last_action_type": last_action.type,
|
|
430
|
+
"last_updated": last_action.timestamp,
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
except Exception as e:
|
|
434
|
+
logger.error(f"Failed to get pause summary: {e}")
|
|
435
|
+
raise RuntimeError(f"Failed to get summary: {e}") from e
|
|
436
|
+
|
|
437
|
+
def _get_session_id(self) -> str:
|
|
438
|
+
"""Extract session ID from first line of active pause file.
|
|
439
|
+
|
|
440
|
+
Returns:
|
|
441
|
+
Session identifier
|
|
442
|
+
|
|
443
|
+
Raises:
|
|
444
|
+
RuntimeError: If file is empty or corrupted
|
|
445
|
+
"""
|
|
446
|
+
try:
|
|
447
|
+
with self.active_pause_path.open("r") as f:
|
|
448
|
+
first_line = f.readline()
|
|
449
|
+
|
|
450
|
+
if not first_line:
|
|
451
|
+
raise RuntimeError("Active pause file is empty")
|
|
452
|
+
|
|
453
|
+
first_action = PauseAction.from_json_line(first_line)
|
|
454
|
+
return first_action.session_id
|
|
455
|
+
|
|
456
|
+
except Exception as e:
|
|
457
|
+
logger.error(f"Failed to read session ID: {e}")
|
|
458
|
+
raise RuntimeError(f"Failed to read session ID: {e}") from e
|
|
459
|
+
|
|
460
|
+
def _calculate_duration(self, start_iso: str, end_iso: str) -> int:
|
|
461
|
+
"""Calculate duration between two ISO timestamps.
|
|
462
|
+
|
|
463
|
+
Args:
|
|
464
|
+
start_iso: Start timestamp (ISO format)
|
|
465
|
+
end_iso: End timestamp (ISO format)
|
|
466
|
+
|
|
467
|
+
Returns:
|
|
468
|
+
Duration in seconds
|
|
469
|
+
|
|
470
|
+
Raises:
|
|
471
|
+
ValueError: If timestamps are invalid
|
|
472
|
+
"""
|
|
473
|
+
try:
|
|
474
|
+
start_dt = datetime.fromisoformat(start_iso.replace("Z", "+00:00"))
|
|
475
|
+
end_dt = datetime.fromisoformat(end_iso.replace("Z", "+00:00"))
|
|
476
|
+
return int((end_dt - start_dt).total_seconds())
|
|
477
|
+
|
|
478
|
+
except Exception as e:
|
|
479
|
+
logger.warning(f"Failed to calculate duration: {e}")
|
|
480
|
+
return 0
|
|
481
|
+
|
|
482
|
+
def _build_enriched_state(
|
|
483
|
+
self,
|
|
484
|
+
initial_state: Dict[str, Any],
|
|
485
|
+
actions: List[PauseAction],
|
|
486
|
+
session_id: str,
|
|
487
|
+
) -> Dict[str, Any]:
|
|
488
|
+
"""Build enriched state dictionary from initial state and recorded actions.
|
|
489
|
+
|
|
490
|
+
Args:
|
|
491
|
+
initial_state: Initial context snapshot
|
|
492
|
+
actions: List of recorded actions
|
|
493
|
+
session_id: Session identifier
|
|
494
|
+
|
|
495
|
+
Returns:
|
|
496
|
+
Enriched state dictionary compatible with SessionPauseManager
|
|
497
|
+
"""
|
|
498
|
+
# Extract action summaries
|
|
499
|
+
tool_calls = [a for a in actions if a.type == "tool_call"]
|
|
500
|
+
assistant_responses = [a for a in actions if a.type == "assistant_response"]
|
|
501
|
+
|
|
502
|
+
# Build accomplishments from actions
|
|
503
|
+
accomplishments = []
|
|
504
|
+
for response in assistant_responses:
|
|
505
|
+
if "summary" in response.data:
|
|
506
|
+
accomplishments.append(response.data["summary"])
|
|
507
|
+
|
|
508
|
+
# Calculate session duration
|
|
509
|
+
first_action = actions[0]
|
|
510
|
+
last_action = actions[-1]
|
|
511
|
+
duration_seconds = self._calculate_duration(
|
|
512
|
+
first_action.timestamp, last_action.timestamp
|
|
513
|
+
)
|
|
514
|
+
|
|
515
|
+
# Build state dictionary
|
|
516
|
+
pause_manager = SessionPauseManager(self.project_path)
|
|
517
|
+
base_state = pause_manager._capture_state(session_id, None)
|
|
518
|
+
|
|
519
|
+
# Enrich with incremental pause data
|
|
520
|
+
base_state["paused_at"] = last_action.timestamp
|
|
521
|
+
base_state["duration_hours"] = round(duration_seconds / 3600, 2)
|
|
522
|
+
base_state["context_usage"] = {
|
|
523
|
+
"tokens_used": int(
|
|
524
|
+
last_action.context_percentage * ContextUsageTracker.CONTEXT_BUDGET
|
|
525
|
+
),
|
|
526
|
+
"tokens_total": ContextUsageTracker.CONTEXT_BUDGET,
|
|
527
|
+
"percentage": last_action.context_percentage * 100,
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
base_state["conversation"]["primary_task"] = (
|
|
531
|
+
"Auto-pause triggered at 90% context"
|
|
532
|
+
)
|
|
533
|
+
base_state["conversation"]["current_phase"] = "Wind-down"
|
|
534
|
+
base_state["conversation"]["summary"] = (
|
|
535
|
+
f"Session auto-paused after {len(actions)} actions. "
|
|
536
|
+
f"Context usage: {first_action.context_percentage:.1%} -> {last_action.context_percentage:.1%}"
|
|
537
|
+
)
|
|
538
|
+
base_state["conversation"]["accomplishments"] = accomplishments[
|
|
539
|
+
:10
|
|
540
|
+
] # Limit to 10
|
|
541
|
+
|
|
542
|
+
# Add incremental pause metadata
|
|
543
|
+
base_state["incremental_pause"] = {
|
|
544
|
+
"enabled": True,
|
|
545
|
+
"action_count": len(actions),
|
|
546
|
+
"duration_seconds": duration_seconds,
|
|
547
|
+
"context_range": [
|
|
548
|
+
first_action.context_percentage,
|
|
549
|
+
last_action.context_percentage,
|
|
550
|
+
],
|
|
551
|
+
"tool_calls": len(tool_calls),
|
|
552
|
+
"actions_summary": [
|
|
553
|
+
{"type": a.type, "timestamp": a.timestamp} for a in actions[-10:]
|
|
554
|
+
], # Last 10 actions
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
return base_state
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
# Import for type hints and usage
|
|
561
|
+
from claude_mpm.services.infrastructure.context_usage_tracker import ContextUsageTracker
|
|
@@ -14,7 +14,7 @@ DESIGN DECISIONS:
|
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
import json
|
|
17
|
-
import subprocess
|
|
17
|
+
import subprocess # nosec B404 - subprocess needed for git commands
|
|
18
18
|
from datetime import datetime, timezone
|
|
19
19
|
from pathlib import Path
|
|
20
20
|
from typing import Any, Dict, List, Optional, Tuple
|
|
@@ -50,9 +50,11 @@ class SessionResumeHelper:
|
|
|
50
50
|
|
|
51
51
|
if self.pause_dir.exists():
|
|
52
52
|
session_files.extend(list(self.pause_dir.glob("session-*.json")))
|
|
53
|
+
session_files.extend(list(self.pause_dir.glob("session-*.md")))
|
|
53
54
|
|
|
54
55
|
if self.legacy_pause_dir.exists():
|
|
55
56
|
session_files.extend(list(self.legacy_pause_dir.glob("session-*.json")))
|
|
57
|
+
session_files.extend(list(self.legacy_pause_dir.glob("session-*.md")))
|
|
56
58
|
|
|
57
59
|
return len(session_files) > 0
|
|
58
60
|
|
|
@@ -67,9 +69,11 @@ class SessionResumeHelper:
|
|
|
67
69
|
|
|
68
70
|
if self.pause_dir.exists():
|
|
69
71
|
session_files.extend(list(self.pause_dir.glob("session-*.json")))
|
|
72
|
+
session_files.extend(list(self.pause_dir.glob("session-*.md")))
|
|
70
73
|
|
|
71
74
|
if self.legacy_pause_dir.exists():
|
|
72
75
|
session_files.extend(list(self.legacy_pause_dir.glob("session-*.json")))
|
|
76
|
+
session_files.extend(list(self.legacy_pause_dir.glob("session-*.md")))
|
|
73
77
|
|
|
74
78
|
if not session_files:
|
|
75
79
|
return None
|
|
@@ -112,7 +116,7 @@ class SessionResumeHelper:
|
|
|
112
116
|
"--all",
|
|
113
117
|
]
|
|
114
118
|
|
|
115
|
-
result = subprocess.run(
|
|
119
|
+
result = subprocess.run( # nosec B603 - git command with safe args
|
|
116
120
|
cmd,
|
|
117
121
|
cwd=self.project_path,
|
|
118
122
|
capture_output=True,
|
|
@@ -332,9 +336,11 @@ class SessionResumeHelper:
|
|
|
332
336
|
|
|
333
337
|
if self.pause_dir.exists():
|
|
334
338
|
session_files.extend(list(self.pause_dir.glob("session-*.json")))
|
|
339
|
+
session_files.extend(list(self.pause_dir.glob("session-*.md")))
|
|
335
340
|
|
|
336
341
|
if self.legacy_pause_dir.exists():
|
|
337
342
|
session_files.extend(list(self.legacy_pause_dir.glob("session-*.json")))
|
|
343
|
+
session_files.extend(list(self.legacy_pause_dir.glob("session-*.md")))
|
|
338
344
|
|
|
339
345
|
return len(session_files)
|
|
340
346
|
|
|
@@ -348,9 +354,11 @@ class SessionResumeHelper:
|
|
|
348
354
|
|
|
349
355
|
if self.pause_dir.exists():
|
|
350
356
|
session_files.extend(list(self.pause_dir.glob("session-*.json")))
|
|
357
|
+
session_files.extend(list(self.pause_dir.glob("session-*.md")))
|
|
351
358
|
|
|
352
359
|
if self.legacy_pause_dir.exists():
|
|
353
360
|
session_files.extend(list(self.legacy_pause_dir.glob("session-*.json")))
|
|
361
|
+
session_files.extend(list(self.legacy_pause_dir.glob("session-*.md")))
|
|
354
362
|
|
|
355
363
|
if not session_files:
|
|
356
364
|
return []
|