claude-mpm 5.6.1__py3-none-any.whl → 5.6.76__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/PM_INSTRUCTIONS.md +8 -3
- 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/commands/commander.py +174 -4
- 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/oauth.py +481 -0
- claude_mpm/cli/commands/skill_source.py +51 -2
- claude_mpm/cli/commands/skills.py +5 -3
- claude_mpm/cli/executor.py +9 -0
- claude_mpm/cli/helpers.py +1 -1
- claude_mpm/cli/parsers/base_parser.py +13 -0
- claude_mpm/cli/parsers/commander_parser.py +43 -10
- claude_mpm/cli/parsers/mcp_parser.py +79 -0
- claude_mpm/cli/parsers/oauth_parser.py +165 -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 +300 -33
- claude_mpm/cli/startup_display.py +4 -2
- claude_mpm/cli/startup_migrations.py +236 -0
- claude_mpm/commander/__init__.py +6 -0
- claude_mpm/commander/adapters/__init__.py +32 -3
- claude_mpm/commander/adapters/auggie.py +260 -0
- claude_mpm/commander/adapters/base.py +98 -1
- claude_mpm/commander/adapters/claude_code.py +32 -1
- claude_mpm/commander/adapters/codex.py +237 -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/app.py +32 -16
- claude_mpm/commander/api/errors.py +21 -0
- claude_mpm/commander/api/routes/messages.py +11 -11
- claude_mpm/commander/api/routes/projects.py +20 -20
- claude_mpm/commander/api/routes/sessions.py +37 -26
- claude_mpm/commander/api/routes/work.py +86 -50
- claude_mpm/commander/api/schemas.py +4 -0
- claude_mpm/commander/chat/cli.py +47 -5
- claude_mpm/commander/chat/commands.py +44 -16
- claude_mpm/commander/chat/repl.py +1729 -82
- claude_mpm/commander/config.py +5 -3
- 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 +215 -10
- claude_mpm/commander/env_loader.py +59 -0
- claude_mpm/commander/events/manager.py +61 -1
- claude_mpm/commander/frameworks/base.py +91 -1
- claude_mpm/commander/frameworks/mpm.py +9 -14
- claude_mpm/commander/git/__init__.py +5 -0
- claude_mpm/commander/git/worktree_manager.py +212 -0
- claude_mpm/commander/instance_manager.py +546 -15
- 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/events.py +6 -0
- claude_mpm/commander/persistence/state_store.py +95 -1
- claude_mpm/commander/registry.py +10 -4
- claude_mpm/commander/runtime/monitor.py +32 -2
- claude_mpm/commander/tmux_orchestrator.py +3 -2
- claude_mpm/commander/work/executor.py +38 -20
- claude_mpm/commander/workflow/event_handler.py +25 -3
- claude_mpm/config/skill_sources.py +16 -0
- claude_mpm/constants.py +5 -0
- claude_mpm/core/claude_runner.py +152 -0
- claude_mpm/core/config.py +30 -22
- claude_mpm/core/config_constants.py +74 -9
- claude_mpm/core/constants.py +56 -12
- claude_mpm/core/hook_manager.py +2 -1
- claude_mpm/core/interactive_session.py +5 -4
- claude_mpm/core/logger.py +16 -2
- claude_mpm/core/logging_utils.py +40 -16
- claude_mpm/core/network_config.py +148 -0
- claude_mpm/core/oneshot_session.py +7 -6
- claude_mpm/core/output_style_manager.py +37 -7
- claude_mpm/core/socketio_pool.py +47 -15
- claude_mpm/core/unified_paths.py +68 -80
- claude_mpm/hooks/claude_hooks/auto_pause_handler.py +30 -31
- claude_mpm/hooks/claude_hooks/event_handlers.py +285 -194
- claude_mpm/hooks/claude_hooks/hook_handler.py +115 -32
- claude_mpm/hooks/claude_hooks/installer.py +222 -54
- claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
- claude_mpm/hooks/claude_hooks/response_tracking.py +40 -59
- claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +25 -30
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +24 -28
- 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 +49 -75
- claude_mpm/hooks/session_resume_hook.py +22 -18
- 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 +21 -14
- claude_mpm/mcp/__init__.py +9 -0
- claude_mpm/mcp/google_workspace_server.py +610 -0
- claude_mpm/scripts/claude-hook-handler.sh +10 -9
- claude_mpm/services/agents/agent_selection_service.py +2 -2
- claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
- claude_mpm/services/command_deployment_service.py +44 -26
- claude_mpm/services/hook_installer_service.py +77 -8
- claude_mpm/services/mcp_config_manager.py +99 -19
- claude_mpm/services/mcp_service_registry.py +294 -0
- claude_mpm/services/monitor/server.py +6 -1
- claude_mpm/services/pm_skills_deployer.py +5 -3
- claude_mpm/services/skills/git_skill_source_manager.py +79 -8
- claude_mpm/services/skills/selective_skill_deployer.py +28 -0
- claude_mpm/services/skills/skill_discovery_service.py +17 -1
- claude_mpm/services/skills_deployer.py +31 -5
- claude_mpm/skills/__init__.py +2 -1
- claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
- claude_mpm/skills/registry.py +295 -90
- {claude_mpm-5.6.1.dist-info → claude_mpm-5.6.76.dist-info}/METADATA +28 -3
- {claude_mpm-5.6.1.dist-info → claude_mpm-5.6.76.dist-info}/RECORD +131 -93
- {claude_mpm-5.6.1.dist-info → claude_mpm-5.6.76.dist-info}/WHEEL +1 -1
- {claude_mpm-5.6.1.dist-info → claude_mpm-5.6.76.dist-info}/entry_points.txt +2 -0
- {claude_mpm-5.6.1.dist-info → claude_mpm-5.6.76.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.6.1.dist-info → claude_mpm-5.6.76.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.6.1.dist-info → claude_mpm-5.6.76.dist-info}/top_level.txt +0 -0
claude_mpm/commander/chat/cli.py
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import logging
|
|
5
|
+
from dataclasses import dataclass
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
from typing import Optional
|
|
7
8
|
|
|
9
|
+
from claude_mpm.commander.env_loader import load_env
|
|
8
10
|
from claude_mpm.commander.instance_manager import InstanceManager
|
|
9
11
|
from claude_mpm.commander.llm.openrouter_client import (
|
|
10
12
|
OpenRouterClient,
|
|
@@ -19,28 +21,61 @@ from claude_mpm.commander.tmux_orchestrator import TmuxOrchestrator
|
|
|
19
21
|
|
|
20
22
|
from .repl import CommanderREPL
|
|
21
23
|
|
|
24
|
+
# Load environment variables at module import
|
|
25
|
+
load_env()
|
|
26
|
+
|
|
22
27
|
logger = logging.getLogger(__name__)
|
|
23
28
|
|
|
24
29
|
|
|
30
|
+
@dataclass
|
|
31
|
+
class CommanderCLIConfig:
|
|
32
|
+
"""Configuration for Commander CLI mode.
|
|
33
|
+
|
|
34
|
+
Attributes:
|
|
35
|
+
summarize_responses: Whether to use LLM to summarize instance responses
|
|
36
|
+
port: Port for internal services (reserved for future use)
|
|
37
|
+
state_dir: Directory for state persistence (optional)
|
|
38
|
+
|
|
39
|
+
Example:
|
|
40
|
+
>>> config = CommanderCLIConfig(summarize_responses=False)
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
summarize_responses: bool = True
|
|
44
|
+
port: int = 8765
|
|
45
|
+
state_dir: Optional[Path] = None
|
|
46
|
+
|
|
47
|
+
|
|
25
48
|
async def run_commander(
|
|
26
49
|
port: int = 8765,
|
|
27
50
|
state_dir: Optional[Path] = None,
|
|
51
|
+
config: Optional[CommanderCLIConfig] = None,
|
|
28
52
|
) -> None:
|
|
29
53
|
"""Run Commander in interactive mode.
|
|
30
54
|
|
|
31
55
|
Args:
|
|
32
56
|
port: Port for internal services (unused currently).
|
|
33
57
|
state_dir: Directory for state persistence (optional).
|
|
58
|
+
config: Commander CLI configuration (optional, uses defaults if None).
|
|
34
59
|
|
|
35
60
|
Example:
|
|
36
61
|
>>> asyncio.run(run_commander())
|
|
37
62
|
# Starts interactive Commander REPL
|
|
63
|
+
>>> config = CommanderCLIConfig(summarize_responses=False)
|
|
64
|
+
>>> asyncio.run(run_commander(config=config))
|
|
65
|
+
# Starts Commander without response summarization
|
|
38
66
|
"""
|
|
39
|
-
#
|
|
67
|
+
# Use default config if not provided
|
|
68
|
+
if config is None:
|
|
69
|
+
config = CommanderCLIConfig(port=port, state_dir=state_dir)
|
|
70
|
+
|
|
71
|
+
# Setup logging - suppress noisy libraries
|
|
40
72
|
logging.basicConfig(
|
|
41
73
|
level=logging.INFO,
|
|
42
|
-
format="%(asctime)s
|
|
74
|
+
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
|
43
75
|
)
|
|
76
|
+
# Suppress httpx request logging (very verbose)
|
|
77
|
+
logging.getLogger("httpx").setLevel(logging.WARNING)
|
|
78
|
+
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
|
44
79
|
|
|
45
80
|
# Initialize components
|
|
46
81
|
logger.info("Initializing Commander...")
|
|
@@ -57,8 +92,8 @@ async def run_commander(
|
|
|
57
92
|
# Try to initialize LLM client (optional)
|
|
58
93
|
llm_client: Optional[OpenRouterClient] = None
|
|
59
94
|
try:
|
|
60
|
-
|
|
61
|
-
llm_client = OpenRouterClient(
|
|
95
|
+
llm_config = OpenRouterConfig()
|
|
96
|
+
llm_client = OpenRouterClient(llm_config)
|
|
62
97
|
logger.info("LLM client initialized")
|
|
63
98
|
except ValueError as e:
|
|
64
99
|
logger.warning(f"LLM client not available: {e}")
|
|
@@ -68,7 +103,14 @@ async def run_commander(
|
|
|
68
103
|
output_relay: Optional[OutputRelay] = None
|
|
69
104
|
if llm_client:
|
|
70
105
|
try:
|
|
71
|
-
summarizer
|
|
106
|
+
# Only create summarizer if summarize_responses is enabled
|
|
107
|
+
summarizer = None
|
|
108
|
+
if config.summarize_responses:
|
|
109
|
+
summarizer = OutputSummarizer(llm_client)
|
|
110
|
+
logger.info("Response summarization enabled")
|
|
111
|
+
else:
|
|
112
|
+
logger.info("Response summarization disabled")
|
|
113
|
+
|
|
72
114
|
handler = OutputHandler(orchestrator, summarizer)
|
|
73
115
|
formatter = OutputFormatter()
|
|
74
116
|
output_relay = OutputRelay(handler, formatter)
|
|
@@ -11,12 +11,19 @@ class CommandType(Enum):
|
|
|
11
11
|
LIST = "list"
|
|
12
12
|
START = "start"
|
|
13
13
|
STOP = "stop"
|
|
14
|
+
CLOSE = "close"
|
|
15
|
+
REGISTER = "register"
|
|
14
16
|
CONNECT = "connect"
|
|
15
17
|
DISCONNECT = "disconnect"
|
|
18
|
+
SAVED = "saved"
|
|
19
|
+
FORGET = "forget"
|
|
16
20
|
STATUS = "status"
|
|
17
21
|
HELP = "help"
|
|
18
22
|
EXIT = "exit"
|
|
19
23
|
INSTANCES = "instances" # alias for list
|
|
24
|
+
MPM_OAUTH = "mpm-oauth"
|
|
25
|
+
CLEANUP = "cleanup"
|
|
26
|
+
SEND = "send"
|
|
20
27
|
|
|
21
28
|
|
|
22
29
|
@dataclass
|
|
@@ -31,27 +38,44 @@ class Command:
|
|
|
31
38
|
class CommandParser:
|
|
32
39
|
"""Parses user input into commands."""
|
|
33
40
|
|
|
34
|
-
|
|
41
|
+
# Map slash command names to CommandType
|
|
42
|
+
SLASH_COMMANDS = {
|
|
43
|
+
"register": CommandType.REGISTER,
|
|
44
|
+
"start": CommandType.START,
|
|
45
|
+
"stop": CommandType.STOP,
|
|
46
|
+
"close": CommandType.CLOSE,
|
|
47
|
+
"connect": CommandType.CONNECT,
|
|
48
|
+
"disconnect": CommandType.DISCONNECT,
|
|
49
|
+
"switch": CommandType.CONNECT, # alias for connect
|
|
50
|
+
"list": CommandType.LIST,
|
|
35
51
|
"ls": CommandType.LIST,
|
|
36
|
-
"
|
|
52
|
+
"saved": CommandType.SAVED,
|
|
53
|
+
"forget": CommandType.FORGET,
|
|
54
|
+
"status": CommandType.STATUS,
|
|
55
|
+
"help": CommandType.HELP,
|
|
56
|
+
"exit": CommandType.EXIT,
|
|
37
57
|
"quit": CommandType.EXIT,
|
|
38
58
|
"q": CommandType.EXIT,
|
|
59
|
+
"mpm-oauth": CommandType.MPM_OAUTH,
|
|
60
|
+
"cleanup": CommandType.CLEANUP,
|
|
61
|
+
"send": CommandType.SEND,
|
|
39
62
|
}
|
|
40
63
|
|
|
41
64
|
def parse(self, input_text: str) -> Optional[Command]:
|
|
42
65
|
"""Parse input into a Command.
|
|
43
66
|
|
|
44
|
-
Returns None if input is not a
|
|
67
|
+
Returns None if input is not a slash command (natural language).
|
|
68
|
+
System commands must start with '/'.
|
|
45
69
|
|
|
46
70
|
Args:
|
|
47
71
|
input_text: Raw user input.
|
|
48
72
|
|
|
49
73
|
Returns:
|
|
50
|
-
Command if input is a
|
|
74
|
+
Command if input is a slash command, None otherwise.
|
|
51
75
|
|
|
52
76
|
Example:
|
|
53
77
|
>>> parser = CommandParser()
|
|
54
|
-
>>> cmd = parser.parse("list")
|
|
78
|
+
>>> cmd = parser.parse("/list")
|
|
55
79
|
>>> cmd.type
|
|
56
80
|
<CommandType.LIST: 'list'>
|
|
57
81
|
>>> parser.parse("tell me about the code")
|
|
@@ -60,22 +84,26 @@ class CommandParser:
|
|
|
60
84
|
if not input_text:
|
|
61
85
|
return None
|
|
62
86
|
|
|
63
|
-
|
|
87
|
+
# System commands must start with /
|
|
88
|
+
if not input_text.startswith("/"):
|
|
89
|
+
return None
|
|
90
|
+
|
|
91
|
+
# Remove the leading / and parse
|
|
92
|
+
cmd_line = input_text[1:]
|
|
93
|
+
parts = cmd_line.split()
|
|
94
|
+
if not parts:
|
|
95
|
+
return None
|
|
96
|
+
|
|
64
97
|
command_str = parts[0].lower()
|
|
65
98
|
args = parts[1:] if len(parts) > 1 else []
|
|
66
99
|
|
|
67
|
-
# Check if it's
|
|
68
|
-
if command_str in self.
|
|
69
|
-
cmd_type = self.
|
|
100
|
+
# Check if it's a valid slash command
|
|
101
|
+
if command_str in self.SLASH_COMMANDS:
|
|
102
|
+
cmd_type = self.SLASH_COMMANDS[command_str]
|
|
70
103
|
return Command(type=cmd_type, args=args, raw=input_text)
|
|
71
104
|
|
|
72
|
-
#
|
|
73
|
-
|
|
74
|
-
cmd_type = CommandType(command_str)
|
|
75
|
-
return Command(type=cmd_type, args=args, raw=input_text)
|
|
76
|
-
except ValueError:
|
|
77
|
-
# Not a built-in command
|
|
78
|
-
return None
|
|
105
|
+
# Unknown slash command
|
|
106
|
+
return None
|
|
79
107
|
|
|
80
108
|
def is_command(self, input_text: str) -> bool:
|
|
81
109
|
"""Check if input is a built-in command.
|