claude-mpm 3.1.2__py3-none-any.whl → 3.2.1__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.
Files changed (52) hide show
  1. claude_mpm/__init__.py +3 -3
  2. claude_mpm/agents/INSTRUCTIONS.md +80 -2
  3. claude_mpm/agents/backups/INSTRUCTIONS.md +238 -0
  4. claude_mpm/agents/base_agent.json +1 -1
  5. claude_mpm/agents/templates/pm.json +25 -0
  6. claude_mpm/agents/templates/research.json +2 -1
  7. claude_mpm/cli/__init__.py +6 -1
  8. claude_mpm/cli/commands/__init__.py +3 -1
  9. claude_mpm/cli/commands/memory.py +232 -0
  10. claude_mpm/cli/commands/run.py +496 -8
  11. claude_mpm/cli/parser.py +91 -1
  12. claude_mpm/config/socketio_config.py +256 -0
  13. claude_mpm/constants.py +9 -0
  14. claude_mpm/core/__init__.py +2 -2
  15. claude_mpm/core/claude_runner.py +919 -0
  16. claude_mpm/core/config.py +21 -1
  17. claude_mpm/core/hook_manager.py +196 -0
  18. claude_mpm/core/pm_hook_interceptor.py +205 -0
  19. claude_mpm/core/simple_runner.py +296 -16
  20. claude_mpm/core/socketio_pool.py +582 -0
  21. claude_mpm/core/websocket_handler.py +233 -0
  22. claude_mpm/deployment_paths.py +261 -0
  23. claude_mpm/hooks/builtin/memory_hooks_example.py +67 -0
  24. claude_mpm/hooks/claude_hooks/hook_handler.py +669 -632
  25. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +9 -4
  26. claude_mpm/hooks/memory_integration_hook.py +312 -0
  27. claude_mpm/orchestration/__init__.py +1 -1
  28. claude_mpm/scripts/claude-mpm-socketio +32 -0
  29. claude_mpm/scripts/claude_mpm_monitor.html +567 -0
  30. claude_mpm/scripts/install_socketio_server.py +407 -0
  31. claude_mpm/scripts/launch_monitor.py +132 -0
  32. claude_mpm/scripts/manage_version.py +479 -0
  33. claude_mpm/scripts/socketio_daemon.py +181 -0
  34. claude_mpm/scripts/socketio_server_manager.py +428 -0
  35. claude_mpm/services/__init__.py +5 -0
  36. claude_mpm/services/agent_memory_manager.py +684 -0
  37. claude_mpm/services/hook_service.py +362 -0
  38. claude_mpm/services/socketio_client_manager.py +474 -0
  39. claude_mpm/services/socketio_server.py +698 -0
  40. claude_mpm/services/standalone_socketio_server.py +631 -0
  41. claude_mpm/services/websocket_server.py +376 -0
  42. claude_mpm/utils/dependency_manager.py +211 -0
  43. claude_mpm/web/open_dashboard.py +34 -0
  44. {claude_mpm-3.1.2.dist-info → claude_mpm-3.2.1.dist-info}/METADATA +20 -1
  45. {claude_mpm-3.1.2.dist-info → claude_mpm-3.2.1.dist-info}/RECORD +50 -24
  46. claude_mpm-3.2.1.dist-info/entry_points.txt +7 -0
  47. claude_mpm/cli_old.py +0 -728
  48. claude_mpm-3.1.2.dist-info/entry_points.txt +0 -4
  49. /claude_mpm/{cli_enhancements.py → experimental/cli_enhancements.py} +0 -0
  50. {claude_mpm-3.1.2.dist-info → claude_mpm-3.2.1.dist-info}/WHEEL +0 -0
  51. {claude_mpm-3.1.2.dist-info → claude_mpm-3.2.1.dist-info}/licenses/LICENSE +0 -0
  52. {claude_mpm-3.1.2.dist-info → claude_mpm-3.2.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,256 @@
1
+ """Socket.IO server configuration for different deployment scenarios.
2
+
3
+ This module provides configuration management for Socket.IO servers
4
+ across different deployment environments and installation methods.
5
+
6
+ WHY configuration management:
7
+ - Enables different settings for development vs production
8
+ - Supports multiple deployment scenarios (local, PyPI, Docker, etc.)
9
+ - Provides environment-specific defaults
10
+ - Allows runtime configuration overrides
11
+ """
12
+
13
+ import os
14
+ from dataclasses import dataclass
15
+ from pathlib import Path
16
+ from typing import Dict, Any, List, Optional
17
+
18
+
19
+ @dataclass
20
+ class SocketIOConfig:
21
+ """Configuration for Socket.IO server instances."""
22
+
23
+ # Server settings
24
+ host: str = "localhost"
25
+ port: int = 8765
26
+ server_id: Optional[str] = None
27
+
28
+ # Connection settings
29
+ cors_allowed_origins: str = "*" # Configure properly for production
30
+ ping_timeout: int = 60
31
+ ping_interval: int = 25
32
+ max_http_buffer_size: int = 1000000
33
+
34
+ # Compatibility settings
35
+ min_client_version: str = "0.7.0"
36
+ max_history_size: int = 10000
37
+
38
+ # Deployment settings
39
+ deployment_mode: str = "auto" # auto, standalone, embedded, client
40
+ auto_start: bool = True
41
+ persistent: bool = True
42
+
43
+ # Logging settings
44
+ log_level: str = "INFO"
45
+ log_to_file: bool = False
46
+ log_file_path: Optional[str] = None
47
+
48
+ # Health monitoring
49
+ health_check_interval: int = 30
50
+ max_connection_attempts: int = 3
51
+ reconnection_delay: int = 1
52
+
53
+ @classmethod
54
+ def from_env(cls) -> 'SocketIOConfig':
55
+ """Create configuration from environment variables."""
56
+ return cls(
57
+ host=os.getenv('CLAUDE_MPM_SOCKETIO_HOST', 'localhost'),
58
+ port=int(os.getenv('CLAUDE_MPM_SOCKETIO_PORT', '8765')),
59
+ server_id=os.getenv('CLAUDE_MPM_SOCKETIO_SERVER_ID'),
60
+ cors_allowed_origins=os.getenv('CLAUDE_MPM_SOCKETIO_CORS', '*'),
61
+ ping_timeout=int(os.getenv('CLAUDE_MPM_SOCKETIO_PING_TIMEOUT', '60')),
62
+ ping_interval=int(os.getenv('CLAUDE_MPM_SOCKETIO_PING_INTERVAL', '25')),
63
+ deployment_mode=os.getenv('CLAUDE_MPM_SOCKETIO_MODE', 'auto'),
64
+ auto_start=os.getenv('CLAUDE_MPM_SOCKETIO_AUTO_START', 'true').lower() == 'true',
65
+ persistent=os.getenv('CLAUDE_MPM_SOCKETIO_PERSISTENT', 'true').lower() == 'true',
66
+ log_level=os.getenv('CLAUDE_MPM_SOCKETIO_LOG_LEVEL', 'INFO'),
67
+ max_history_size=int(os.getenv('CLAUDE_MPM_SOCKETIO_HISTORY_SIZE', '10000'))
68
+ )
69
+
70
+ @classmethod
71
+ def for_development(cls) -> 'SocketIOConfig':
72
+ """Configuration optimized for development."""
73
+ return cls(
74
+ host="localhost",
75
+ port=8765,
76
+ deployment_mode="auto",
77
+ log_level="DEBUG",
78
+ ping_timeout=30,
79
+ ping_interval=10,
80
+ max_history_size=5000
81
+ )
82
+
83
+ @classmethod
84
+ def for_production(cls) -> 'SocketIOConfig':
85
+ """Configuration optimized for production."""
86
+ return cls(
87
+ host="0.0.0.0", # Bind to all interfaces in production
88
+ port=8765,
89
+ cors_allowed_origins="https://your-domain.com", # Restrict CORS
90
+ deployment_mode="standalone",
91
+ persistent=True,
92
+ log_level="INFO",
93
+ log_to_file=True,
94
+ log_file_path="/var/log/claude-mpm-socketio.log",
95
+ ping_timeout=120,
96
+ ping_interval=30,
97
+ max_history_size=20000
98
+ )
99
+
100
+ @classmethod
101
+ def for_docker(cls) -> 'SocketIOConfig':
102
+ """Configuration optimized for Docker deployment."""
103
+ return cls(
104
+ host="0.0.0.0",
105
+ port=8765,
106
+ deployment_mode="standalone",
107
+ persistent=True,
108
+ log_level="INFO",
109
+ ping_timeout=90,
110
+ ping_interval=25,
111
+ max_history_size=15000
112
+ )
113
+
114
+ def to_dict(self) -> Dict[str, Any]:
115
+ """Convert configuration to dictionary."""
116
+ return {
117
+ 'host': self.host,
118
+ 'port': self.port,
119
+ 'server_id': self.server_id,
120
+ 'cors_allowed_origins': self.cors_allowed_origins,
121
+ 'ping_timeout': self.ping_timeout,
122
+ 'ping_interval': self.ping_interval,
123
+ 'max_http_buffer_size': self.max_http_buffer_size,
124
+ 'min_client_version': self.min_client_version,
125
+ 'max_history_size': self.max_history_size,
126
+ 'deployment_mode': self.deployment_mode,
127
+ 'auto_start': self.auto_start,
128
+ 'persistent': self.persistent,
129
+ 'log_level': self.log_level,
130
+ 'log_to_file': self.log_to_file,
131
+ 'log_file_path': self.log_file_path,
132
+ 'health_check_interval': self.health_check_interval,
133
+ 'max_connection_attempts': self.max_connection_attempts,
134
+ 'reconnection_delay': self.reconnection_delay
135
+ }
136
+
137
+
138
+ class ConfigManager:
139
+ """Manages Socket.IO configuration across different environments."""
140
+
141
+ def __init__(self):
142
+ self.config_file_name = "socketio_config.json"
143
+ self.config_search_paths = [
144
+ Path.cwd() / self.config_file_name, # Current directory
145
+ Path.home() / ".claude-mpm" / self.config_file_name, # User home
146
+ Path("/etc/claude-mpm") / self.config_file_name, # System config
147
+ ]
148
+
149
+ def detect_environment(self) -> str:
150
+ """Detect the current deployment environment."""
151
+ # Check for Docker
152
+ if os.path.exists('/.dockerenv') or os.getenv('DOCKER_CONTAINER'):
153
+ return "docker"
154
+
155
+ # Check for production indicators
156
+ if os.getenv('ENVIRONMENT') == 'production' or os.getenv('NODE_ENV') == 'production':
157
+ return "production"
158
+
159
+ # Check if running from installed package
160
+ try:
161
+ import claude_mpm
162
+ pkg_path = Path(claude_mpm.__file__).parent
163
+ if 'site-packages' in str(pkg_path) or 'dist-packages' in str(pkg_path):
164
+ return "installed"
165
+ except ImportError:
166
+ pass
167
+
168
+ # Default to development
169
+ return "development"
170
+
171
+ def get_config(self, environment: str = None) -> SocketIOConfig:
172
+ """Get configuration for the specified environment."""
173
+ if environment is None:
174
+ environment = self.detect_environment()
175
+
176
+ # Start with environment-specific defaults
177
+ if environment == "production":
178
+ config = SocketIOConfig.for_production()
179
+ elif environment == "docker":
180
+ config = SocketIOConfig.for_docker()
181
+ elif environment == "development":
182
+ config = SocketIOConfig.for_development()
183
+ else:
184
+ config = SocketIOConfig()
185
+
186
+ # Override with environment variables
187
+ env_config = SocketIOConfig.from_env()
188
+ for field in config.__dataclass_fields__:
189
+ env_value = getattr(env_config, field)
190
+ if env_value != getattr(SocketIOConfig(), field): # Only if different from default
191
+ setattr(config, field, env_value)
192
+
193
+ # Override with config file if available
194
+ config_file_data = self._load_config_file()
195
+ if config_file_data:
196
+ for key, value in config_file_data.items():
197
+ if hasattr(config, key):
198
+ setattr(config, key, value)
199
+
200
+ return config
201
+
202
+ def _load_config_file(self) -> Optional[Dict[str, Any]]:
203
+ """Load configuration from file if available."""
204
+ import json
205
+
206
+ for config_path in self.config_search_paths:
207
+ if config_path.exists():
208
+ try:
209
+ with open(config_path, 'r') as f:
210
+ return json.load(f)
211
+ except Exception as e:
212
+ print(f"Warning: Failed to load config from {config_path}: {e}")
213
+
214
+ return None
215
+
216
+ def save_config(self, config: SocketIOConfig, path: str = None) -> bool:
217
+ """Save configuration to file."""
218
+ import json
219
+
220
+ if path is None:
221
+ # Use user config directory
222
+ config_dir = Path.home() / ".claude-mpm"
223
+ config_dir.mkdir(exist_ok=True)
224
+ path = config_dir / self.config_file_name
225
+
226
+ try:
227
+ with open(path, 'w') as f:
228
+ json.dump(config.to_dict(), f, indent=2)
229
+ return True
230
+ except Exception as e:
231
+ print(f"Error saving config to {path}: {e}")
232
+ return False
233
+
234
+
235
+ # Global configuration manager instance
236
+ _config_manager = ConfigManager()
237
+
238
+
239
+ def get_config(environment: str = None) -> SocketIOConfig:
240
+ """Get Socket.IO configuration for the current or specified environment."""
241
+ return _config_manager.get_config(environment)
242
+
243
+
244
+ def get_server_ports(config: SocketIOConfig) -> List[int]:
245
+ """Get list of ports to try for server discovery."""
246
+ base_port = config.port
247
+ return [base_port, base_port + 1, base_port + 2, base_port + 3, base_port + 4]
248
+
249
+
250
+ def get_discovery_hosts(config: SocketIOConfig) -> List[str]:
251
+ """Get list of hosts to try for server discovery."""
252
+ if config.host == "0.0.0.0":
253
+ # If server binds to all interfaces, try localhost and 127.0.0.1 for discovery
254
+ return ["localhost", "127.0.0.1"]
255
+ else:
256
+ return [config.host, "localhost", "127.0.0.1"]
claude_mpm/constants.py CHANGED
@@ -27,6 +27,7 @@ class CLICommands(str, Enum):
27
27
  INFO = "info"
28
28
  AGENTS = "agents"
29
29
  UI = "ui"
30
+ MEMORY = "memory"
30
31
 
31
32
  def with_prefix(self, prefix: CLIPrefix = CLIPrefix.MPM) -> str:
32
33
  """Get command with prefix."""
@@ -55,6 +56,14 @@ class AgentCommands(str, Enum):
55
56
  CLEAN = "clean"
56
57
 
57
58
 
59
+ class MemoryCommands(str, Enum):
60
+ """Memory subcommand constants."""
61
+ STATUS = "status"
62
+ VIEW = "view"
63
+ ADD = "add"
64
+ CLEAN = "clean"
65
+
66
+
58
67
  class CLIFlags(str, Enum):
59
68
  """CLI flag constants (without prefix)."""
60
69
  # Logging flags
@@ -1,6 +1,6 @@
1
1
  """Core components for Claude MPM."""
2
2
 
3
- from .simple_runner import SimpleClaudeRunner
3
+ from .claude_runner import ClaudeRunner
4
4
  from .mixins import LoggerMixin
5
5
 
6
6
  # Import config components if needed
@@ -24,7 +24,7 @@ except ImportError:
24
24
  pass
25
25
 
26
26
  __all__ = [
27
- "SimpleClaudeRunner",
27
+ "ClaudeRunner",
28
28
  "LoggerMixin",
29
29
  "Config",
30
30
  "ConfigAliases",