claude-mpm 4.0.20__py3-none-any.whl → 4.0.22__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/BUILD_NUMBER +1 -1
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/INSTRUCTIONS.md +74 -0
- claude_mpm/agents/WORKFLOW.md +308 -4
- claude_mpm/agents/agents_metadata.py +52 -0
- claude_mpm/agents/base_agent_loader.py +75 -19
- claude_mpm/agents/templates/__init__.py +4 -0
- claude_mpm/agents/templates/api_qa.json +206 -0
- claude_mpm/agents/templates/research.json +24 -16
- claude_mpm/agents/templates/ticketing.json +18 -5
- claude_mpm/agents/templates/vercel_ops_agent.json +281 -0
- claude_mpm/agents/templates/vercel_ops_instructions.md +582 -0
- claude_mpm/cli/commands/mcp_command_router.py +87 -1
- claude_mpm/cli/commands/mcp_install_commands.py +207 -26
- claude_mpm/cli/parsers/mcp_parser.py +23 -0
- claude_mpm/constants.py +1 -0
- claude_mpm/core/base_service.py +7 -1
- claude_mpm/core/config.py +64 -39
- claude_mpm/core/framework_loader.py +68 -28
- claude_mpm/core/interactive_session.py +28 -17
- claude_mpm/scripts/socketio_daemon.py +67 -7
- claude_mpm/scripts/socketio_daemon_hardened.py +897 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +65 -3
- claude_mpm/services/agents/deployment/async_agent_deployment.py +65 -1
- claude_mpm/services/agents/memory/agent_memory_manager.py +42 -203
- claude_mpm/services/memory_hook_service.py +62 -4
- claude_mpm/services/runner_configuration_service.py +5 -9
- claude_mpm/services/socketio/server/broadcaster.py +32 -1
- claude_mpm/services/socketio/server/core.py +4 -0
- claude_mpm/services/socketio/server/main.py +23 -4
- {claude_mpm-4.0.20.dist-info → claude_mpm-4.0.22.dist-info}/METADATA +1 -1
- {claude_mpm-4.0.20.dist-info → claude_mpm-4.0.22.dist-info}/RECORD +36 -32
- {claude_mpm-4.0.20.dist-info → claude_mpm-4.0.22.dist-info}/WHEEL +0 -0
- {claude_mpm-4.0.20.dist-info → claude_mpm-4.0.22.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.0.20.dist-info → claude_mpm-4.0.22.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.0.20.dist-info → claude_mpm-4.0.22.dist-info}/top_level.txt +0 -0
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
1
|
#!/usr/bin/env python3
|
|
4
2
|
"""
|
|
5
3
|
Pure Python daemon management for Socket.IO server.
|
|
@@ -12,6 +10,64 @@ import signal
|
|
|
12
10
|
import subprocess
|
|
13
11
|
import sys
|
|
14
12
|
import time
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
# Detect and use virtual environment Python if available
|
|
16
|
+
def get_python_executable():
|
|
17
|
+
"""
|
|
18
|
+
Get the appropriate Python executable, preferring virtual environment.
|
|
19
|
+
|
|
20
|
+
WHY: The daemon must use the same Python environment as the parent process
|
|
21
|
+
to ensure all dependencies are available. System Python won't have the
|
|
22
|
+
required packages installed.
|
|
23
|
+
"""
|
|
24
|
+
# First, check if we're already in a virtual environment
|
|
25
|
+
if hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix):
|
|
26
|
+
# We're in a virtual environment, use its Python
|
|
27
|
+
return sys.executable
|
|
28
|
+
|
|
29
|
+
# Check for common virtual environment indicators
|
|
30
|
+
# 1. VIRTUAL_ENV environment variable (most common)
|
|
31
|
+
venv_path = os.environ.get('VIRTUAL_ENV')
|
|
32
|
+
if venv_path:
|
|
33
|
+
venv_python = Path(venv_path) / 'bin' / 'python'
|
|
34
|
+
if venv_python.exists():
|
|
35
|
+
return str(venv_python)
|
|
36
|
+
|
|
37
|
+
# 2. Check if current executable is in a venv directory structure
|
|
38
|
+
exe_path = Path(sys.executable).resolve()
|
|
39
|
+
for parent in exe_path.parents:
|
|
40
|
+
# Check for common venv directory names
|
|
41
|
+
if parent.name in ('venv', '.venv', 'env', '.env'):
|
|
42
|
+
# This looks like a virtual environment
|
|
43
|
+
return sys.executable
|
|
44
|
+
|
|
45
|
+
# Check for typical venv structure (bin/python or Scripts/python.exe)
|
|
46
|
+
if parent.name == 'bin' and (parent.parent / 'pyvenv.cfg').exists():
|
|
47
|
+
return sys.executable
|
|
48
|
+
if parent.name == 'Scripts' and (parent.parent / 'pyvenv.cfg').exists():
|
|
49
|
+
return sys.executable
|
|
50
|
+
|
|
51
|
+
# 3. Try to detect project-specific venv
|
|
52
|
+
# Look for venv in the project root (going up from script location)
|
|
53
|
+
script_path = Path(__file__).resolve()
|
|
54
|
+
for parent in script_path.parents:
|
|
55
|
+
# Stop at src or when we've gone too far up
|
|
56
|
+
if parent.name == 'src' or not (parent / 'src').exists():
|
|
57
|
+
# Check for venv directories
|
|
58
|
+
for venv_name in ('venv', '.venv', 'env', '.env'):
|
|
59
|
+
venv_dir = parent / venv_name
|
|
60
|
+
if venv_dir.exists():
|
|
61
|
+
venv_python = venv_dir / 'bin' / 'python'
|
|
62
|
+
if venv_python.exists():
|
|
63
|
+
return str(venv_python)
|
|
64
|
+
break
|
|
65
|
+
|
|
66
|
+
# Fall back to current Python executable
|
|
67
|
+
return sys.executable
|
|
68
|
+
|
|
69
|
+
# Store the detected Python executable for daemon usage
|
|
70
|
+
PYTHON_EXECUTABLE = get_python_executable()
|
|
15
71
|
|
|
16
72
|
import psutil
|
|
17
73
|
|
|
@@ -145,11 +201,12 @@ def start_server():
|
|
|
145
201
|
|
|
146
202
|
ensure_dirs()
|
|
147
203
|
|
|
148
|
-
# Fork to create daemon
|
|
204
|
+
# Fork to create daemon using the correct Python environment
|
|
149
205
|
pid = os.fork()
|
|
150
206
|
if pid > 0:
|
|
151
207
|
# Parent process
|
|
152
208
|
print(f"Starting Socket.IO server on port {selected_port} (PID: {pid})...")
|
|
209
|
+
print(f"Using Python: {PYTHON_EXECUTABLE}")
|
|
153
210
|
|
|
154
211
|
# Register the instance
|
|
155
212
|
instance_id = port_manager.register_instance(selected_port, pid)
|
|
@@ -179,10 +236,13 @@ def start_server():
|
|
|
179
236
|
os.dup2(log.fileno(), sys.stdout.fileno())
|
|
180
237
|
os.dup2(log.fileno(), sys.stderr.fileno())
|
|
181
238
|
|
|
182
|
-
#
|
|
239
|
+
# Log environment information for debugging
|
|
183
240
|
print(
|
|
184
241
|
f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Starting Socket.IO server on port {selected_port}..."
|
|
185
242
|
)
|
|
243
|
+
print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Python executable: {sys.executable}")
|
|
244
|
+
print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Python version: {sys.version}")
|
|
245
|
+
print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Python path: {sys.path[:3]}...") # Show first 3 entries
|
|
186
246
|
server = SocketIOServer(host="localhost", port=selected_port)
|
|
187
247
|
|
|
188
248
|
# Handle signals
|
|
@@ -384,12 +444,12 @@ def main():
|
|
|
384
444
|
|
|
385
445
|
|
|
386
446
|
if __name__ == "__main__":
|
|
387
|
-
# Install psutil if not available
|
|
447
|
+
# Install psutil if not available (using correct Python)
|
|
388
448
|
try:
|
|
389
449
|
import psutil
|
|
390
450
|
except ImportError:
|
|
391
|
-
print("Installing psutil...")
|
|
392
|
-
subprocess.check_call([
|
|
451
|
+
print(f"Installing psutil using {PYTHON_EXECUTABLE}...")
|
|
452
|
+
subprocess.check_call([PYTHON_EXECUTABLE, "-m", "pip", "install", "psutil"])
|
|
393
453
|
import psutil
|
|
394
454
|
|
|
395
455
|
main()
|