claude-mpm 5.4.41__py3-none-any.whl → 5.6.72__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 +109 -1925
- claude_mpm/agents/PM_INSTRUCTIONS.md +161 -298
- claude_mpm/agents/WORKFLOW.md +2 -0
- claude_mpm/agents/templates/circuit-breakers.md +26 -17
- claude_mpm/auth/__init__.py +35 -0
- claude_mpm/auth/callback_server.py +328 -0
- claude_mpm/auth/models.py +104 -0
- claude_mpm/auth/oauth_manager.py +266 -0
- claude_mpm/auth/providers/__init__.py +12 -0
- claude_mpm/auth/providers/base.py +165 -0
- claude_mpm/auth/providers/google.py +261 -0
- claude_mpm/auth/token_storage.py +252 -0
- 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 +216 -0
- claude_mpm/cli/commands/configure.py +620 -21
- claude_mpm/cli/commands/configure_agent_display.py +3 -1
- claude_mpm/cli/commands/hook_errors.py +60 -60
- claude_mpm/cli/commands/mcp.py +29 -17
- claude_mpm/cli/commands/mcp_command_router.py +39 -0
- claude_mpm/cli/commands/mcp_service_commands.py +304 -0
- claude_mpm/cli/commands/monitor.py +2 -2
- claude_mpm/cli/commands/mpm_init/core.py +15 -8
- claude_mpm/cli/commands/oauth.py +481 -0
- claude_mpm/cli/commands/profile.py +9 -10
- claude_mpm/cli/commands/run.py +35 -3
- claude_mpm/cli/commands/skill_source.py +51 -2
- claude_mpm/cli/commands/skills.py +182 -32
- claude_mpm/cli/executor.py +129 -16
- claude_mpm/cli/helpers.py +1 -1
- 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 +89 -1
- claude_mpm/cli/parsers/commander_parser.py +116 -0
- claude_mpm/cli/parsers/mcp_parser.py +79 -0
- claude_mpm/cli/parsers/oauth_parser.py +165 -0
- claude_mpm/cli/parsers/profile_parser.py +0 -1
- 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 +2 -3
- claude_mpm/cli/startup.py +662 -524
- claude_mpm/cli/startup_display.py +76 -7
- 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 +149 -0
- claude_mpm/commander/chat/commands.py +122 -0
- claude_mpm/commander/chat/repl.py +1821 -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 +392 -0
- claude_mpm/commander/frameworks/__init__.py +12 -0
- claude_mpm/commander/frameworks/base.py +233 -0
- claude_mpm/commander/frameworks/claude_code.py +58 -0
- claude_mpm/commander/frameworks/mpm.py +57 -0
- claude_mpm/commander/git/__init__.py +5 -0
- claude_mpm/commander/git/worktree_manager.py +212 -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 +865 -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 +127 -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 +403 -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 +362 -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 +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 +6 -0
- claude_mpm/core/claude_runner.py +154 -2
- claude_mpm/core/config.py +35 -22
- claude_mpm/core/config_constants.py +74 -9
- claude_mpm/core/constants.py +56 -12
- claude_mpm/core/hook_manager.py +53 -4
- claude_mpm/core/interactive_session.py +12 -11
- claude_mpm/core/logger.py +26 -9
- claude_mpm/core/logging_utils.py +39 -13
- claude_mpm/core/network_config.py +148 -0
- claude_mpm/core/oneshot_session.py +7 -6
- claude_mpm/core/optimized_startup.py +3 -1
- claude_mpm/core/output_style_manager.py +66 -18
- claude_mpm/core/shared/config_loader.py +3 -1
- claude_mpm/core/socketio_pool.py +47 -15
- 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/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/{uj46x2Wr.js → BSNlmTZj.js} +1 -1
- 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/{N4qtv3Hx.js → DR8nis88.js} +2 -2
- 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/{DjhvlsAc.js → NqQ1dWOy.js} +1 -1
- 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.CAGBuiOw.js → 0.RgBboRvH.js} +1 -1
- 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 -1
- claude_mpm/dashboard/static/svelte-build/index.html +11 -11
- 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__/auto_pause_handler.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/auto_pause_handler.py +485 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +466 -136
- claude_mpm/hooks/claude_hooks/hook_handler.py +204 -104
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
- claude_mpm/hooks/claude_hooks/installer.py +291 -59
- claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
- claude_mpm/hooks/claude_hooks/response_tracking.py +43 -60
- claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
- 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__/container.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/protocols.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 +41 -26
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
- claude_mpm/hooks/claude_hooks/services/container.py +326 -0
- claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
- claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +75 -77
- claude_mpm/hooks/kuzu_memory_hook.py +5 -5
- claude_mpm/hooks/session_resume_hook.py +89 -1
- claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
- claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
- claude_mpm/init.py +224 -4
- claude_mpm/mcp/__init__.py +9 -0
- claude_mpm/mcp/google_workspace_server.py +610 -0
- claude_mpm/scripts/claude-hook-handler.sh +46 -19
- 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/agent_discovery_service.py +3 -1
- claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
- claude_mpm/services/agents/deployment/agent_template_builder.py +37 -17
- 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 +36 -8
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +50 -26
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/git_source_manager.py +21 -2
- 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/sources/git_source_sync_service.py +116 -5
- 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/command_deployment_service.py +44 -26
- 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/hook_installer_service.py +77 -8
- 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/mcp_config_manager.py +99 -19
- claude_mpm/services/mcp_service_registry.py +294 -0
- claude_mpm/services/monitor/daemon_manager.py +15 -4
- claude_mpm/services/monitor/management/lifecycle.py +8 -3
- claude_mpm/services/monitor/server.py +111 -16
- claude_mpm/services/pm_skills_deployer.py +302 -94
- claude_mpm/services/profile_manager.py +10 -4
- claude_mpm/services/skills/git_skill_source_manager.py +192 -29
- claude_mpm/services/skills/selective_skill_deployer.py +211 -46
- claude_mpm/services/skills/skill_discovery_service.py +74 -4
- claude_mpm/services/skills_deployer.py +192 -70
- claude_mpm/services/socketio/handlers/hook.py +14 -7
- claude_mpm/services/socketio/server/main.py +12 -4
- 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 +29 -23
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/utils/agent_dependency_loader.py +103 -4
- claude_mpm/utils/robust_installer.py +45 -24
- claude_mpm-5.6.72.dist-info/METADATA +416 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/RECORD +477 -159
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/WHEEL +1 -1
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/entry_points.txt +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +0 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +0 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +0 -10
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
- claude_mpm-5.4.41.dist-info/METADATA +0 -998
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/top_level.txt +0 -0
|
@@ -688,13 +688,18 @@ class MPMInitCommand:
|
|
|
688
688
|
return len(text) // 4
|
|
689
689
|
|
|
690
690
|
def _deploy_pm_skills(self) -> None:
|
|
691
|
-
"""Deploy PM skills templates to project .claude
|
|
691
|
+
"""Deploy PM skills templates to project .claude directory.
|
|
692
692
|
|
|
693
|
-
Copies PM skills from bundled templates to .claude
|
|
693
|
+
Copies PM skills from bundled templates to .claude/skills/
|
|
694
694
|
with version tracking and checksum validation.
|
|
695
695
|
"""
|
|
696
696
|
try:
|
|
697
|
-
from rich.progress import
|
|
697
|
+
from rich.progress import (
|
|
698
|
+
BarColumn,
|
|
699
|
+
Progress,
|
|
700
|
+
TaskProgressColumn,
|
|
701
|
+
TextColumn,
|
|
702
|
+
)
|
|
698
703
|
|
|
699
704
|
from claude_mpm.services.pm_skills_deployer import PMSkillsDeployerService
|
|
700
705
|
|
|
@@ -711,7 +716,9 @@ class MPMInitCommand:
|
|
|
711
716
|
task = progress.add_task("", total=None) # Unknown total initially
|
|
712
717
|
|
|
713
718
|
def update_progress(skill_name: str, current: int, total: int) -> None:
|
|
714
|
-
progress.update(
|
|
719
|
+
progress.update(
|
|
720
|
+
task, total=total, completed=current, description=skill_name
|
|
721
|
+
)
|
|
715
722
|
|
|
716
723
|
result = deployer.deploy_pm_skills(
|
|
717
724
|
self.project_path, progress_callback=update_progress
|
|
@@ -729,7 +736,9 @@ class MPMInitCommand:
|
|
|
729
736
|
)
|
|
730
737
|
|
|
731
738
|
if result.errors:
|
|
732
|
-
self.console.print(
|
|
739
|
+
self.console.print(
|
|
740
|
+
f"[yellow]⚠️ {len(result.errors)} errors:[/yellow]"
|
|
741
|
+
)
|
|
733
742
|
for error in result.errors[:3]: # Show first 3 errors
|
|
734
743
|
self.console.print(f" • {error['skill']}: {error['error']}")
|
|
735
744
|
else:
|
|
@@ -744,9 +753,7 @@ class MPMInitCommand:
|
|
|
744
753
|
)
|
|
745
754
|
except Exception as e:
|
|
746
755
|
logger.error(f"Failed to deploy PM skills: {e}")
|
|
747
|
-
self.console.print(
|
|
748
|
-
f"[yellow]⚠️ PM skills deployment failed: {e}[/yellow]"
|
|
749
|
-
)
|
|
756
|
+
self.console.print(f"[yellow]⚠️ PM skills deployment failed: {e}[/yellow]")
|
|
750
757
|
|
|
751
758
|
|
|
752
759
|
__all__ = ["MPMInitCommand"]
|
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
"""
|
|
2
|
+
OAuth management commands for claude-mpm CLI.
|
|
3
|
+
|
|
4
|
+
WHY: Users need a way to manage OAuth authentication for MCP services
|
|
5
|
+
that require OAuth2 flows (e.g., Google Workspace) directly from the terminal.
|
|
6
|
+
|
|
7
|
+
DESIGN DECISIONS:
|
|
8
|
+
- Use BaseCommand for consistent CLI patterns
|
|
9
|
+
- Reuse OAuth logic from commander/chat/repl.py
|
|
10
|
+
- Support multiple credential sources: .env.local, .env, environment variables
|
|
11
|
+
- Provide clear feedback during OAuth flow
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import asyncio
|
|
15
|
+
import json
|
|
16
|
+
import os
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
from rich.console import Console
|
|
21
|
+
from rich.panel import Panel
|
|
22
|
+
from rich.table import Table
|
|
23
|
+
|
|
24
|
+
from ..shared import BaseCommand, CommandResult
|
|
25
|
+
|
|
26
|
+
console = Console()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _load_oauth_credentials_from_env_files() -> tuple[str | None, str | None]:
|
|
30
|
+
"""Load OAuth credentials from .env files.
|
|
31
|
+
|
|
32
|
+
Checks .env.local first (user overrides), then .env.
|
|
33
|
+
Returns tuple of (client_id, client_secret), either may be None.
|
|
34
|
+
"""
|
|
35
|
+
client_id = None
|
|
36
|
+
client_secret = None
|
|
37
|
+
|
|
38
|
+
# Priority order: .env.local first (user overrides), then .env
|
|
39
|
+
env_files = [".env.local", ".env"]
|
|
40
|
+
|
|
41
|
+
for env_file in env_files:
|
|
42
|
+
env_path = Path.cwd() / env_file
|
|
43
|
+
if env_path.exists():
|
|
44
|
+
try:
|
|
45
|
+
with open(env_path) as f:
|
|
46
|
+
for line in f:
|
|
47
|
+
line = line.strip()
|
|
48
|
+
# Skip empty lines and comments
|
|
49
|
+
if not line or line.startswith("#"):
|
|
50
|
+
continue
|
|
51
|
+
if "=" in line:
|
|
52
|
+
key, _, value = line.partition("=")
|
|
53
|
+
key = key.strip()
|
|
54
|
+
value = value.strip().strip('"').strip("'")
|
|
55
|
+
|
|
56
|
+
if key == "GOOGLE_OAUTH_CLIENT_ID" and not client_id:
|
|
57
|
+
client_id = value
|
|
58
|
+
elif (
|
|
59
|
+
key == "GOOGLE_OAUTH_CLIENT_SECRET"
|
|
60
|
+
and not client_secret
|
|
61
|
+
):
|
|
62
|
+
client_secret = value
|
|
63
|
+
|
|
64
|
+
# If we found both, no need to check more files
|
|
65
|
+
if client_id and client_secret:
|
|
66
|
+
break
|
|
67
|
+
except Exception: # nosec B110 - intentionally ignore .env file read errors
|
|
68
|
+
pass
|
|
69
|
+
|
|
70
|
+
return client_id, client_secret
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class OAuthCommand(BaseCommand):
|
|
74
|
+
"""OAuth management command for MCP services."""
|
|
75
|
+
|
|
76
|
+
def __init__(self):
|
|
77
|
+
super().__init__("oauth")
|
|
78
|
+
|
|
79
|
+
def validate_args(self, args) -> str | None:
|
|
80
|
+
"""Validate command arguments."""
|
|
81
|
+
# If no oauth_command specified, default to 'list'
|
|
82
|
+
if not hasattr(args, "oauth_command") or not args.oauth_command:
|
|
83
|
+
args.oauth_command = None # Will show help
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
valid_commands = ["list", "setup", "status", "revoke", "refresh"]
|
|
87
|
+
if args.oauth_command not in valid_commands:
|
|
88
|
+
return f"Unknown oauth command: {args.oauth_command}. Valid commands: {', '.join(valid_commands)}"
|
|
89
|
+
|
|
90
|
+
# Validate service_name for commands that require it
|
|
91
|
+
if args.oauth_command in ["setup", "status", "revoke", "refresh"]:
|
|
92
|
+
if not hasattr(args, "service_name") or not args.service_name:
|
|
93
|
+
return f"oauth {args.oauth_command} requires a service name"
|
|
94
|
+
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
def run(self, args) -> CommandResult:
|
|
98
|
+
"""Execute the OAuth command."""
|
|
99
|
+
# If no subcommand, show help
|
|
100
|
+
if not hasattr(args, "oauth_command") or not args.oauth_command:
|
|
101
|
+
self._show_help()
|
|
102
|
+
return CommandResult.success_result("Help displayed")
|
|
103
|
+
|
|
104
|
+
if args.oauth_command == "list":
|
|
105
|
+
return self._list_services(args)
|
|
106
|
+
if args.oauth_command == "setup":
|
|
107
|
+
return self._setup_oauth(args)
|
|
108
|
+
if args.oauth_command == "status":
|
|
109
|
+
return self._show_status(args)
|
|
110
|
+
if args.oauth_command == "revoke":
|
|
111
|
+
return self._revoke_tokens(args)
|
|
112
|
+
if args.oauth_command == "refresh":
|
|
113
|
+
return self._refresh_tokens(args)
|
|
114
|
+
|
|
115
|
+
return CommandResult.error_result(
|
|
116
|
+
f"Unknown oauth command: {args.oauth_command}"
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
def _show_help(self) -> None:
|
|
120
|
+
"""Display OAuth command help."""
|
|
121
|
+
help_text = """
|
|
122
|
+
[bold]OAuth Commands:[/bold]
|
|
123
|
+
oauth list List OAuth-capable MCP services
|
|
124
|
+
oauth setup <service> Set up OAuth authentication for a service
|
|
125
|
+
oauth status <service> Show OAuth token status for a service
|
|
126
|
+
oauth revoke <service> Revoke OAuth tokens for a service
|
|
127
|
+
oauth refresh <service> Refresh OAuth tokens for a service
|
|
128
|
+
|
|
129
|
+
[bold]Examples:[/bold]
|
|
130
|
+
claude-mpm oauth list
|
|
131
|
+
claude-mpm oauth setup workspace-mcp
|
|
132
|
+
claude-mpm oauth status workspace-mcp
|
|
133
|
+
"""
|
|
134
|
+
console.print(help_text)
|
|
135
|
+
|
|
136
|
+
def _list_services(self, args) -> CommandResult:
|
|
137
|
+
"""List OAuth-capable MCP services."""
|
|
138
|
+
try:
|
|
139
|
+
from claude_mpm.services.mcp_service_registry import MCPServiceRegistry
|
|
140
|
+
|
|
141
|
+
services = MCPServiceRegistry.list_all()
|
|
142
|
+
oauth_services = [s for s in services if s.oauth_provider]
|
|
143
|
+
|
|
144
|
+
if not oauth_services:
|
|
145
|
+
console.print("[yellow]No OAuth-capable services found.[/yellow]")
|
|
146
|
+
return CommandResult.success_result("No OAuth services found")
|
|
147
|
+
|
|
148
|
+
# Check output format
|
|
149
|
+
output_format = getattr(args, "format", "table")
|
|
150
|
+
|
|
151
|
+
if output_format == "json":
|
|
152
|
+
data = [
|
|
153
|
+
{
|
|
154
|
+
"name": s.name,
|
|
155
|
+
"description": s.description,
|
|
156
|
+
"oauth_provider": s.oauth_provider,
|
|
157
|
+
"oauth_scopes": s.oauth_scopes,
|
|
158
|
+
"required_env": s.required_env,
|
|
159
|
+
}
|
|
160
|
+
for s in oauth_services
|
|
161
|
+
]
|
|
162
|
+
console.print(json.dumps(data, indent=2))
|
|
163
|
+
return CommandResult.success_result(
|
|
164
|
+
"Services listed", data={"services": data}
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
# Table format
|
|
168
|
+
table = Table(title="OAuth-Capable MCP Services")
|
|
169
|
+
table.add_column("Service", style="cyan")
|
|
170
|
+
table.add_column("Provider", style="green")
|
|
171
|
+
table.add_column("Description", style="white")
|
|
172
|
+
|
|
173
|
+
for service in oauth_services:
|
|
174
|
+
table.add_row(
|
|
175
|
+
service.name,
|
|
176
|
+
service.oauth_provider or "",
|
|
177
|
+
service.description,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
console.print(table)
|
|
181
|
+
return CommandResult.success_result(
|
|
182
|
+
f"Found {len(oauth_services)} OAuth-capable service(s)"
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
except ImportError:
|
|
186
|
+
return CommandResult.error_result("MCP Service Registry not available")
|
|
187
|
+
except Exception as e:
|
|
188
|
+
return CommandResult.error_result(f"Error listing services: {e}")
|
|
189
|
+
|
|
190
|
+
def _setup_oauth(self, args) -> CommandResult:
|
|
191
|
+
"""Set up OAuth for a service."""
|
|
192
|
+
service_name = args.service_name
|
|
193
|
+
|
|
194
|
+
# Get service info from registry to get provider and scopes
|
|
195
|
+
try:
|
|
196
|
+
from claude_mpm.services.mcp_service_registry import MCPServiceRegistry
|
|
197
|
+
|
|
198
|
+
service = MCPServiceRegistry.get(service_name)
|
|
199
|
+
if not service:
|
|
200
|
+
return CommandResult.error_result(f"Service '{service_name}' not found")
|
|
201
|
+
|
|
202
|
+
provider_name = service.oauth_provider
|
|
203
|
+
if not provider_name:
|
|
204
|
+
return CommandResult.error_result(
|
|
205
|
+
f"Service '{service_name}' does not use OAuth"
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
scopes = service.oauth_scopes or None
|
|
209
|
+
except ImportError:
|
|
210
|
+
return CommandResult.error_result("MCP Service Registry not available")
|
|
211
|
+
|
|
212
|
+
# Priority: 1) .env files, 2) environment variables, 3) interactive prompt
|
|
213
|
+
client_id, client_secret = _load_oauth_credentials_from_env_files()
|
|
214
|
+
|
|
215
|
+
# Fall back to environment variables if not found in .env files
|
|
216
|
+
if not client_id:
|
|
217
|
+
client_id = os.environ.get("GOOGLE_OAUTH_CLIENT_ID")
|
|
218
|
+
if not client_secret:
|
|
219
|
+
client_secret = os.environ.get("GOOGLE_OAUTH_CLIENT_SECRET")
|
|
220
|
+
|
|
221
|
+
# Set credentials in environment so OAuth provider can access them
|
|
222
|
+
if client_id and client_secret:
|
|
223
|
+
os.environ["GOOGLE_OAUTH_CLIENT_ID"] = client_id
|
|
224
|
+
os.environ["GOOGLE_OAUTH_CLIENT_SECRET"] = client_secret
|
|
225
|
+
|
|
226
|
+
# If credentials missing, prompt for them interactively
|
|
227
|
+
if not client_id or not client_secret:
|
|
228
|
+
console.print("\n[yellow]Google OAuth credentials not found.[/yellow]")
|
|
229
|
+
console.print("Checked: .env.local, .env, and environment variables.\n")
|
|
230
|
+
console.print(
|
|
231
|
+
"Get credentials from: https://console.cloud.google.com/apis/credentials\n"
|
|
232
|
+
)
|
|
233
|
+
console.print("[dim]Tip: Add to .env.local for automatic loading:[/dim]")
|
|
234
|
+
console.print('[dim] GOOGLE_OAUTH_CLIENT_ID="your-client-id"[/dim]')
|
|
235
|
+
console.print(
|
|
236
|
+
'[dim] GOOGLE_OAUTH_CLIENT_SECRET="your-client-secret"[/dim]\n' # pragma: allowlist secret
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
try:
|
|
240
|
+
from prompt_toolkit import prompt as pt_prompt
|
|
241
|
+
|
|
242
|
+
client_id = pt_prompt("Enter GOOGLE_OAUTH_CLIENT_ID: ")
|
|
243
|
+
if not client_id.strip():
|
|
244
|
+
return CommandResult.error_result("Client ID is required")
|
|
245
|
+
|
|
246
|
+
client_secret = pt_prompt(
|
|
247
|
+
"Enter GOOGLE_OAUTH_CLIENT_SECRET: ", is_password=True
|
|
248
|
+
)
|
|
249
|
+
if not client_secret.strip():
|
|
250
|
+
return CommandResult.error_result("Client Secret is required")
|
|
251
|
+
|
|
252
|
+
# Set in environment for this session
|
|
253
|
+
os.environ["GOOGLE_OAUTH_CLIENT_ID"] = client_id.strip()
|
|
254
|
+
os.environ["GOOGLE_OAUTH_CLIENT_SECRET"] = client_secret.strip()
|
|
255
|
+
console.print("\n[green]Credentials set for this session.[/green]")
|
|
256
|
+
|
|
257
|
+
except (EOFError, KeyboardInterrupt):
|
|
258
|
+
return CommandResult.error_result("Credential entry cancelled")
|
|
259
|
+
except ImportError:
|
|
260
|
+
return CommandResult.error_result(
|
|
261
|
+
"prompt_toolkit not available for interactive input. "
|
|
262
|
+
"Please set GOOGLE_OAUTH_CLIENT_ID and GOOGLE_OAUTH_CLIENT_SECRET environment variables."
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
# Run OAuth flow
|
|
266
|
+
try:
|
|
267
|
+
from claude_mpm.auth import OAuthManager
|
|
268
|
+
from claude_mpm.auth.callback_server import DEFAULT_PORT
|
|
269
|
+
from claude_mpm.auth.providers.google import OAuthError
|
|
270
|
+
|
|
271
|
+
manager = OAuthManager()
|
|
272
|
+
|
|
273
|
+
# Get the actual callback port from the server
|
|
274
|
+
callback_port = DEFAULT_PORT
|
|
275
|
+
no_browser = getattr(args, "no_browser", False)
|
|
276
|
+
|
|
277
|
+
console.print(f"\n[cyan]Setting up OAuth for '{service_name}'...[/cyan]")
|
|
278
|
+
console.print(
|
|
279
|
+
f"Callback server listening on http://localhost:{callback_port}/callback"
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
if not no_browser:
|
|
283
|
+
console.print("Opening browser for authentication...")
|
|
284
|
+
else:
|
|
285
|
+
console.print(
|
|
286
|
+
"[yellow]Browser auto-open disabled. Please open the URL manually.[/yellow]"
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
# Run async OAuth flow - authenticate returns OAuthToken directly
|
|
290
|
+
# and raises OAuthError on failure
|
|
291
|
+
token = asyncio.run(
|
|
292
|
+
manager.authenticate(
|
|
293
|
+
service_name=service_name,
|
|
294
|
+
provider_name=provider_name,
|
|
295
|
+
scopes=scopes,
|
|
296
|
+
open_browser=not no_browser,
|
|
297
|
+
)
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
# Success - token was returned
|
|
301
|
+
console.print(f"\n[green]OAuth setup complete for '{service_name}'[/green]")
|
|
302
|
+
if token.expires_at:
|
|
303
|
+
console.print(f" Token expires: {token.expires_at}")
|
|
304
|
+
return CommandResult.success_result(
|
|
305
|
+
f"OAuth setup complete for '{service_name}'"
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
except OAuthError as e:
|
|
309
|
+
return CommandResult.error_result(f"OAuth setup failed: {e}")
|
|
310
|
+
except ImportError as e:
|
|
311
|
+
return CommandResult.error_result(f"OAuth module not available: {e}")
|
|
312
|
+
except Exception as e:
|
|
313
|
+
return CommandResult.error_result(f"Error during OAuth setup: {e}")
|
|
314
|
+
|
|
315
|
+
def _show_status(self, args) -> CommandResult:
|
|
316
|
+
"""Show OAuth token status for a service."""
|
|
317
|
+
service_name = args.service_name
|
|
318
|
+
|
|
319
|
+
try:
|
|
320
|
+
from claude_mpm.auth import OAuthManager
|
|
321
|
+
from claude_mpm.auth.models import TokenStatus
|
|
322
|
+
|
|
323
|
+
manager = OAuthManager()
|
|
324
|
+
# get_status is synchronous and returns (TokenStatus, StoredToken | None)
|
|
325
|
+
token_status, stored_token = manager.get_status(service_name)
|
|
326
|
+
|
|
327
|
+
if token_status == TokenStatus.MISSING or stored_token is None:
|
|
328
|
+
console.print(
|
|
329
|
+
f"[yellow]No OAuth tokens found for '{service_name}'[/yellow]"
|
|
330
|
+
)
|
|
331
|
+
return CommandResult.success_result(
|
|
332
|
+
f"No tokens found for '{service_name}'"
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
# Build status dict for display
|
|
336
|
+
is_valid = token_status == TokenStatus.VALID
|
|
337
|
+
status_data = {
|
|
338
|
+
"valid": is_valid,
|
|
339
|
+
"status": token_status.name,
|
|
340
|
+
"expires_at": stored_token.token.expires_at,
|
|
341
|
+
"scopes": stored_token.token.scopes,
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
# Check output format
|
|
345
|
+
output_format = getattr(args, "format", "table")
|
|
346
|
+
|
|
347
|
+
if output_format == "json":
|
|
348
|
+
console.print(json.dumps(status_data, indent=2, default=str))
|
|
349
|
+
return CommandResult.success_result(
|
|
350
|
+
"Status displayed", data=status_data
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
# Table format
|
|
354
|
+
self._print_token_status(service_name, status_data)
|
|
355
|
+
return CommandResult.success_result("Status displayed")
|
|
356
|
+
|
|
357
|
+
except ImportError:
|
|
358
|
+
return CommandResult.error_result("OAuth module not available")
|
|
359
|
+
except Exception as e:
|
|
360
|
+
return CommandResult.error_result(f"Error checking status: {e}")
|
|
361
|
+
|
|
362
|
+
def _print_token_status(self, name: str, status: dict[str, Any]) -> None:
|
|
363
|
+
"""Print token status information."""
|
|
364
|
+
panel_content = []
|
|
365
|
+
panel_content.append(f"[bold]Service:[/bold] {name}")
|
|
366
|
+
panel_content.append("[bold]Stored:[/bold] Yes")
|
|
367
|
+
|
|
368
|
+
if status.get("valid"):
|
|
369
|
+
panel_content.append("[bold]Status:[/bold] [green]Valid[/green]")
|
|
370
|
+
else:
|
|
371
|
+
panel_content.append("[bold]Status:[/bold] [red]Invalid/Expired[/red]")
|
|
372
|
+
|
|
373
|
+
if status.get("expires_at"):
|
|
374
|
+
panel_content.append(f"[bold]Expires:[/bold] {status['expires_at']}")
|
|
375
|
+
|
|
376
|
+
if status.get("scopes"):
|
|
377
|
+
scopes = ", ".join(status["scopes"])
|
|
378
|
+
panel_content.append(f"[bold]Scopes:[/bold] {scopes}")
|
|
379
|
+
|
|
380
|
+
panel = Panel(
|
|
381
|
+
"\n".join(panel_content),
|
|
382
|
+
title="OAuth Token Status",
|
|
383
|
+
border_style="green" if status.get("valid") else "red",
|
|
384
|
+
)
|
|
385
|
+
console.print(panel)
|
|
386
|
+
|
|
387
|
+
def _revoke_tokens(self, args) -> CommandResult:
|
|
388
|
+
"""Revoke OAuth tokens for a service."""
|
|
389
|
+
service_name = args.service_name
|
|
390
|
+
|
|
391
|
+
# Confirm unless -y flag
|
|
392
|
+
if not getattr(args, "yes", False):
|
|
393
|
+
console.print(
|
|
394
|
+
f"[yellow]This will revoke OAuth tokens for '{service_name}'.[/yellow]"
|
|
395
|
+
)
|
|
396
|
+
try:
|
|
397
|
+
from prompt_toolkit import prompt as pt_prompt
|
|
398
|
+
|
|
399
|
+
confirm = pt_prompt("Are you sure? (y/N): ")
|
|
400
|
+
if confirm.lower() not in ("y", "yes"):
|
|
401
|
+
return CommandResult.success_result("Revocation cancelled")
|
|
402
|
+
except (EOFError, KeyboardInterrupt):
|
|
403
|
+
return CommandResult.success_result("Revocation cancelled")
|
|
404
|
+
except ImportError:
|
|
405
|
+
# No prompt_toolkit, proceed without confirmation
|
|
406
|
+
pass
|
|
407
|
+
|
|
408
|
+
try:
|
|
409
|
+
from claude_mpm.auth import OAuthManager
|
|
410
|
+
|
|
411
|
+
manager = OAuthManager()
|
|
412
|
+
|
|
413
|
+
console.print(f"[cyan]Revoking OAuth tokens for '{service_name}'...[/cyan]")
|
|
414
|
+
# revoke() returns bool directly
|
|
415
|
+
revoked = asyncio.run(manager.revoke(service_name))
|
|
416
|
+
|
|
417
|
+
if revoked:
|
|
418
|
+
console.print(
|
|
419
|
+
f"[green]OAuth tokens revoked for '{service_name}'[/green]"
|
|
420
|
+
)
|
|
421
|
+
return CommandResult.success_result(
|
|
422
|
+
f"Tokens revoked for '{service_name}'"
|
|
423
|
+
)
|
|
424
|
+
return CommandResult.error_result(
|
|
425
|
+
f"Failed to revoke tokens for '{service_name}'"
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
except ImportError:
|
|
429
|
+
return CommandResult.error_result("OAuth module not available")
|
|
430
|
+
except Exception as e:
|
|
431
|
+
return CommandResult.error_result(f"Error revoking tokens: {e}")
|
|
432
|
+
|
|
433
|
+
def _refresh_tokens(self, args) -> CommandResult:
|
|
434
|
+
"""Refresh OAuth tokens for a service."""
|
|
435
|
+
service_name = args.service_name
|
|
436
|
+
|
|
437
|
+
try:
|
|
438
|
+
from claude_mpm.auth import OAuthManager
|
|
439
|
+
from claude_mpm.auth.providers.google import OAuthError
|
|
440
|
+
|
|
441
|
+
manager = OAuthManager()
|
|
442
|
+
|
|
443
|
+
console.print(
|
|
444
|
+
f"[cyan]Refreshing OAuth tokens for '{service_name}'...[/cyan]"
|
|
445
|
+
)
|
|
446
|
+
# refresh_if_needed() returns Optional[OAuthToken]
|
|
447
|
+
token = asyncio.run(manager.refresh_if_needed(service_name))
|
|
448
|
+
|
|
449
|
+
if token is not None:
|
|
450
|
+
console.print(
|
|
451
|
+
f"[green]OAuth tokens refreshed for '{service_name}'[/green]"
|
|
452
|
+
)
|
|
453
|
+
if token.expires_at:
|
|
454
|
+
console.print(f" New expiry: {token.expires_at}")
|
|
455
|
+
return CommandResult.success_result(
|
|
456
|
+
f"Tokens refreshed for '{service_name}'"
|
|
457
|
+
)
|
|
458
|
+
return CommandResult.error_result(
|
|
459
|
+
f"Failed to refresh tokens for '{service_name}' - no token found or no refresh token available"
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
except OAuthError as e:
|
|
463
|
+
return CommandResult.error_result(f"Failed to refresh: {e}")
|
|
464
|
+
except ImportError:
|
|
465
|
+
return CommandResult.error_result("OAuth module not available")
|
|
466
|
+
except Exception as e:
|
|
467
|
+
return CommandResult.error_result(f"Error refreshing tokens: {e}")
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
def manage_oauth(args) -> int:
|
|
471
|
+
"""Main entry point for OAuth management commands.
|
|
472
|
+
|
|
473
|
+
Args:
|
|
474
|
+
args: Parsed command line arguments
|
|
475
|
+
|
|
476
|
+
Returns:
|
|
477
|
+
Exit code (0 for success, non-zero for errors)
|
|
478
|
+
"""
|
|
479
|
+
command = OAuthCommand()
|
|
480
|
+
result = command.execute(args)
|
|
481
|
+
return result.exit_code
|
|
@@ -13,10 +13,8 @@ DESIGN DECISIONS:
|
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
15
|
from pathlib import Path
|
|
16
|
-
from typing import Any, Dict
|
|
17
16
|
|
|
18
17
|
import yaml
|
|
19
|
-
from rich.console import Console
|
|
20
18
|
from rich.table import Table
|
|
21
19
|
|
|
22
20
|
from ...core.shared.config_loader import ConfigLoader
|
|
@@ -63,16 +61,15 @@ class ProfileCommand(BaseCommand):
|
|
|
63
61
|
try:
|
|
64
62
|
if args.profile_command == "list":
|
|
65
63
|
return self._list_profiles(args)
|
|
66
|
-
|
|
64
|
+
if args.profile_command == "set":
|
|
67
65
|
return self._set_profile(args)
|
|
68
|
-
|
|
66
|
+
if args.profile_command == "status":
|
|
69
67
|
return self._show_status(args)
|
|
70
|
-
|
|
68
|
+
if args.profile_command == "show":
|
|
71
69
|
return self._show_profile(args)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
)
|
|
70
|
+
return CommandResult.error_result(
|
|
71
|
+
f"Unknown profile command: {args.profile_command}"
|
|
72
|
+
)
|
|
76
73
|
except Exception as e:
|
|
77
74
|
return CommandResult.error_result(f"Profile command failed: {e}")
|
|
78
75
|
|
|
@@ -145,7 +142,9 @@ class ProfileCommand(BaseCommand):
|
|
|
145
142
|
|
|
146
143
|
# Show summary
|
|
147
144
|
summary = self.profile_manager.get_filtering_summary()
|
|
148
|
-
console.print(
|
|
145
|
+
console.print(
|
|
146
|
+
f"[green]✓[/green] Active profile set to: [cyan]{profile_name}[/cyan]"
|
|
147
|
+
)
|
|
149
148
|
console.print(
|
|
150
149
|
f" Agents enabled: [cyan]{summary['enabled_agents_count']}[/cyan]"
|
|
151
150
|
)
|
claude_mpm/cli/commands/run.py
CHANGED
|
@@ -13,7 +13,7 @@ DESIGN DECISIONS:
|
|
|
13
13
|
- Support multiple output formats (json, yaml, table, text)
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
|
-
import subprocess
|
|
16
|
+
import subprocess # nosec B404 - required for process management
|
|
17
17
|
import sys
|
|
18
18
|
from datetime import datetime, timezone
|
|
19
19
|
from typing import Optional
|
|
@@ -489,6 +489,18 @@ class RunCommand(BaseCommand):
|
|
|
489
489
|
if hasattr(args, "claude_args") and args.claude_args:
|
|
490
490
|
claude_args.extend(args.claude_args)
|
|
491
491
|
|
|
492
|
+
# Add --resume if flag is set
|
|
493
|
+
if getattr(args, "resume", False) and "--resume" not in claude_args:
|
|
494
|
+
claude_args.insert(0, "--resume")
|
|
495
|
+
|
|
496
|
+
# Add --chrome if flag is set
|
|
497
|
+
if getattr(args, "chrome", False) and "--chrome" not in claude_args:
|
|
498
|
+
claude_args.insert(0, "--chrome")
|
|
499
|
+
|
|
500
|
+
# Add --no-chrome if flag is set
|
|
501
|
+
if getattr(args, "no_chrome", False) and "--no-chrome" not in claude_args:
|
|
502
|
+
claude_args.insert(0, "--no-chrome")
|
|
503
|
+
|
|
492
504
|
# Create runner
|
|
493
505
|
runner = ClaudeRunner(
|
|
494
506
|
enable_tickets=enable_tickets,
|
|
@@ -553,7 +565,7 @@ class RunCommand(BaseCommand):
|
|
|
553
565
|
wrapper_path = get_scripts_dir() / "interactive_wrapper.py"
|
|
554
566
|
if wrapper_path.exists():
|
|
555
567
|
print("Starting interactive session with command interception...")
|
|
556
|
-
subprocess.run([sys.executable, str(wrapper_path)], check=False)
|
|
568
|
+
subprocess.run([sys.executable, str(wrapper_path)], check=False) # nosec B603 - trusted internal paths
|
|
557
569
|
else:
|
|
558
570
|
self.logger.warning(
|
|
559
571
|
"Interactive wrapper not found, falling back to normal mode"
|
|
@@ -907,6 +919,26 @@ def run_session_legacy(args):
|
|
|
907
919
|
else:
|
|
908
920
|
logger.info("[INFO]️ --resume already in claude_args")
|
|
909
921
|
|
|
922
|
+
# Add --chrome to claude_args if the flag is set
|
|
923
|
+
chrome_flag_present = getattr(args, "chrome", False)
|
|
924
|
+
if chrome_flag_present:
|
|
925
|
+
logger.info("📌 --chrome flag detected in args")
|
|
926
|
+
if "--chrome" not in raw_claude_args:
|
|
927
|
+
raw_claude_args = ["--chrome", *raw_claude_args]
|
|
928
|
+
logger.info("✅ Added --chrome to claude_args")
|
|
929
|
+
else:
|
|
930
|
+
logger.info("ℹ️ --chrome already in claude_args")
|
|
931
|
+
|
|
932
|
+
# Add --no-chrome to claude_args if the flag is set
|
|
933
|
+
no_chrome_flag_present = getattr(args, "no_chrome", False)
|
|
934
|
+
if no_chrome_flag_present:
|
|
935
|
+
logger.info("📌 --no-chrome flag detected in args")
|
|
936
|
+
if "--no-chrome" not in raw_claude_args:
|
|
937
|
+
raw_claude_args = ["--no-chrome", *raw_claude_args]
|
|
938
|
+
logger.info("✅ Added --no-chrome to claude_args")
|
|
939
|
+
else:
|
|
940
|
+
logger.info("ℹ️ --no-chrome already in claude_args")
|
|
941
|
+
|
|
910
942
|
# Filter out claude-mpm specific flags before passing to Claude CLI
|
|
911
943
|
logger.debug(f"Pre-filter claude_args: {raw_claude_args}")
|
|
912
944
|
claude_args = filter_claude_mpm_args(raw_claude_args)
|
|
@@ -1044,7 +1076,7 @@ def run_session_legacy(args):
|
|
|
1044
1076
|
wrapper_path = get_scripts_dir() / "interactive_wrapper.py"
|
|
1045
1077
|
if wrapper_path.exists():
|
|
1046
1078
|
print("Starting interactive session with command interception...")
|
|
1047
|
-
subprocess.run([sys.executable, str(wrapper_path)], check=False)
|
|
1079
|
+
subprocess.run([sys.executable, str(wrapper_path)], check=False) # nosec B603 - trusted internal paths
|
|
1048
1080
|
else:
|
|
1049
1081
|
logger.warning("Interactive wrapper not found, falling back to normal mode")
|
|
1050
1082
|
runner.run_interactive(context)
|