claude-mpm 3.4.7__py3-none-any.whl → 3.4.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/cli/commands/run.py +53 -27
- claude_mpm/utils/dependency_manager.py +10 -7
- {claude_mpm-3.4.7.dist-info → claude_mpm-3.4.10.dist-info}/METADATA +4 -4
- {claude_mpm-3.4.7.dist-info → claude_mpm-3.4.10.dist-info}/RECORD +8 -8
- {claude_mpm-3.4.7.dist-info → claude_mpm-3.4.10.dist-info}/WHEEL +0 -0
- {claude_mpm-3.4.7.dist-info → claude_mpm-3.4.10.dist-info}/entry_points.txt +0 -0
- {claude_mpm-3.4.7.dist-info → claude_mpm-3.4.10.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-3.4.7.dist-info → claude_mpm-3.4.10.dist-info}/top_level.txt +0 -0
claude_mpm/cli/commands/run.py
CHANGED
|
@@ -467,6 +467,7 @@ def _check_socketio_server_running(port, logger):
|
|
|
467
467
|
|
|
468
468
|
DESIGN DECISION: We try multiple endpoints and connection methods to ensure
|
|
469
469
|
robust detection. Some servers may be starting up and only partially ready.
|
|
470
|
+
Added retry logic to handle race conditions during server initialization.
|
|
470
471
|
|
|
471
472
|
Args:
|
|
472
473
|
port: Port number to check
|
|
@@ -483,34 +484,50 @@ def _check_socketio_server_running(port, logger):
|
|
|
483
484
|
# First, do a basic TCP connection check
|
|
484
485
|
try:
|
|
485
486
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
486
|
-
s.settimeout(
|
|
487
|
+
s.settimeout(2.0) # Increased from 1.0s for slower connections
|
|
487
488
|
result = s.connect_ex(('127.0.0.1', port))
|
|
488
489
|
if result != 0:
|
|
489
|
-
logger.debug(f"TCP connection to port {port} failed (not
|
|
490
|
+
logger.debug(f"TCP connection to port {port} failed (server not started yet)")
|
|
490
491
|
return False
|
|
491
492
|
except Exception as e:
|
|
492
493
|
logger.debug(f"TCP socket check failed for port {port}: {e}")
|
|
493
494
|
return False
|
|
494
495
|
|
|
495
|
-
# If TCP connection succeeds, try HTTP health check
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
logger.debug(f"✅ Socket.IO server health check passed on port {port}")
|
|
502
|
-
logger.debug(f"📄 Server response: {content[:100]}...")
|
|
503
|
-
return True
|
|
504
|
-
else:
|
|
505
|
-
logger.debug(f"⚠️ HTTP response code {response.getcode()} from port {port}")
|
|
506
|
-
return False
|
|
496
|
+
# If TCP connection succeeds, try HTTP health check with retries
|
|
497
|
+
# WHY: Even when TCP is accepting connections, the HTTP handler may not be ready
|
|
498
|
+
max_retries = 3
|
|
499
|
+
for retry in range(max_retries):
|
|
500
|
+
try:
|
|
501
|
+
response = urllib.request.urlopen(f'http://localhost:{port}/status', timeout=10) # Increased from 5s to 10s
|
|
507
502
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
503
|
+
if response.getcode() == 200:
|
|
504
|
+
content = response.read().decode()
|
|
505
|
+
logger.debug(f"✅ Socket.IO server health check passed on port {port} (attempt {retry + 1})")
|
|
506
|
+
logger.debug(f"📄 Server response: {content[:100]}...")
|
|
507
|
+
return True
|
|
508
|
+
else:
|
|
509
|
+
logger.debug(f"⚠️ HTTP response code {response.getcode()} from port {port} (attempt {retry + 1})")
|
|
510
|
+
if retry < max_retries - 1:
|
|
511
|
+
time.sleep(0.5) # Brief pause before retry
|
|
512
|
+
|
|
513
|
+
except urllib.error.HTTPError as e:
|
|
514
|
+
logger.debug(f"⚠️ HTTP error {e.code} from server on port {port} (attempt {retry + 1})")
|
|
515
|
+
if retry < max_retries - 1 and e.code in [404, 503]: # Server starting but not ready
|
|
516
|
+
logger.debug("Server appears to be starting, retrying...")
|
|
517
|
+
time.sleep(0.5)
|
|
518
|
+
continue
|
|
519
|
+
return False
|
|
520
|
+
except urllib.error.URLError as e:
|
|
521
|
+
logger.debug(f"⚠️ URL error connecting to port {port} (attempt {retry + 1}): {e.reason}")
|
|
522
|
+
if retry < max_retries - 1:
|
|
523
|
+
logger.debug("Connection refused - server may still be initializing, retrying...")
|
|
524
|
+
time.sleep(0.5)
|
|
525
|
+
continue
|
|
526
|
+
return False
|
|
527
|
+
|
|
528
|
+
# All retries exhausted
|
|
529
|
+
logger.debug(f"Health check failed after {max_retries} attempts - server not fully ready")
|
|
530
|
+
return False
|
|
514
531
|
|
|
515
532
|
except (ConnectionError, OSError) as e:
|
|
516
533
|
logger.debug(f"🔌 Connection error checking port {port}: {e}")
|
|
@@ -569,13 +586,17 @@ def _start_standalone_socketio_server(port, logger):
|
|
|
569
586
|
# 2. Event loop setup (~1s)
|
|
570
587
|
# 3. aiohttp server binding (~2-5s)
|
|
571
588
|
# 4. Socket.IO service initialization (~1-3s)
|
|
572
|
-
# Total: up to
|
|
573
|
-
max_attempts =
|
|
574
|
-
initial_delay = 0
|
|
575
|
-
max_delay =
|
|
589
|
+
# Total: up to 15+ seconds for full readiness (especially on Python 3.13)
|
|
590
|
+
max_attempts = 30 # Increased from 20 to handle Python 3.13 slower initialization
|
|
591
|
+
initial_delay = 1.0 # Increased from 0.5s to give daemon more time to fork
|
|
592
|
+
max_delay = 3.0 # Increased from 2.0s for slower systems
|
|
576
593
|
|
|
577
594
|
logger.info(f"Waiting up to {max_attempts * max_delay} seconds for server to be fully ready...")
|
|
578
595
|
|
|
596
|
+
# Give the daemon initial time to fork and start before checking
|
|
597
|
+
logger.debug("Allowing initial daemon startup time...")
|
|
598
|
+
time.sleep(0.5)
|
|
599
|
+
|
|
579
600
|
for attempt in range(max_attempts):
|
|
580
601
|
# Progressive delay - start fast, then slow down for socket binding
|
|
581
602
|
if attempt < 5:
|
|
@@ -596,9 +617,14 @@ def _start_standalone_socketio_server(port, logger):
|
|
|
596
617
|
else:
|
|
597
618
|
logger.debug(f"Server not yet accepting connections on attempt {attempt + 1}")
|
|
598
619
|
|
|
599
|
-
logger.error(f"❌ Socket.IO server
|
|
600
|
-
logger.
|
|
601
|
-
logger.
|
|
620
|
+
logger.error(f"❌ Socket.IO server health check failed after {max_attempts} attempts ({max_attempts * max_delay:.1f}s)")
|
|
621
|
+
logger.warning(f"⏱️ Server may still be starting - initialization can take 15+ seconds on some systems")
|
|
622
|
+
logger.warning(f"💡 The daemon process might be running but not yet accepting HTTP connections")
|
|
623
|
+
logger.error(f"🔧 Troubleshooting steps:")
|
|
624
|
+
logger.error(f" - Wait a few more seconds and try again")
|
|
625
|
+
logger.error(f" - Check for port conflicts: lsof -i :{port}")
|
|
626
|
+
logger.error(f" - Try a different port with --websocket-port")
|
|
627
|
+
logger.error(f" - Verify dependencies: pip install python-socketio aiohttp")
|
|
602
628
|
return False
|
|
603
629
|
|
|
604
630
|
except Exception as e:
|
|
@@ -107,12 +107,14 @@ def ensure_socketio_dependencies(logger=None) -> Tuple[bool, str]:
|
|
|
107
107
|
"""
|
|
108
108
|
Ensure Socket.IO dependencies are installed for monitoring features.
|
|
109
109
|
|
|
110
|
-
WHY:
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
WHY: Socket.IO dependencies (python-socketio, aiohttp, python-engineio) are now
|
|
111
|
+
core dependencies and should be installed automatically with claude-mpm.
|
|
112
|
+
This function verifies they are available and provides helpful error messages
|
|
113
|
+
if something went wrong during installation.
|
|
113
114
|
|
|
114
|
-
DESIGN DECISION: We check each dependency individually
|
|
115
|
-
|
|
115
|
+
DESIGN DECISION: We still check each dependency individually to provide
|
|
116
|
+
specific error messages if any are missing, which helps with troubleshooting
|
|
117
|
+
installation issues.
|
|
116
118
|
|
|
117
119
|
Args:
|
|
118
120
|
logger: Optional logger for output
|
|
@@ -142,8 +144,9 @@ def ensure_socketio_dependencies(logger=None) -> Tuple[bool, str]:
|
|
|
142
144
|
logger.debug("All Socket.IO dependencies are already installed")
|
|
143
145
|
return True, ""
|
|
144
146
|
|
|
145
|
-
# Install missing packages
|
|
146
|
-
logger.
|
|
147
|
+
# Install missing packages (should be rare since they're now core dependencies)
|
|
148
|
+
logger.warning(f"Socket.IO dependencies are missing despite being core dependencies: {missing_packages}")
|
|
149
|
+
logger.info(f"Attempting to install missing dependencies: {missing_packages}")
|
|
147
150
|
success, error_msg = install_packages(missing_packages, logger)
|
|
148
151
|
|
|
149
152
|
if success:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: claude-mpm
|
|
3
|
-
Version: 3.4.
|
|
3
|
+
Version: 3.4.10
|
|
4
4
|
Summary: Claude Multi-agent Project Manager - Clean orchestration with ticket management
|
|
5
5
|
Home-page: https://github.com/bobmatnyc/claude-mpm
|
|
6
6
|
Author: Claude MPM Team
|
|
@@ -32,6 +32,9 @@ Requires-Dist: flask-cors>=4.0.0
|
|
|
32
32
|
Requires-Dist: watchdog>=3.0.0
|
|
33
33
|
Requires-Dist: tree-sitter>=0.21.0
|
|
34
34
|
Requires-Dist: tree-sitter-language-pack>=0.8.0
|
|
35
|
+
Requires-Dist: python-socketio>=5.11.0
|
|
36
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
37
|
+
Requires-Dist: python-engineio>=4.8.0
|
|
35
38
|
Provides-Extra: dev
|
|
36
39
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
37
40
|
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
@@ -40,9 +43,6 @@ Requires-Dist: black; extra == "dev"
|
|
|
40
43
|
Requires-Dist: flake8; extra == "dev"
|
|
41
44
|
Requires-Dist: mypy; extra == "dev"
|
|
42
45
|
Provides-Extra: monitor
|
|
43
|
-
Requires-Dist: python-socketio>=5.11.0; extra == "monitor"
|
|
44
|
-
Requires-Dist: aiohttp>=3.9.0; extra == "monitor"
|
|
45
|
-
Requires-Dist: python-engineio>=4.8.0; extra == "monitor"
|
|
46
46
|
Dynamic: author-email
|
|
47
47
|
Dynamic: home-page
|
|
48
48
|
Dynamic: license-file
|
|
@@ -43,7 +43,7 @@ claude_mpm/cli/commands/agents.py,sha256=FqqEQcfAfCxjz_E7fGQUtLznloJLz8fWQtnjQhk
|
|
|
43
43
|
claude_mpm/cli/commands/info.py,sha256=ETL6jC08OTQVTPjs219Y0m3FzfKOUlI0-yI81AI8FXY,2990
|
|
44
44
|
claude_mpm/cli/commands/memory.py,sha256=6jYD1bgfnWA0DvBpLJnZCPYMRoGAPBopAED8Qr-iIos,37357
|
|
45
45
|
claude_mpm/cli/commands/monitor.py,sha256=80_tmSdfn_2cYpzxxPu9GnvFW0eixlSJ4wCqbn8VSCM,12407
|
|
46
|
-
claude_mpm/cli/commands/run.py,sha256=
|
|
46
|
+
claude_mpm/cli/commands/run.py,sha256=Rv6RT2S9WN8KcqX5e9rtmALP8yiOSw8ojl_Qp7gugqg,30234
|
|
47
47
|
claude_mpm/cli/commands/tickets.py,sha256=SXyGtHSyGJwTeJwDAHf7kRbdiG1DlZkXkod5UoNy7Ik,2150
|
|
48
48
|
claude_mpm/cli/commands/ui.py,sha256=FhBQiOKW61cNduyryRu0UhC366d6o1eEkBgbPd7Au1w,1900
|
|
49
49
|
claude_mpm/cli_module/__init__.py,sha256=CkMp4gzWKoZZF_qKyBDi2sQaZw_GLWZYLtKouv-4f8s,390
|
|
@@ -184,7 +184,7 @@ claude_mpm/ui/rich_terminal_ui.py,sha256=gx_9TD0kR4Exq867pHjVVs_b-gw1q267t5oA2ZD
|
|
|
184
184
|
claude_mpm/ui/terminal_ui.py,sha256=E_M-L-6EuGp6L8pRpaWEhTqf-ddDXhZp5W85D0XNRPw,11928
|
|
185
185
|
claude_mpm/utils/__init__.py,sha256=E8Hvv6ykL6rnnc8-YmfoGNpRCZbcIirxcFuNz7YvDIg,346
|
|
186
186
|
claude_mpm/utils/config_manager.py,sha256=TlekZYIWOz_ouWHQU4Gc-zckhoFK9AqA25b6A_XZdDc,16412
|
|
187
|
-
claude_mpm/utils/dependency_manager.py,sha256=
|
|
187
|
+
claude_mpm/utils/dependency_manager.py,sha256=2Gs881HkzwMEm7X2z7Lx8l2Lws4PvS-rPBuH737-rkg,7543
|
|
188
188
|
claude_mpm/utils/error_handler.py,sha256=W_Zc0FrKudpXvxT66Oxx0v8WkR8HA2KlynzzGy3eGcU,8168
|
|
189
189
|
claude_mpm/utils/framework_detection.py,sha256=nzs1qRZK9K-zT0382z1FpGDvgzUNrUg8rBL-O_WLq-Q,1217
|
|
190
190
|
claude_mpm/utils/import_migration_example.py,sha256=W4a4XH3FY_VBB00BB8Lae2aRPM021PxLHzdUfEs0B5w,2463
|
|
@@ -193,9 +193,9 @@ claude_mpm/utils/path_operations.py,sha256=6pLMnAWBVzHkgp6JyQHmHbGD-dWn-nX21yV4E
|
|
|
193
193
|
claude_mpm/utils/paths.py,sha256=Xv0SZWdZRkRjN9e6clBcA165ya00GNQxt7SwMz51tfA,10153
|
|
194
194
|
claude_mpm/validation/__init__.py,sha256=bJ19g9lnk7yIjtxzN8XPegp87HTFBzCrGQOpFgRTf3g,155
|
|
195
195
|
claude_mpm/validation/agent_validator.py,sha256=GCA2b2rKhKDeaNyUqWxTiWIs3sDdWjD9cgOFRp9K6ic,18227
|
|
196
|
-
claude_mpm-3.4.
|
|
197
|
-
claude_mpm-3.4.
|
|
198
|
-
claude_mpm-3.4.
|
|
199
|
-
claude_mpm-3.4.
|
|
200
|
-
claude_mpm-3.4.
|
|
201
|
-
claude_mpm-3.4.
|
|
196
|
+
claude_mpm-3.4.10.dist-info/licenses/LICENSE,sha256=cSdDfXjoTVhstrERrqme4zgxAu4GubU22zVEHsiXGxs,1071
|
|
197
|
+
claude_mpm-3.4.10.dist-info/METADATA,sha256=IEX7hJ0U89JTyyFHps19mQ7qVFBENPk0z-nEGVIVOXU,6464
|
|
198
|
+
claude_mpm-3.4.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
199
|
+
claude_mpm-3.4.10.dist-info/entry_points.txt,sha256=3_d7wLrg9sRmQ1SfrFGWoTNL8Wrd6lQb2XVSYbTwRIg,324
|
|
200
|
+
claude_mpm-3.4.10.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
|
|
201
|
+
claude_mpm-3.4.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|