claude-mpm 5.4.65__py3-none-any.whl → 5.6.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/CLAUDE_MPM_OUTPUT_STYLE.md +66 -241
- claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +107 -1928
- claude_mpm/agents/PM_INSTRUCTIONS.md +119 -689
- claude_mpm/agents/WORKFLOW.md +2 -0
- claude_mpm/agents/templates/circuit-breakers.md +26 -17
- claude_mpm/cli/__init__.py +5 -1
- claude_mpm/cli/commands/agents.py +2 -4
- claude_mpm/cli/commands/agents_reconcile.py +197 -0
- claude_mpm/cli/commands/autotodos.py +566 -0
- claude_mpm/cli/commands/commander.py +46 -0
- claude_mpm/cli/commands/configure.py +620 -21
- 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 +2 -2
- claude_mpm/cli/commands/run.py +35 -3
- claude_mpm/cli/commands/skill_source.py +51 -2
- claude_mpm/cli/commands/skills.py +171 -17
- claude_mpm/cli/executor.py +120 -16
- claude_mpm/cli/interactive/__init__.py +10 -0
- claude_mpm/cli/interactive/agent_wizard.py +30 -50
- claude_mpm/cli/interactive/questionary_styles.py +65 -0
- claude_mpm/cli/interactive/skill_selector.py +481 -0
- claude_mpm/cli/parsers/base_parser.py +76 -1
- claude_mpm/cli/parsers/commander_parser.py +83 -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 +5 -0
- claude_mpm/cli/startup.py +203 -359
- claude_mpm/cli/startup_display.py +72 -5
- claude_mpm/cli/startup_logging.py +2 -2
- claude_mpm/cli/utils.py +7 -3
- claude_mpm/commander/__init__.py +72 -0
- claude_mpm/commander/adapters/__init__.py +31 -0
- claude_mpm/commander/adapters/base.py +191 -0
- claude_mpm/commander/adapters/claude_code.py +361 -0
- claude_mpm/commander/adapters/communication.py +366 -0
- claude_mpm/commander/api/__init__.py +16 -0
- claude_mpm/commander/api/app.py +105 -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 +228 -0
- claude_mpm/commander/api/routes/work.py +260 -0
- claude_mpm/commander/api/schemas.py +182 -0
- claude_mpm/commander/chat/__init__.py +7 -0
- claude_mpm/commander/chat/cli.py +107 -0
- claude_mpm/commander/chat/commands.py +96 -0
- claude_mpm/commander/chat/repl.py +310 -0
- claude_mpm/commander/config.py +49 -0
- claude_mpm/commander/config_loader.py +115 -0
- claude_mpm/commander/daemon.py +398 -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 +143 -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 +337 -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/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 +404 -0
- claude_mpm/commander/runtime/__init__.py +10 -0
- claude_mpm/commander/runtime/executor.py +191 -0
- claude_mpm/commander/runtime/monitor.py +316 -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 +189 -0
- claude_mpm/commander/work/queue.py +405 -0
- claude_mpm/commander/workflow/__init__.py +27 -0
- claude_mpm/commander/workflow/event_handler.py +219 -0
- claude_mpm/commander/workflow/notifier.py +146 -0
- claude_mpm/commands/mpm-config.md +8 -0
- claude_mpm/commands/mpm-doctor.md +8 -0
- claude_mpm/commands/mpm-help.md +8 -0
- claude_mpm/commands/mpm-init.md +8 -0
- claude_mpm/commands/mpm-monitor.md +8 -0
- claude_mpm/commands/mpm-organize.md +8 -0
- claude_mpm/commands/mpm-postmortem.md +8 -0
- claude_mpm/commands/mpm-session-resume.md +9 -1
- claude_mpm/commands/mpm-status.md +8 -0
- claude_mpm/commands/mpm-ticket-view.md +8 -0
- claude_mpm/commands/mpm-version.md +8 -0
- claude_mpm/commands/mpm.md +8 -0
- claude_mpm/config/agent_presets.py +8 -7
- claude_mpm/config/skill_sources.py +16 -0
- claude_mpm/constants.py +1 -0
- claude_mpm/core/claude_runner.py +2 -2
- claude_mpm/core/config.py +32 -19
- claude_mpm/core/hook_manager.py +51 -3
- claude_mpm/core/interactive_session.py +7 -7
- claude_mpm/core/logger.py +26 -9
- claude_mpm/core/logging_utils.py +35 -11
- claude_mpm/core/output_style_manager.py +31 -13
- claude_mpm/core/unified_config.py +54 -8
- claude_mpm/core/unified_paths.py +95 -90
- 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/{Cs_tUR18.js → 1WZnGYqX.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CDuw-vjf.js → 67pF3qNn.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{bTOqqlTd.js → 6RxdMKe4.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DwBR2MJi.js → 8cZrfX0h.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{ZGh7QtNv.js → 9a6T2nm-.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{D9lljYKQ.js → B443AUzu.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{RJiighC3.js → B8AwtY2H.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uuIeMWc-.js → BF15LAsF.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{D3k0OPJN.js → BRcwIQNr.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CyWMqx4W.js → BV6nKitt.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CiIAseT4.js → BViJ8lZt.js} +5 -5
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CBBdVcY8.js → BcQ-Q0FE.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BovzEFCE.js → Bpyvgze_.js} +1 -1
- 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/{eNVUfhuA.js → C3rbW_a-.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{GYwsonyD.js → C8WYN38h.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BIF9m_hv.js → C9I8FlXH.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B0uc0UOD.js → CIQcWgO2.js} +3 -3
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Be7GpZd6.js → CIctN7YN.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Bh0LDWpI.js → CKrS_JZW.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DUrLdbGD.js → CR6P9C4A.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B7xVLGWV.js → CRRR9MD_.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Dhb8PKl3.js → CSXtMOf0.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BPYeabCQ.js → CT-sbxSk.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{sQeU3Y1z.js → CWm6DJsp.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CnA0NrzZ.js → CpqQ1Kzn.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C4B-KCzX.js → D2nGpDRe.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DGkLK5U1.js → D9iCMida.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BofRWZRR.js → D9ykgMoY.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DmxopI1J.js → DL2Ldur1.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C30mlcqg.js → DPfltzjH.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Vzk33B_K.js → DR8nis88.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DI7hHRFL.js → DUliQN2b.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C4JcI4KD.js → DXlhR01x.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{bT1r9zLR.js → D_lyTybS.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DZX00Y4g.js → DngoTTgh.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CzZX-COe.js → DqkmHtDC.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B7RN905-.js → DsDh8EYs.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DLVjFsZ3.js → DypDmXgd.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{iEWssX7S.js → IPYC-LnN.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DaimHw_p.js → JpevfAFt.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DY1XQ8fi.js → R8CEIRAd.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Dle-35c7.js → Zxy7qc-l.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C_Usid8X.js → qtd3IeO4.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CzeYkLYB.js → ulBFON_C.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Cfqx1Qun.js → wQVh1CoA.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/{app.D6-I5TpK.js → app.Dr7t0z2J.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.m1gL8KXf.js → 0.RgBboRvH.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{1.CgNOuw-d.js → 1.DG-KkbDf.js} +1 -1
- 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 -1
- claude_mpm/dashboard/static/svelte-build/index.html +9 -9
- 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-314.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-314.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-314.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-314.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-314.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-314.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-314.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-314.pyc +0 -0
- claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +283 -87
- claude_mpm/hooks/claude_hooks/hook_handler.py +106 -89
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
- claude_mpm/hooks/claude_hooks/installer.py +116 -8
- claude_mpm/hooks/claude_hooks/memory_integration.py +51 -31
- claude_mpm/hooks/claude_hooks/response_tracking.py +42 -59
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-314.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__/connection_manager_http.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-314.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-314.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-314.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-314.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +39 -24
- 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/session_resume_hook.py +89 -1
- claude_mpm/hooks/templates/pre_tool_use_template.py +10 -2
- claude_mpm/init.py +1 -1
- claude_mpm/scripts/claude-hook-handler.sh +43 -16
- claude_mpm/services/agents/agent_recommendation_service.py +8 -8
- claude_mpm/services/agents/agent_selection_service.py +2 -2
- claude_mpm/services/agents/cache_git_manager.py +1 -1
- claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +3 -0
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
- claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
- claude_mpm/services/agents/startup_sync.py +5 -2
- 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/delegation_detector.py +175 -0
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +30 -0
- 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_log.py +325 -0
- 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_manager.py +15 -4
- claude_mpm/services/monitor/management/lifecycle.py +8 -2
- claude_mpm/services/monitor/server.py +106 -16
- claude_mpm/services/pm_skills_deployer.py +259 -87
- claude_mpm/services/skills/git_skill_source_manager.py +135 -11
- claude_mpm/services/skills/selective_skill_deployer.py +142 -26
- claude_mpm/services/skills/skill_discovery_service.py +74 -4
- claude_mpm/services/skills_deployer.py +31 -5
- claude_mpm/services/socketio/handlers/hook.py +14 -7
- claude_mpm/services/socketio/server/main.py +12 -4
- 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-doctor/SKILL.md +53 -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-session-management/SKILL.md +312 -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-tool-usage-guide/SKILL.md +386 -0
- claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
- claude_mpm/skills/skill_manager.py +4 -4
- claude_mpm/utils/agent_dependency_loader.py +4 -2
- claude_mpm/utils/robust_installer.py +10 -6
- claude_mpm-5.6.10.dist-info/METADATA +391 -0
- {claude_mpm-5.4.65.dist-info → claude_mpm-5.6.10.dist-info}/RECORD +303 -181
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +0 -24
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +0 -323
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +0 -1
- claude_mpm-5.4.65.dist-info/METADATA +0 -999
- /claude_mpm/skills/bundled/pm/{pm-delegation-patterns → mpm-delegation-patterns}/SKILL.md +0 -0
- /claude_mpm/skills/bundled/pm/{pm-git-file-tracking → mpm-git-file-tracking}/SKILL.md +0 -0
- /claude_mpm/skills/bundled/pm/{pm-pr-workflow → mpm-pr-workflow}/SKILL.md +0 -0
- /claude_mpm/skills/bundled/pm/{pm-ticketing-integration → mpm-ticketing-integration}/SKILL.md +0 -0
- /claude_mpm/skills/bundled/pm/{pm-verification-protocols → mpm-verification-protocols}/SKILL.md +0 -0
- {claude_mpm-5.4.65.dist-info → claude_mpm-5.6.10.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.65.dist-info → claude_mpm-5.6.10.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.65.dist-info → claude_mpm-5.6.10.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.65.dist-info → claude_mpm-5.6.10.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.65.dist-info → claude_mpm-5.6.10.dist-info}/top_level.txt +0 -0
|
@@ -12,7 +12,7 @@ of InteractiveSession without circular dependency issues.
|
|
|
12
12
|
|
|
13
13
|
import contextlib
|
|
14
14
|
import os
|
|
15
|
-
import subprocess
|
|
15
|
+
import subprocess # nosec B404
|
|
16
16
|
import uuid
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple
|
|
@@ -359,19 +359,19 @@ class InteractiveSession:
|
|
|
359
359
|
osm = self.runner.framework_loader.output_style_manager
|
|
360
360
|
if osm:
|
|
361
361
|
if osm.claude_version and osm.supports_output_styles():
|
|
362
|
-
# Check if
|
|
362
|
+
# Check if Claude MPM style is active
|
|
363
363
|
settings_file = osm.settings_file
|
|
364
364
|
if settings_file.exists():
|
|
365
365
|
import json
|
|
366
366
|
|
|
367
367
|
settings = json.loads(settings_file.read_text())
|
|
368
368
|
active_style = settings.get("activeOutputStyle")
|
|
369
|
-
if active_style
|
|
370
|
-
return "Output Style:
|
|
369
|
+
if active_style in ("Claude MPM", "Claude MPM Teacher"):
|
|
370
|
+
return f"Output Style: {active_style} ✅"
|
|
371
371
|
return f"Output Style: {active_style or 'none'}"
|
|
372
372
|
return "Output Style: Available"
|
|
373
373
|
return "Output Style: Injected (legacy)"
|
|
374
|
-
except Exception:
|
|
374
|
+
except Exception: # nosec B110
|
|
375
375
|
pass
|
|
376
376
|
return None
|
|
377
377
|
|
|
@@ -582,7 +582,7 @@ class InteractiveSession:
|
|
|
582
582
|
)
|
|
583
583
|
|
|
584
584
|
# This will not return if successful
|
|
585
|
-
os.execvpe(cmd[0], cmd, env)
|
|
585
|
+
os.execvpe(cmd[0], cmd, env) # nosec B606
|
|
586
586
|
return False # Only reached on failure
|
|
587
587
|
|
|
588
588
|
def _launch_subprocess_mode(self, cmd: list, env: dict) -> bool:
|
|
@@ -641,7 +641,7 @@ class InteractiveSession:
|
|
|
641
641
|
cmd = environment["command"]
|
|
642
642
|
env = environment["environment"]
|
|
643
643
|
|
|
644
|
-
result = subprocess.run(
|
|
644
|
+
result = subprocess.run( # nosec B603
|
|
645
645
|
cmd, stdin=None, stdout=None, stderr=None, env=env, check=False
|
|
646
646
|
)
|
|
647
647
|
|
claude_mpm/core/logger.py
CHANGED
|
@@ -214,19 +214,22 @@ def setup_logging(
|
|
|
214
214
|
|
|
215
215
|
# Console handler
|
|
216
216
|
if console_output:
|
|
217
|
+
# MUST use stderr to avoid corrupting hook JSON output
|
|
218
|
+
# WHY stderr: Hook handlers output JSON to stdout. Logging to stdout
|
|
219
|
+
# corrupts this JSON and causes "hook error" messages from Claude Code.
|
|
217
220
|
if use_streaming:
|
|
218
221
|
# Use streaming handler for single-line INFO messages
|
|
219
|
-
console_handler = StreamingHandler(sys.
|
|
222
|
+
console_handler = StreamingHandler(sys.stderr)
|
|
220
223
|
console_handler.setFormatter(simple_formatter)
|
|
221
224
|
elif use_rich and not json_format:
|
|
222
225
|
# Rich support has been removed, use standard handler
|
|
223
|
-
console_handler = logging.StreamHandler(sys.
|
|
226
|
+
console_handler = logging.StreamHandler(sys.stderr)
|
|
224
227
|
console_handler.setFormatter(simple_formatter)
|
|
225
228
|
else:
|
|
226
|
-
console_handler = logging.StreamHandler(sys.
|
|
229
|
+
console_handler = logging.StreamHandler(sys.stderr)
|
|
227
230
|
console_handler.setFormatter(formatter if json_format else simple_formatter)
|
|
228
231
|
|
|
229
|
-
console_handler.setLevel(
|
|
232
|
+
console_handler.setLevel(log_level) # Respect the requested log level
|
|
230
233
|
logger.addHandler(console_handler)
|
|
231
234
|
|
|
232
235
|
# File handler
|
|
@@ -263,7 +266,7 @@ def setup_logging(
|
|
|
263
266
|
if deleted_count > 0:
|
|
264
267
|
# Log to the new file handler that we're about to add
|
|
265
268
|
pass # Deletion count will be logged when logger is ready
|
|
266
|
-
except Exception:
|
|
269
|
+
except Exception: # nosec B110 - intentional: logging should not break app
|
|
267
270
|
pass # Ignore cleanup errors
|
|
268
271
|
|
|
269
272
|
# Also create a symlink to latest log (with thread safety)
|
|
@@ -305,7 +308,7 @@ def setup_logging(
|
|
|
305
308
|
# Fallback: try to create a regular file with reference to actual log
|
|
306
309
|
try:
|
|
307
310
|
latest_link.write_text(f"Latest log: {log_file.name}\n")
|
|
308
|
-
except Exception:
|
|
311
|
+
except Exception: # nosec B110 - intentional: logging should not break app
|
|
309
312
|
pass # Silently fail - logging should not break the application
|
|
310
313
|
except Exception as e:
|
|
311
314
|
# Catch any other unexpected errors to ensure logging doesn't break
|
|
@@ -381,15 +384,29 @@ def cleanup_old_mpm_logs(
|
|
|
381
384
|
try:
|
|
382
385
|
log_file.unlink()
|
|
383
386
|
deleted_count += 1
|
|
384
|
-
except Exception:
|
|
387
|
+
except Exception: # nosec B110 - intentional: log cleanup is best-effort
|
|
385
388
|
pass # Ignore deletion errors
|
|
386
389
|
|
|
387
390
|
return deleted_count
|
|
388
391
|
|
|
389
392
|
|
|
390
393
|
def get_logger(name: str) -> logging.Logger:
|
|
391
|
-
"""Get a logger instance.
|
|
392
|
-
|
|
394
|
+
"""Get a logger instance.
|
|
395
|
+
|
|
396
|
+
CRITICAL: Respects startup suppression mode (CRITICAL+1) to prevent
|
|
397
|
+
early INFO logs before setup_logging() is called.
|
|
398
|
+
"""
|
|
399
|
+
logger = logging.getLogger(f"claude_mpm.{name}")
|
|
400
|
+
|
|
401
|
+
# Check if root logger is suppressed (startup.py sets CRITICAL+1)
|
|
402
|
+
root_logger = logging.getLogger()
|
|
403
|
+
if root_logger.level > logging.CRITICAL:
|
|
404
|
+
# Suppression active - ensure this logger is also suppressed
|
|
405
|
+
logger.setLevel(logging.CRITICAL + 1)
|
|
406
|
+
logger.handlers = []
|
|
407
|
+
logger.propagate = False
|
|
408
|
+
|
|
409
|
+
return logger
|
|
393
410
|
|
|
394
411
|
|
|
395
412
|
def setup_streaming_logger(name: str, level: str = "INFO") -> logging.Logger:
|
claude_mpm/core/logging_utils.py
CHANGED
|
@@ -103,21 +103,45 @@ class LoggerFactory:
|
|
|
103
103
|
|
|
104
104
|
# Set up root logger
|
|
105
105
|
root_logger = logging.getLogger()
|
|
106
|
-
|
|
106
|
+
|
|
107
|
+
# CRITICAL FIX: Respect existing root logger suppression
|
|
108
|
+
# If root logger is already set to CRITICAL+1 (suppressed by startup.py),
|
|
109
|
+
# don't override it. This prevents logging from appearing during startup
|
|
110
|
+
# before the CLI's setup_logging() runs.
|
|
111
|
+
current_level = root_logger.level
|
|
112
|
+
desired_level = LoggingConfig.LEVELS.get(cls._log_level, logging.INFO)
|
|
113
|
+
|
|
114
|
+
# Only set level if current is unset (0) or lower than desired
|
|
115
|
+
# CRITICAL+1 is 51, so this check preserves suppression
|
|
116
|
+
should_configure_logging = current_level == 0 or (
|
|
117
|
+
current_level < desired_level and current_level <= logging.CRITICAL
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
if should_configure_logging:
|
|
121
|
+
root_logger.setLevel(desired_level)
|
|
122
|
+
# else: root logger is suppressed (CRITICAL+1), keep it suppressed
|
|
107
123
|
|
|
108
124
|
# Remove existing handlers
|
|
109
125
|
root_logger.handlers = []
|
|
110
126
|
|
|
111
|
-
#
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
127
|
+
# CRITICAL FIX: Don't add handlers if logging is suppressed
|
|
128
|
+
# If root logger is at CRITICAL+1 (startup suppression), don't add any handlers
|
|
129
|
+
# This prevents early imports from logging before CLI setup_logging() runs
|
|
130
|
+
if should_configure_logging:
|
|
131
|
+
# Console handler - MUST use stderr to avoid corrupting hook JSON output
|
|
132
|
+
# WHY stderr: Hook handlers output JSON to stdout. Logging to stdout
|
|
133
|
+
# corrupts this JSON and causes "hook error" messages from Claude Code.
|
|
134
|
+
console_handler = logging.StreamHandler(sys.stderr)
|
|
135
|
+
console_handler.setLevel(
|
|
136
|
+
LoggingConfig.LEVELS.get(cls._log_level, logging.INFO)
|
|
137
|
+
)
|
|
138
|
+
console_formatter = logging.Formatter(
|
|
139
|
+
log_format or LoggingConfig.DEFAULT_FORMAT,
|
|
140
|
+
date_format or LoggingConfig.DATE_FORMAT,
|
|
141
|
+
)
|
|
142
|
+
console_handler.setFormatter(console_formatter)
|
|
143
|
+
root_logger.addHandler(console_handler)
|
|
144
|
+
cls._handlers["console"] = console_handler
|
|
121
145
|
|
|
122
146
|
# File handler (optional)
|
|
123
147
|
if log_to_file and cls._log_dir:
|
|
@@ -13,7 +13,7 @@ Users can change it if they want, and the system will respect their choice.
|
|
|
13
13
|
|
|
14
14
|
import json
|
|
15
15
|
import re
|
|
16
|
-
import subprocess
|
|
16
|
+
import subprocess # nosec B404
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
from typing import Any, Dict, Literal, Optional, TypedDict, cast
|
|
19
19
|
|
|
@@ -27,7 +27,9 @@ _CACHED_CLAUDE_VERSION: Optional[str] = None
|
|
|
27
27
|
_VERSION_DETECTED: bool = False
|
|
28
28
|
|
|
29
29
|
# Output style types
|
|
30
|
-
OutputStyleType = Literal[
|
|
30
|
+
OutputStyleType = Literal[
|
|
31
|
+
"professional", "teaching", "research", "founders"
|
|
32
|
+
] # "founders" is deprecated, use "research"
|
|
31
33
|
|
|
32
34
|
|
|
33
35
|
class StyleConfig(TypedDict):
|
|
@@ -41,9 +43,10 @@ class StyleConfig(TypedDict):
|
|
|
41
43
|
class OutputStyleManager:
|
|
42
44
|
"""Manages output style deployment and version-based handling.
|
|
43
45
|
|
|
44
|
-
Supports
|
|
46
|
+
Supports three output styles:
|
|
45
47
|
- professional: Default Claude MPM style (claude-mpm.md)
|
|
46
|
-
- teaching: Adaptive teaching mode (claude-mpm-
|
|
48
|
+
- teaching: Adaptive teaching mode (claude-mpm-teacher.md)
|
|
49
|
+
- research: Codebase research mode for founders, PMs, and developers (claude-mpm-research.md)
|
|
47
50
|
"""
|
|
48
51
|
|
|
49
52
|
def __init__(self) -> None:
|
|
@@ -51,8 +54,8 @@ class OutputStyleManager:
|
|
|
51
54
|
self.logger = get_logger("output_style_manager") # type: ignore[misc]
|
|
52
55
|
self.claude_version = self._detect_claude_version()
|
|
53
56
|
|
|
54
|
-
# Deploy to ~/.claude/styles/ directory (
|
|
55
|
-
self.output_style_dir = Path.home() / ".claude" / "styles"
|
|
57
|
+
# Deploy to ~/.claude/output-styles/ directory (official Claude Code location)
|
|
58
|
+
self.output_style_dir = Path.home() / ".claude" / "output-styles"
|
|
56
59
|
self.settings_file = Path.home() / ".claude" / "settings.json"
|
|
57
60
|
|
|
58
61
|
# Style definitions
|
|
@@ -62,14 +65,29 @@ class OutputStyleManager:
|
|
|
62
65
|
/ "agents"
|
|
63
66
|
/ "CLAUDE_MPM_OUTPUT_STYLE.md",
|
|
64
67
|
target=self.output_style_dir / "claude-mpm.md",
|
|
65
|
-
name="
|
|
68
|
+
name="Claude MPM",
|
|
66
69
|
),
|
|
67
70
|
"teaching": StyleConfig(
|
|
68
71
|
source=Path(__file__).parent.parent
|
|
69
72
|
/ "agents"
|
|
70
73
|
/ "CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md",
|
|
71
|
-
target=self.output_style_dir / "claude-mpm-
|
|
72
|
-
name="
|
|
74
|
+
target=self.output_style_dir / "claude-mpm-teacher.md",
|
|
75
|
+
name="Claude MPM Teacher",
|
|
76
|
+
),
|
|
77
|
+
"research": StyleConfig(
|
|
78
|
+
source=Path(__file__).parent.parent
|
|
79
|
+
/ "agents"
|
|
80
|
+
/ "CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md",
|
|
81
|
+
target=self.output_style_dir / "claude-mpm-research.md",
|
|
82
|
+
name="Claude MPM Research",
|
|
83
|
+
),
|
|
84
|
+
# Backward compatibility alias (deprecated)
|
|
85
|
+
"founders": StyleConfig(
|
|
86
|
+
source=Path(__file__).parent.parent
|
|
87
|
+
/ "agents"
|
|
88
|
+
/ "CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md",
|
|
89
|
+
target=self.output_style_dir / "claude-mpm-research.md",
|
|
90
|
+
name="Claude MPM Research",
|
|
73
91
|
),
|
|
74
92
|
}
|
|
75
93
|
|
|
@@ -93,7 +111,7 @@ class OutputStyleManager:
|
|
|
93
111
|
|
|
94
112
|
try:
|
|
95
113
|
# Run claude --version command
|
|
96
|
-
result = subprocess.run(
|
|
114
|
+
result = subprocess.run( # nosec B603 B607
|
|
97
115
|
["claude", "--version"],
|
|
98
116
|
capture_output=True,
|
|
99
117
|
text=True,
|
|
@@ -300,12 +318,12 @@ class OutputStyleManager:
|
|
|
300
318
|
self.logger.error(f"Failed to deploy {style} style: {e}")
|
|
301
319
|
return False
|
|
302
320
|
|
|
303
|
-
def _activate_output_style(self, style_name: str = "
|
|
321
|
+
def _activate_output_style(self, style_name: str = "Claude MPM") -> bool:
|
|
304
322
|
"""
|
|
305
323
|
Update Claude Code settings to activate a specific output style.
|
|
306
324
|
|
|
307
325
|
Args:
|
|
308
|
-
style_name: Name of the style to activate (e.g., "
|
|
326
|
+
style_name: Name of the style to activate (e.g., "Claude MPM", "Claude MPM Teacher")
|
|
309
327
|
|
|
310
328
|
Returns:
|
|
311
329
|
True if activated successfully, False otherwise
|
|
@@ -443,7 +461,7 @@ class OutputStyleManager:
|
|
|
443
461
|
|
|
444
462
|
# Activate the default style if requested
|
|
445
463
|
if activate_default and results.get("professional", False):
|
|
446
|
-
self._activate_output_style("
|
|
464
|
+
self._activate_output_style("Claude MPM")
|
|
447
465
|
|
|
448
466
|
return results
|
|
449
467
|
|
|
@@ -16,7 +16,7 @@ Design Principles:
|
|
|
16
16
|
from pathlib import Path
|
|
17
17
|
from typing import Any, Dict, List, Optional, Union
|
|
18
18
|
|
|
19
|
-
from pydantic import BaseModel, Field,
|
|
19
|
+
from pydantic import BaseModel, Field, field_validator
|
|
20
20
|
from pydantic_settings import BaseSettings
|
|
21
21
|
|
|
22
22
|
from .exceptions import ConfigurationError
|
|
@@ -54,8 +54,9 @@ class LoggingConfig(BaseModel):
|
|
|
54
54
|
default=True, description="Enable console logging"
|
|
55
55
|
)
|
|
56
56
|
|
|
57
|
-
@
|
|
58
|
-
|
|
57
|
+
@field_validator("level")
|
|
58
|
+
@classmethod
|
|
59
|
+
def validate_log_level(cls, v):
|
|
59
60
|
valid_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
|
60
61
|
if v.upper() not in valid_levels:
|
|
61
62
|
raise ValueError(f"Invalid log level. Must be one of: {valid_levels}")
|
|
@@ -65,8 +66,36 @@ class LoggingConfig(BaseModel):
|
|
|
65
66
|
class AgentConfig(BaseModel):
|
|
66
67
|
"""Agent system configuration."""
|
|
67
68
|
|
|
69
|
+
# Explicit deployment lists (simplified model)
|
|
70
|
+
enabled: List[str] = Field(
|
|
71
|
+
default_factory=list,
|
|
72
|
+
description="Explicit list of agent IDs to deploy (empty = use auto_discover)",
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Required agents that are always deployed
|
|
76
|
+
# Standard 7 core agents for essential PM workflow functionality
|
|
77
|
+
# These are auto-deployed when no agents are specified in configuration
|
|
78
|
+
required: List[str] = Field(
|
|
79
|
+
default_factory=lambda: [
|
|
80
|
+
"engineer", # General-purpose implementation
|
|
81
|
+
"research", # Codebase exploration and analysis
|
|
82
|
+
"qa", # Testing and quality assurance
|
|
83
|
+
"web-qa", # Browser-based testing specialist
|
|
84
|
+
"documentation", # Documentation generation
|
|
85
|
+
"ops", # Basic deployment operations
|
|
86
|
+
"ticketing", # Ticket tracking (essential for PM workflow)
|
|
87
|
+
],
|
|
88
|
+
description="Agents that are always deployed (standard 7 core agents)",
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
include_universal: bool = Field(
|
|
92
|
+
default=True,
|
|
93
|
+
description="Auto-include all agents with 'universal' toolchain/category",
|
|
94
|
+
)
|
|
95
|
+
|
|
68
96
|
auto_discover: bool = Field(
|
|
69
|
-
default=
|
|
97
|
+
default=False,
|
|
98
|
+
description="Enable automatic agent discovery (deprecated, use enabled list)",
|
|
70
99
|
)
|
|
71
100
|
precedence: List[str] = Field(
|
|
72
101
|
default=["project", "user", "system"], description="Agent precedence order"
|
|
@@ -239,6 +268,21 @@ class DocumentationConfig(BaseModel):
|
|
|
239
268
|
)
|
|
240
269
|
|
|
241
270
|
|
|
271
|
+
class SkillConfig(BaseModel):
|
|
272
|
+
"""Skill system configuration."""
|
|
273
|
+
|
|
274
|
+
# Explicit deployment lists (simplified model)
|
|
275
|
+
enabled: List[str] = Field(
|
|
276
|
+
default_factory=list,
|
|
277
|
+
description="Explicit list of skill IDs to deploy (includes agent dependencies)",
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
auto_detect_dependencies: bool = Field(
|
|
281
|
+
default=True,
|
|
282
|
+
description="Automatically include skills required by enabled agents",
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
|
|
242
286
|
class UnifiedConfig(BaseSettings):
|
|
243
287
|
"""
|
|
244
288
|
Unified configuration model for Claude MPM.
|
|
@@ -258,6 +302,7 @@ class UnifiedConfig(BaseSettings):
|
|
|
258
302
|
network: NetworkConfig = Field(default_factory=NetworkConfig)
|
|
259
303
|
logging: LoggingConfig = Field(default_factory=LoggingConfig)
|
|
260
304
|
agents: AgentConfig = Field(default_factory=AgentConfig)
|
|
305
|
+
skills: SkillConfig = Field(default_factory=SkillConfig)
|
|
261
306
|
memory: MemoryConfig = Field(default_factory=MemoryConfig)
|
|
262
307
|
security: SecurityConfig = Field(default_factory=SecurityConfig)
|
|
263
308
|
performance: PerformanceConfig = Field(default_factory=PerformanceConfig)
|
|
@@ -287,8 +332,9 @@ class UnifiedConfig(BaseSettings):
|
|
|
287
332
|
validate_assignment = True
|
|
288
333
|
extra = "allow" # Allow extra fields for backward compatibility
|
|
289
334
|
|
|
290
|
-
@
|
|
291
|
-
|
|
335
|
+
@field_validator("environment")
|
|
336
|
+
@classmethod
|
|
337
|
+
def validate_environment(cls, v):
|
|
292
338
|
valid_envs = ["development", "testing", "production"]
|
|
293
339
|
if v not in valid_envs:
|
|
294
340
|
raise ValueError(f"Invalid environment. Must be one of: {valid_envs}")
|
|
@@ -554,12 +600,12 @@ class ConfigurationService:
|
|
|
554
600
|
import yaml
|
|
555
601
|
|
|
556
602
|
with file_path.open("w") as f:
|
|
557
|
-
yaml.dump(self._config.
|
|
603
|
+
yaml.dump(self._config.model_dump(), f, default_flow_style=False)
|
|
558
604
|
elif format.lower() == "json":
|
|
559
605
|
import json
|
|
560
606
|
|
|
561
607
|
with file_path.open("w") as f:
|
|
562
|
-
json.dump(self._config.
|
|
608
|
+
json.dump(self._config.model_dump(), f, indent=2)
|
|
563
609
|
else:
|
|
564
610
|
raise ConfigurationError(f"Unsupported export format: {format}")
|
|
565
611
|
|