claude-mpm 4.2.35__py3-none-any.whl → 4.2.37__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 CHANGED
@@ -1 +1 @@
1
- 4.2.35
1
+ 4.2.37
@@ -161,14 +161,16 @@ class UnifiedMonitorDaemon:
161
161
  self._wait_for_prewarm_completion()
162
162
 
163
163
  # Use daemon manager's daemonize which includes cleanup
164
- self.daemon_manager.startup_status_file = None # Reset status file
164
+ # DO NOT reset startup_status_file - it's needed for parent-child communication!
165
+ # self.daemon_manager.startup_status_file = None # BUG: This breaks communication
165
166
  success = self.daemon_manager.daemonize()
166
167
  if not success:
167
168
  return False
168
169
 
169
170
  # We're now in the daemon process
170
- # Update our PID references
171
+ # Update our PID references and status file
171
172
  self.lifecycle.pid_file = self.daemon_manager.pid_file
173
+ self.lifecycle.startup_status_file = self.daemon_manager.startup_status_file
172
174
 
173
175
  # Start the server in daemon mode
174
176
  try:
@@ -223,9 +223,32 @@ class DaemonManager:
223
223
  text=True, check=False,
224
224
  )
225
225
 
226
+ # Get full command to check if it's our monitor process
227
+ cmd_info = subprocess.run(
228
+ ["ps", "-p", str(pid), "-o", "command="],
229
+ capture_output=True,
230
+ text=True, check=False,
231
+ )
232
+
233
+ if cmd_info.returncode != 0:
234
+ continue
235
+
236
+ full_command = cmd_info.stdout.strip().lower()
226
237
  process_name = process_info.stdout.strip().lower()
227
- if "python" in process_name or "claude" in process_name:
228
- self.logger.info(f"Killing Python/Claude process {pid}")
238
+
239
+ # Check if this is our monitor/socketio process specifically
240
+ # Look for monitor, socketio, dashboard, or our specific port
241
+ is_monitor = any([
242
+ "monitor" in full_command,
243
+ "socketio" in full_command,
244
+ "dashboard" in full_command,
245
+ f"port={self.port}" in full_command,
246
+ f":{self.port}" in full_command,
247
+ "unified_monitor" in full_command,
248
+ ])
249
+
250
+ if is_monitor and "python" in process_name:
251
+ self.logger.info(f"Killing monitor process {pid}: {full_command[:100]}")
229
252
  os.kill(pid, signal.SIGTERM)
230
253
 
231
254
  # Wait briefly for graceful shutdown
@@ -242,10 +265,12 @@ class DaemonManager:
242
265
  except ProcessLookupError:
243
266
  pass # Process already dead
244
267
  else:
245
- self.logger.warning(
246
- f"Process {pid} ({process_name}) is not a Claude MPM process"
268
+ # Not a monitor process - log but don't fail
269
+ self.logger.info(
270
+ f"Skipping non-monitor process {pid} ({process_name})"
247
271
  )
248
- return False
272
+ # Continue to next PID - don't return False
273
+ continue
249
274
 
250
275
  except (ValueError, ProcessLookupError) as e:
251
276
  self.logger.debug(f"Error handling PID {pid_str}: {e}")
@@ -303,13 +328,16 @@ class DaemonManager:
303
328
  return False
304
329
 
305
330
  def _kill_claude_mpm_processes(self) -> bool:
306
- """Kill any claude-mpm monitor processes.
331
+ """Kill any claude-mpm monitor processes specifically.
332
+
333
+ This targets monitor/dashboard/socketio processes only,
334
+ NOT general Claude instances.
307
335
 
308
336
  Returns:
309
337
  True if successful, False on error
310
338
  """
311
339
  try:
312
- # Look for claude-mpm monitor processes
340
+ # Look for monitor-specific processes
313
341
  result = subprocess.run(["ps", "aux"], capture_output=True, text=True, check=False)
314
342
 
315
343
  if result.returncode != 0:
@@ -319,7 +347,12 @@ class DaemonManager:
319
347
  killed_any = False
320
348
 
321
349
  for line in lines:
322
- if "claude" in line.lower() and "monitor" in line.lower():
350
+ line_lower = line.lower()
351
+ # Only target monitor/dashboard/socketio processes
352
+ if any(["monitor" in line_lower and "claude" in line_lower,
353
+ "dashboard" in line_lower and "claude" in line_lower,
354
+ "socketio" in line_lower,
355
+ f":{self.port}" in line_lower and "python" in line_lower]):
323
356
  parts = line.split()
324
357
  if len(parts) > 1:
325
358
  try:
@@ -513,11 +546,12 @@ class DaemonManager:
513
546
 
514
547
  self.logger.info(f"Daemon process started with PID {os.getpid()}")
515
548
 
516
- # Report successful startup
517
- self._report_startup_success()
549
+ # DO NOT report success here - let the caller report after starting the service
550
+ # This prevents race conditions where we report success before the server starts
551
+ # self._report_startup_success() # REMOVED - caller must report
518
552
 
519
553
  # Note: Daemon process continues running
520
- # Caller is responsible for running the actual service
554
+ # Caller is responsible for running the actual service AND reporting status
521
555
  return True
522
556
 
523
557
  def stop_daemon(self, timeout: int = 10) -> bool:
@@ -737,18 +771,32 @@ class DaemonManager:
737
771
 
738
772
  def _report_startup_success(self):
739
773
  """Report successful startup to parent process."""
740
- if self.startup_status_file and Path(self.startup_status_file).exists():
774
+ if self.startup_status_file:
741
775
  try:
776
+ # Don't check if file exists - we need to write to it regardless
777
+ # The parent created it and is waiting for us to update it
742
778
  with open(self.startup_status_file, "w") as f:
743
779
  f.write("success")
780
+ f.flush() # Ensure it's written immediately
781
+ os.fsync(f.fileno()) # Force write to disk
744
782
  except Exception as e:
745
- self.logger.error(f"Error reporting startup success: {e}")
783
+ # Logging might not work in daemon process after fork
784
+ pass
746
785
 
747
786
  def _report_startup_error(self, error: str):
748
787
  """Report startup error to parent process."""
749
- if self.startup_status_file and Path(self.startup_status_file).exists():
788
+ if self.startup_status_file:
750
789
  try:
790
+ # Don't check if file exists - we need to write to it regardless
751
791
  with open(self.startup_status_file, "w") as f:
752
792
  f.write(f"error:{error}")
793
+ f.flush() # Ensure it's written immediately
794
+ os.fsync(f.fileno()) # Force write to disk
753
795
  except Exception as e:
754
- self.logger.error(f"Error reporting startup error: {e}")
796
+ # Try to write error to a debug file since logging might not work
797
+ try:
798
+ with open("/tmp/daemon_debug_error.txt", "a") as debug:
799
+ debug.write(f"Error reporting error: {e}\n")
800
+ debug.write(f"Status file: {self.startup_status_file}\n")
801
+ except:
802
+ pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-mpm
3
- Version: 4.2.35
3
+ Version: 4.2.37
4
4
  Summary: Claude Multi-Agent Project Manager - Orchestrate Claude with agent delegation and ticket tracking
5
5
  Author-email: Bob Matsuoka <bob@matsuoka.com>
6
6
  Maintainer: Claude MPM Team
@@ -1,5 +1,5 @@
1
1
  claude_mpm/BUILD_NUMBER,sha256=toytnNjkIKPgQaGwDqQdC1rpNTAdSEc6Vja50d7Ovug,4
2
- claude_mpm/VERSION,sha256=OgiTt9hnrEgzTrCgguvpjrTIWEqXs1pbpeuN0Uscq34,7
2
+ claude_mpm/VERSION,sha256=8MTto0T2Pjn3EmbsPiVKwl4bfctwhNwfnZha2doafiU,7
3
3
  claude_mpm/__init__.py,sha256=lyTZAYGH4DTaFGLRNWJKk5Q5oTjzN5I6AXmfVX-Jff0,1512
4
4
  claude_mpm/__main__.py,sha256=Ro5UBWBoQaSAIoSqWAr7zkbLyvi4sSy28WShqAhKJG0,723
5
5
  claude_mpm/constants.py,sha256=I946iCQzIIPRZVVJ8aO7lA4euiyDnNw2IX7EelAOkIE,5915
@@ -552,8 +552,8 @@ claude_mpm/services/memory/cache/__init__.py,sha256=6M6-P8ParyxX8vOgp_IxHgLMvacr
552
552
  claude_mpm/services/memory/cache/shared_prompt_cache.py,sha256=crnYPUT8zcS7TvoE1vW7pyaf4T77N5rJ1wUf_YQ2vvo,28704
553
553
  claude_mpm/services/memory/cache/simple_cache.py,sha256=qsTjbcsPxj-kNfaod9VN_uE5NioIwpfkUin_mMVUJCg,10218
554
554
  claude_mpm/services/monitor/__init__.py,sha256=X7gxSLUm9Fg_zEsX6LtCHP2ipF0qj6Emkun20h2So7g,745
555
- claude_mpm/services/monitor/daemon.py,sha256=nkB_xslT4yxIiSVf2u6nGm56rYpkit0WDj4YPWr-osM,22961
556
- claude_mpm/services/monitor/daemon_manager.py,sha256=31cscLPel109_IbcM9vtQyd4PbMWFRJc8vUOYSirOss,25291
555
+ claude_mpm/services/monitor/daemon.py,sha256=94Wdv9gRxbPUSnGU4aQrvYQzykqqoUdiciJgh10EerE,23166
556
+ claude_mpm/services/monitor/daemon_manager.py,sha256=ITtD3-lccRETX6RibWr50tdbg2YiAHDVtv29MS2jgHw,27885
557
557
  claude_mpm/services/monitor/event_emitter.py,sha256=JzRLNg8PUJ5s3ulNnq_D4yqCPItvidJzu8DmFxriieQ,12224
558
558
  claude_mpm/services/monitor/server.py,sha256=aKweXs3saNuPDaPwuoJT9g6kYYHefSiLcGmLdHD6FYM,28579
559
559
  claude_mpm/services/monitor/handlers/__init__.py,sha256=jgPIf4IJVERm_tAeD9834tfx9IcxtlHj5r9rhEWpkfM,701
@@ -644,9 +644,9 @@ claude_mpm/utils/subprocess_utils.py,sha256=zgiwLqh_17WxHpySvUPH65pb4bzIeUGOAYUJ
644
644
  claude_mpm/validation/__init__.py,sha256=YZhwE3mhit-lslvRLuwfX82xJ_k4haZeKmh4IWaVwtk,156
645
645
  claude_mpm/validation/agent_validator.py,sha256=3Lo6LK-Mw9IdnL_bd3zl_R6FkgSVDYKUUM7EeVVD3jc,20865
646
646
  claude_mpm/validation/frontmatter_validator.py,sha256=u8g4Eyd_9O6ugj7Un47oSGh3kqv4wMkuks2i_CtWRvM,7028
647
- claude_mpm-4.2.35.dist-info/licenses/LICENSE,sha256=lpaivOlPuBZW1ds05uQLJJswy8Rp_HMNieJEbFlqvLk,1072
648
- claude_mpm-4.2.35.dist-info/METADATA,sha256=XuC8xr5D_eX9dtuJWgAKHOxSSjNQDTVV6WwmUviFIY4,14451
649
- claude_mpm-4.2.35.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
650
- claude_mpm-4.2.35.dist-info/entry_points.txt,sha256=FDPZgz8JOvD-6iuXY2l9Zbo9zYVRuE4uz4Qr0vLeGOk,471
651
- claude_mpm-4.2.35.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
652
- claude_mpm-4.2.35.dist-info/RECORD,,
647
+ claude_mpm-4.2.37.dist-info/licenses/LICENSE,sha256=lpaivOlPuBZW1ds05uQLJJswy8Rp_HMNieJEbFlqvLk,1072
648
+ claude_mpm-4.2.37.dist-info/METADATA,sha256=bENryvC9QBtyjDK0QZDgPuYMd8KP7DJGwk4P9gkMgOc,14451
649
+ claude_mpm-4.2.37.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
650
+ claude_mpm-4.2.37.dist-info/entry_points.txt,sha256=FDPZgz8JOvD-6iuXY2l9Zbo9zYVRuE4uz4Qr0vLeGOk,471
651
+ claude_mpm-4.2.37.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
652
+ claude_mpm-4.2.37.dist-info/RECORD,,