claude-mpm 4.1.6__py3-none-any.whl → 4.1.8__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.
@@ -71,20 +71,28 @@ class ClientConnection:
71
71
  metadata: Dict[str, Any] = field(default_factory=dict)
72
72
 
73
73
  def is_healthy(self, timeout: float = 90.0) -> bool:
74
- """Check if connection is healthy based on activity."""
74
+ """Check if connection is healthy based on activity.
75
+
76
+ Args:
77
+ timeout: Seconds before considering connection unhealthy (default 90s)
78
+ """
75
79
  if self.state != ConnectionState.CONNECTED:
76
80
  return False
77
81
 
78
82
  now = time.time()
79
83
 
80
84
  # Check last activity (ping, pong, or event)
85
+ # Include metrics.last_activity for more comprehensive tracking
81
86
  last_activity = max(
82
87
  self.last_ping or 0,
83
88
  self.last_pong or 0,
84
89
  self.last_event or 0,
90
+ self.metrics.last_activity or 0,
85
91
  self.connected_at,
86
92
  )
87
93
 
94
+ # More aggressive timeout for stale detection (no grace period)
95
+ # This helps identify truly stale connections faster
88
96
  return (now - last_activity) < timeout
89
97
 
90
98
  def calculate_quality(self) -> float:
@@ -140,22 +148,28 @@ class ConnectionManager:
140
148
  - Automatic event replay on reconnection
141
149
  """
142
150
 
143
- def __init__(self, max_buffer_size: int = 1000, event_ttl: int = 300):
151
+ def __init__(self, max_buffer_size: int = None, event_ttl: int = None):
144
152
  """
145
- Initialize connection manager.
153
+ Initialize connection manager with centralized configuration.
146
154
 
147
155
  Args:
148
- max_buffer_size: Maximum events to buffer per client
149
- event_ttl: Time-to-live for buffered events in seconds
156
+ max_buffer_size: Maximum events to buffer per client (uses config if None)
157
+ event_ttl: Time-to-live for buffered events in seconds (uses config if None)
150
158
  """
159
+ from ....config.socketio_config import CONNECTION_CONFIG
160
+
151
161
  self.logger = get_logger(__name__)
152
162
  self.connections: Dict[str, ClientConnection] = {}
153
163
  self.client_mapping: Dict[str, str] = {} # client_id -> current sid
154
- self.max_buffer_size = max_buffer_size
155
- self.event_ttl = event_ttl
164
+
165
+ # Use centralized configuration with optional overrides
166
+ self.max_buffer_size = max_buffer_size or CONNECTION_CONFIG["max_events_buffer"]
167
+ self.event_ttl = event_ttl or CONNECTION_CONFIG["event_ttl"]
156
168
  self.global_sequence = 0
157
- self.health_check_interval = 30 # seconds
158
- self.stale_timeout = 90 # seconds
169
+ self.health_check_interval = CONNECTION_CONFIG[
170
+ "health_check_interval"
171
+ ] # 30 seconds
172
+ self.stale_timeout = CONNECTION_CONFIG["stale_timeout"] # 180 seconds (was 90)
159
173
  self.health_task = None
160
174
  self._lock = asyncio.Lock()
161
175
 
@@ -163,7 +177,7 @@ class ConnectionManager:
163
177
  self, sid: str, client_id: Optional[str] = None
164
178
  ) -> ClientConnection:
165
179
  """
166
- Register a new connection or reconnection.
180
+ Register a new connection or reconnection with retry logic.
167
181
 
168
182
  Args:
169
183
  sid: Socket ID
@@ -172,54 +186,83 @@ class ConnectionManager:
172
186
  Returns:
173
187
  ClientConnection object
174
188
  """
175
- async with self._lock:
176
- now = time.time()
189
+ max_retries = 3
190
+ retry_delay = 0.1 # Start with 100ms
177
191
 
178
- # Check if this is a reconnection
179
- if client_id and client_id in self.client_mapping:
180
- old_sid = self.client_mapping[client_id]
181
- if old_sid in self.connections:
182
- old_conn = self.connections[old_sid]
192
+ for attempt in range(max_retries):
193
+ try:
194
+ async with self._lock:
195
+ now = time.time()
196
+
197
+ # Check if this is a reconnection
198
+ if client_id and client_id in self.client_mapping:
199
+ old_sid = self.client_mapping[client_id]
200
+ if old_sid in self.connections:
201
+ old_conn = self.connections[old_sid]
202
+
203
+ # Create new connection with history
204
+ conn = ClientConnection(
205
+ sid=sid,
206
+ client_id=client_id,
207
+ state=ConnectionState.CONNECTED,
208
+ connected_at=now,
209
+ event_buffer=old_conn.event_buffer,
210
+ event_sequence=old_conn.event_sequence,
211
+ last_acked_sequence=old_conn.last_acked_sequence,
212
+ metrics=old_conn.metrics,
213
+ )
214
+
215
+ # Update metrics
216
+ conn.metrics.reconnect_count += 1
217
+ conn.metrics.connect_count += 1
218
+ if old_conn.disconnected_at:
219
+ conn.metrics.total_downtime += (
220
+ now - old_conn.disconnected_at
221
+ )
222
+
223
+ # Clean up old connection
224
+ del self.connections[old_sid]
225
+
226
+ self.logger.info(
227
+ f"Client {client_id} reconnected (new sid: {sid}, "
228
+ f"buffered events: {len(conn.event_buffer)})"
229
+ )
230
+ else:
231
+ # No old connection found, create new
232
+ client_id = client_id or str(uuid4())
233
+ conn = self._create_new_connection(sid, client_id, now)
234
+ else:
235
+ # New client
236
+ client_id = client_id or str(uuid4())
237
+ conn = self._create_new_connection(sid, client_id, now)
183
238
 
184
- # Create new connection with history
239
+ # Register connection with validation
240
+ if conn and conn.state == ConnectionState.CONNECTED:
241
+ self.connections[sid] = conn
242
+ self.client_mapping[client_id] = sid
243
+ return conn
244
+ raise ValueError(f"Invalid connection state for {sid}")
245
+
246
+ except Exception as e:
247
+ self.logger.warning(
248
+ f"Failed to register connection {sid} (attempt {attempt + 1}/{max_retries}): {e}"
249
+ )
250
+ if attempt < max_retries - 1:
251
+ await asyncio.sleep(retry_delay)
252
+ retry_delay *= 2 # Exponential backoff
253
+ else:
254
+ # Final attempt failed, create minimal connection
255
+ self.logger.error(
256
+ f"All attempts failed for {sid}, creating minimal connection"
257
+ )
185
258
  conn = ClientConnection(
186
259
  sid=sid,
187
- client_id=client_id,
260
+ client_id=client_id or str(uuid4()),
188
261
  state=ConnectionState.CONNECTED,
189
- connected_at=now,
190
- event_buffer=old_conn.event_buffer,
191
- event_sequence=old_conn.event_sequence,
192
- last_acked_sequence=old_conn.last_acked_sequence,
193
- metrics=old_conn.metrics,
262
+ connected_at=time.time(),
194
263
  )
195
-
196
- # Update metrics
197
- conn.metrics.reconnect_count += 1
198
- conn.metrics.connect_count += 1
199
- if old_conn.disconnected_at:
200
- conn.metrics.total_downtime += now - old_conn.disconnected_at
201
-
202
- # Clean up old connection
203
- del self.connections[old_sid]
204
-
205
- self.logger.info(
206
- f"Client {client_id} reconnected (new sid: {sid}, "
207
- f"buffered events: {len(conn.event_buffer)})"
208
- )
209
- else:
210
- # No old connection found, create new
211
- client_id = client_id or str(uuid4())
212
- conn = self._create_new_connection(sid, client_id, now)
213
- else:
214
- # New client
215
- client_id = client_id or str(uuid4())
216
- conn = self._create_new_connection(sid, client_id, now)
217
-
218
- # Register connection
219
- self.connections[sid] = conn
220
- self.client_mapping[client_id] = sid
221
-
222
- return conn
264
+ self.connections[sid] = conn
265
+ return conn
223
266
 
224
267
  def _create_new_connection(
225
268
  self, sid: str, client_id: str, now: float
@@ -439,21 +482,39 @@ class ConnectionManager:
439
482
  if conn.is_healthy(self.stale_timeout):
440
483
  report["healthy"] += 1
441
484
  else:
442
- # Mark as stale
443
- conn.state = ConnectionState.STALE
444
- report["stale"] += 1
445
- self.logger.warning(
446
- f"Connection {conn.client_id} marked as stale "
447
- f"(last activity: {now - conn.metrics.last_activity:.1f}s ago)"
485
+ # Mark as stale only if really stale (no grace period activity)
486
+ last_activity = max(
487
+ conn.last_ping or 0,
488
+ conn.last_pong or 0,
489
+ conn.last_event or 0,
490
+ conn.metrics.last_activity or 0,
491
+ conn.connected_at,
448
492
  )
493
+ time_since_activity = now - last_activity
494
+
495
+ # Only mark as stale if significantly over timeout (2x)
496
+ if time_since_activity > (self.stale_timeout * 2):
497
+ conn.state = ConnectionState.STALE
498
+ report["stale"] += 1
499
+ self.logger.warning(
500
+ f"Connection {conn.client_id} marked as stale "
501
+ f"(last activity: {time_since_activity:.1f}s ago)"
502
+ )
503
+ else:
504
+ # Connection is borderline - keep it alive but log
505
+ report["healthy"] += 1
506
+ self.logger.debug(
507
+ f"Connection {conn.client_id} borderline "
508
+ f"(last activity: {time_since_activity:.1f}s ago)"
509
+ )
510
+
449
511
  elif conn.state == ConnectionState.DISCONNECTED:
450
512
  report["disconnected"] += 1
451
513
 
452
- # Clean up old disconnected connections
453
- if (
454
- conn.disconnected_at
455
- and (now - conn.disconnected_at) > self.event_ttl
456
- ):
514
+ # Clean up old disconnected connections (be conservative)
515
+ if conn.disconnected_at and (now - conn.disconnected_at) > (
516
+ self.event_ttl * 2
517
+ ): # Double the TTL
457
518
  to_clean.append(sid)
458
519
 
459
520
  # Clean up old connections
@@ -158,20 +158,40 @@ class SocketIOServerCore:
158
158
  async def _start_server(self):
159
159
  """Start the Socket.IO server with aiohttp."""
160
160
  try:
161
- # Create Socket.IO server with proper ping/pong configuration
161
+ # Import centralized configuration for consistency
162
+ from ....config.socketio_config import CONNECTION_CONFIG
163
+
164
+ # Create Socket.IO server with centralized configuration
165
+ # CRITICAL: These values MUST match client settings to prevent disconnections
162
166
  self.sio = socketio.AsyncServer(
163
167
  cors_allowed_origins="*",
164
168
  logger=False, # Disable Socket.IO's own logging
165
169
  engineio_logger=False,
166
- ping_interval=25, # Send ping every 25 seconds
167
- ping_timeout=60, # Wait 60 seconds for pong response
168
- max_http_buffer_size=1e8, # 100MB max buffer
170
+ ping_interval=CONNECTION_CONFIG[
171
+ "ping_interval"
172
+ ], # 45 seconds from config
173
+ ping_timeout=CONNECTION_CONFIG[
174
+ "ping_timeout"
175
+ ], # 20 seconds from config
176
+ max_http_buffer_size=CONNECTION_CONFIG[
177
+ "max_http_buffer_size"
178
+ ], # 100MB from config
169
179
  )
170
180
 
171
181
  # Create aiohttp application
172
182
  self.app = web.Application()
173
183
  self.sio.attach(self.app)
174
184
 
185
+ # CRITICAL: Register event handlers BEFORE starting the server
186
+ # This ensures handlers are ready when clients connect
187
+ if self.main_server and hasattr(self.main_server, "_register_events_async"):
188
+ self.logger.info(
189
+ "Registering Socket.IO event handlers before server start"
190
+ )
191
+ await self.main_server._register_events_async()
192
+ else:
193
+ self.logger.warning("Main server not available for event registration")
194
+
175
195
  # Setup HTTP API endpoints for receiving events from hook handlers
176
196
  self._setup_http_api()
177
197
 
@@ -196,9 +216,16 @@ class SocketIOServerCore:
196
216
  if self.static_path:
197
217
  self.logger.info(f"Serving static files from: {self.static_path}")
198
218
 
199
- # Start heartbeat task
200
- self.heartbeat_task = asyncio.create_task(self._heartbeat_loop())
201
- self.logger.info("Started system heartbeat task")
219
+ # Conditionally start heartbeat task based on configuration
220
+ from ....config.socketio_config import CONNECTION_CONFIG
221
+
222
+ if CONNECTION_CONFIG.get("enable_extra_heartbeat", False):
223
+ self.heartbeat_task = asyncio.create_task(self._heartbeat_loop())
224
+ self.logger.info("Started system heartbeat task")
225
+ else:
226
+ self.logger.info(
227
+ "System heartbeat disabled (using Socket.IO ping/pong instead)"
228
+ )
202
229
 
203
230
  # Keep the server running
204
231
  while self.running:
@@ -111,7 +111,8 @@ class SocketIOServer(SocketIOServiceInterface):
111
111
  flush=True,
112
112
  )
113
113
 
114
- # Start the core server
114
+ # CRITICAL: Start the core server first to create sio instance
115
+ # Event handlers will be registered inside _start_server before accepting connections
115
116
  self.core.start_sync()
116
117
 
117
118
  # Initialize connection manager for robust connection tracking
@@ -163,8 +164,9 @@ class SocketIOServer(SocketIOServiceInterface):
163
164
  self.connection_manager.start_health_monitoring(), self.core.loop
164
165
  )
165
166
 
166
- # Register events
167
- self._register_events()
167
+ # Register events if not already done in async context
168
+ if self.core.sio and not self.event_registry:
169
+ self._register_events()
168
170
 
169
171
  # Setup EventBus integration
170
172
  # WHY: This connects the EventBus to the Socket.IO server, allowing
@@ -173,35 +175,64 @@ class SocketIOServer(SocketIOServiceInterface):
173
175
  f"[{datetime.now().isoformat()}] Setting up EventBus integration...",
174
176
  flush=True,
175
177
  )
176
- try:
177
- self.eventbus_integration = EventBusIntegration(self)
178
+
179
+ # CRITICAL: Ensure broadcaster is fully initialized before setting up EventBus
180
+ # The relay needs the broadcaster to be ready to relay events
181
+ if not self.broadcaster:
182
+ self.logger.error(
183
+ "Broadcaster not initialized - cannot setup EventBus integration"
184
+ )
185
+ print(
186
+ f"[{datetime.now().isoformat()}] ERROR: Broadcaster not initialized",
187
+ flush=True,
188
+ )
189
+ else:
178
190
  print(
179
- f"[{datetime.now().isoformat()}] EventBusIntegration instance created",
191
+ f"[{datetime.now().isoformat()}] Broadcaster ready, proceeding with EventBus setup",
180
192
  flush=True,
181
193
  )
182
194
 
183
- if self.eventbus_integration.setup(self.port):
184
- self.logger.info("EventBus integration setup successful")
195
+ try:
196
+ self.eventbus_integration = EventBusIntegration(self)
185
197
  print(
186
- f"[{datetime.now().isoformat()}] EventBus integration setup successful",
198
+ f"[{datetime.now().isoformat()}] EventBusIntegration instance created",
187
199
  flush=True,
188
200
  )
189
- else:
190
- self.logger.warning("EventBus integration setup failed or disabled")
201
+
202
+ if self.eventbus_integration.setup(self.port):
203
+ self.logger.info("EventBus integration setup successful")
204
+ print(
205
+ f"[{datetime.now().isoformat()}] EventBus integration setup successful",
206
+ flush=True,
207
+ )
208
+
209
+ # Verify relay is connected and has broadcaster
210
+ if (
211
+ hasattr(self.eventbus_integration, "relay")
212
+ and self.eventbus_integration.relay
213
+ ):
214
+ relay_stats = self.eventbus_integration.relay.get_stats()
215
+ self.logger.info(f"EventBus relay stats: {relay_stats}")
216
+ print(
217
+ f"[{datetime.now().isoformat()}] EventBus relay stats: {relay_stats}",
218
+ flush=True,
219
+ )
220
+ else:
221
+ self.logger.warning("EventBus integration setup failed or disabled")
222
+ print(
223
+ f"[{datetime.now().isoformat()}] EventBus integration setup failed or disabled",
224
+ flush=True,
225
+ )
226
+ except Exception as e:
227
+ self.logger.error(f"Failed to setup EventBus integration: {e}")
191
228
  print(
192
- f"[{datetime.now().isoformat()}] EventBus integration setup failed or disabled",
229
+ f"[{datetime.now().isoformat()}] Failed to setup EventBus integration: {e}",
193
230
  flush=True,
194
231
  )
195
- except Exception as e:
196
- self.logger.error(f"Failed to setup EventBus integration: {e}")
197
- print(
198
- f"[{datetime.now().isoformat()}] Failed to setup EventBus integration: {e}",
199
- flush=True,
200
- )
201
- import traceback
232
+ import traceback
202
233
 
203
- traceback.print_exc()
204
- self.eventbus_integration = None
234
+ traceback.print_exc()
235
+ self.eventbus_integration = None
205
236
 
206
237
  # Update running state
207
238
  self.running = self.core.running
@@ -252,6 +283,12 @@ class SocketIOServer(SocketIOServiceInterface):
252
283
  handlers in a modular way. Each handler focuses on a specific domain,
253
284
  reducing complexity and improving maintainability.
254
285
  """
286
+ if not self.core.sio:
287
+ self.logger.error(
288
+ "Cannot register events - Socket.IO server not initialized"
289
+ )
290
+ return
291
+
255
292
  # Initialize the event handler registry
256
293
  self.event_registry = EventHandlerRegistry(self)
257
294
  self.event_registry.initialize()
@@ -265,6 +302,31 @@ class SocketIOServer(SocketIOServiceInterface):
265
302
 
266
303
  self.logger.info("All Socket.IO events registered via handler system")
267
304
 
305
+ async def _register_events_async(self):
306
+ """Async version of event registration for calling from async context.
307
+
308
+ WHY: This allows us to register events from within the async _start_server
309
+ method before the server starts accepting connections.
310
+ """
311
+ if not self.core.sio:
312
+ self.logger.error(
313
+ "Cannot register events - Socket.IO server not initialized"
314
+ )
315
+ return
316
+
317
+ # Initialize the event handler registry
318
+ self.event_registry = EventHandlerRegistry(self)
319
+ self.event_registry.initialize()
320
+
321
+ # Register all events from all handlers
322
+ self.event_registry.register_all_events()
323
+
324
+ # Keep handler instances for HTTP endpoint compatibility
325
+ self.file_handler = self.event_registry.get_handler(FileEventHandler)
326
+ self.git_handler = self.event_registry.get_handler(GitEventHandler)
327
+
328
+ self.logger.info("All Socket.IO events registered via handler system (async)")
329
+
268
330
  # Delegate broadcasting methods to the broadcaster
269
331
  def broadcast_event(self, event_type: str, data: Dict[str, Any]):
270
332
  """Broadcast an event to all connected clients."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-mpm
3
- Version: 4.1.6
3
+ Version: 4.1.8
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=w9Yv379QUvcGT8ToH1cuQa1SSo52GJWg_Ikc6-hN2jo,6
2
+ claude_mpm/VERSION,sha256=9_cjWZcnvxfj2ollTh4zoGcoRfdahIWrvGWSvtEA1e4,6
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=5-k9ZbfDRe3WpGfHx3R0iTXokuOaZY-NcWcx1xkLTws,5678
@@ -9,6 +9,7 @@ claude_mpm/agents/BASE_AGENT_TEMPLATE.md,sha256=aK9qxS1FRpm_8VaB5GI2I6YA9Wr8dGHu
9
9
  claude_mpm/agents/BASE_PM.md,sha256=OMWebRWA4ZDk9z3H9DxvksNYqfG4ZExFVNF2vUirUBo,9299
10
10
  claude_mpm/agents/INSTRUCTIONS.md,sha256=bTTlGVJwcYjdQ51PMsJXPW6FIEg15wItyHY2u0BYJSU,10777
11
11
  claude_mpm/agents/MEMORY.md,sha256=EeY1MwnrhaAij5_pUCt_lcOc2-coo3EYkWRyRbPyJmM,3181
12
+ claude_mpm/agents/OUTPUT_STYLE.md,sha256=HZ5GhiTwMWj9G_uefmMguH4Ukhs2CQqa8u5FQ6HBrbo,2538
12
13
  claude_mpm/agents/WORKFLOW.md,sha256=y-tYNbSqJ4D4ND5TMc5bvcnq_mYw3Gwq9bnpz-LzwvQ,7972
13
14
  claude_mpm/agents/__init__.py,sha256=jRFxvV_DIZ-NdENa-703Xu3YpwvlQj6yv-mQ6FgmldM,3220
14
15
  claude_mpm/agents/agent-template.yaml,sha256=mRlz5Yd0SmknTeoJWgFkZXzEF5T7OmGBJGs2-KPT93k,1969
@@ -22,8 +23,8 @@ claude_mpm/agents/frontmatter_validator.py,sha256=GiCxr13b-SFwvZNbNHDO0lFH9dFhsQ
22
23
  claude_mpm/agents/system_agent_config.py,sha256=HBDrtRld1ruPqrThA0j4vtMr4cBt0fT7qjDeCR79bps,24105
23
24
  claude_mpm/agents/schema/agent_schema.json,sha256=3p-_vcEAz5Py0ik7LPSJB9CQyE9L_zHhC82J0eCfn78,8784
24
25
  claude_mpm/agents/templates/__init__.py,sha256=kghxAWs3KvcAA9Esk3NI7caumYgW6fiW8vRO1-MEndU,2735
25
- claude_mpm/agents/templates/agent-manager.json,sha256=pRMILoAMxVZcc5g_XwStpJoz2K8LJo8sUyJB6bep6rI,628
26
- claude_mpm/agents/templates/agent-manager.md,sha256=vsy49vWxIlMVLX6H7_BtjPDaR4j_gkechvgWbN88aPI,8218
26
+ claude_mpm/agents/templates/agent-manager.json,sha256=nX7kfxb1AjbUXqi2tHKgNnWVVB-eLRUHV3O7gqHxjEk,628
27
+ claude_mpm/agents/templates/agent-manager.md,sha256=rWQ7MREoMdQtJhMujEPVYud6N-fGvicMuBvYIdRo22w,19418
27
28
  claude_mpm/agents/templates/api_qa.json,sha256=hTdeNOgA2tzADCb2V9ExguFSvAv267yQYqa26AnOQHk,5786
28
29
  claude_mpm/agents/templates/code_analyzer.json,sha256=UOTXl6VTmzx1OoF5M4Bc9lQGriLf6Jq84rz30J77tEM,4718
29
30
  claude_mpm/agents/templates/data_engineer.json,sha256=rP3ffuaHwe0xGVpXShhVHTn1jEVMV2aAlnNGZL8j3jc,5629
@@ -55,8 +56,8 @@ claude_mpm/cli/commands/aggregate.py,sha256=rLwZxXmIyTPuDUYKTooVtTgiW4mU3vw4_383
55
56
  claude_mpm/cli/commands/cleanup.py,sha256=c4QyAs9odx7__rSM9RDy2r9iwPlrfeIzx2vINbl7WaA,19694
56
57
  claude_mpm/cli/commands/cleanup_orphaned_agents.py,sha256=JR8crvgrz7Sa6d-SI-gKywok5S9rwc_DzDVk_h85sVs,4467
57
58
  claude_mpm/cli/commands/config.py,sha256=Yfi8WO-10_MYz2QipFw-yEzVvHKNQ6iSQXeyW5J85Cg,18559
58
- claude_mpm/cli/commands/configure.py,sha256=IDZWyvvj04HCW6jpZovJhX0EgeGlp0FAsR0Ty3LhuPk,46684
59
- claude_mpm/cli/commands/configure_tui.py,sha256=YOetibU9oNyc6xYwKdb9aiBJITemYFPHsZAzWxGtDQQ,66864
59
+ claude_mpm/cli/commands/configure.py,sha256=SBWh4ZMxEvB8yIXk4SiJjkcZ845XvYXVhxwqNLtemJg,53003
60
+ claude_mpm/cli/commands/configure_tui.py,sha256=dTghSkJqvY1xdbDyCeNy5gxmyQOVCCr01cH_4aUVe4I,66929
60
61
  claude_mpm/cli/commands/doctor.py,sha256=bOZzDNxEMNMZYrJnu_V82tyZ12r5FiBRQNLVfSVvRIQ,5774
61
62
  claude_mpm/cli/commands/info.py,sha256=_hWH7uNv9VLO0eZh9Ua6qc5L1Z66kYj9ATzU4Q8UkSM,7377
62
63
  claude_mpm/cli/commands/mcp.py,sha256=f4PmzAt89cmXXHBJAul2nFh7-EStDY97_J4vaL690CE,7029
@@ -76,7 +77,7 @@ claude_mpm/cli/parsers/agent_manager_parser.py,sha256=8HuGpTnHSOnTOqOHriBTzi8EzK
76
77
  claude_mpm/cli/parsers/agents_parser.py,sha256=DxAZMotptyaJbROqbRbTipOKLLJ96ATrXhwiFK6Dbm0,5450
77
78
  claude_mpm/cli/parsers/base_parser.py,sha256=eIh4IOO8eSV971Z3paYmq10CBLRfm9ionv7Z1Hxg4FI,12346
78
79
  claude_mpm/cli/parsers/config_parser.py,sha256=wp6NbV8_p9txP28MXFcQrri0JDIfGFM7u4aJbYJXcYQ,2699
79
- claude_mpm/cli/parsers/configure_parser.py,sha256=8ZYCgnMo7zH5X44hdQe3af9655jNrjITXVk3s3B9tUc,3880
80
+ claude_mpm/cli/parsers/configure_parser.py,sha256=cg3VXrnSqi9QLhMihJXeKDjtp1sS5jSHZNM_prgm0S4,4598
80
81
  claude_mpm/cli/parsers/mcp_parser.py,sha256=zW4wClYOGf_o8yRediJkQRxgta2RI6S3IG_QDgAkp-k,5992
81
82
  claude_mpm/cli/parsers/memory_parser.py,sha256=ZwCDxJEgp-w03L-1tZsWTgisiwamP42s424bA5bvDJc,4760
82
83
  claude_mpm/cli/parsers/monitor_parser.py,sha256=Go78VOFQCts2fouv33tKfd303w0mVPpJiuBbRBGK5x0,4525
@@ -95,7 +96,7 @@ claude_mpm/config/__init__.py,sha256=V2dyJQ8_gVCpNiCg8zYTQqE1RSeON5Zm8n5Ndkqhp1g
95
96
  claude_mpm/config/agent_config.py,sha256=d_cHE4HMkeZZrGjDGpBP655llV64p_E8DRDPPdsO1jg,14829
96
97
  claude_mpm/config/experimental_features.py,sha256=ma-Va7CVqOYrUEGZW6A4gdMRLHOpovHf8pHgP_3-xr0,7481
97
98
  claude_mpm/config/paths.py,sha256=Dl35_QF0kfC2I6Fy7ETcNjz7jlumNGt45qlRKqsPJrk,7611
98
- claude_mpm/config/socketio_config.py,sha256=qNLvjKZWUZEsNmSXUe0ueXu1q7-EOlxK3mdQquEZwTI,9714
99
+ claude_mpm/config/socketio_config.py,sha256=Kv5vxQ-UAKAFsa_FukkrujnBzFAwOi2KbEa3mFX3UXQ,11343
99
100
  claude_mpm/core/__init__.py,sha256=QhEX_NpiCprUp87bV75FnMapblMeqC5soNVJXVvZObc,887
100
101
  claude_mpm/core/agent_name_normalizer.py,sha256=_h92sTPltmvqevCjdKQ7EsOz-CAm1-hd8GOubWjuRgw,8907
101
102
  claude_mpm/core/agent_registry.py,sha256=cPQsOSIyrspr3KpS-P9MQ6Dv_BLXa9BWhs9RM0iu4C4,18798
@@ -178,7 +179,7 @@ claude_mpm/dashboard/static/dist/components/working-directory.js,sha256=7V1pBeux
178
179
  claude_mpm/dashboard/static/js/connection-manager.js,sha256=IJrtihUCQqkECXhiqy53vAJIdxNp7pJVIsV2ocos3As,17981
179
180
  claude_mpm/dashboard/static/js/dashboard.js,sha256=bacYhLFaxQIVOeRaUZProQ0Px6CeZFZmgnwZoHjKWls,71535
180
181
  claude_mpm/dashboard/static/js/extension-error-handler.js,sha256=DZHrJ3gbfv4nsjmZpNMj-Sc3GKjVJ5ds8lgoaLRnq5I,6274
181
- claude_mpm/dashboard/static/js/socket-client.js,sha256=i19ZYpUqO38kXubk5NpuVXlSlz8UhorTEYYCJFxbcLM,35984
182
+ claude_mpm/dashboard/static/js/socket-client.js,sha256=eXVTR3EQ6uK9PEjjmwT_8EpPDPPpCRbWiNBK5fS5CJk,37436
182
183
  claude_mpm/dashboard/static/js/components/agent-hierarchy.js,sha256=Xihxog_vJrk8VBEkDogV_wbye2GIFWmH71VQ1lETOHk,28243
183
184
  claude_mpm/dashboard/static/js/components/agent-inference.js,sha256=RUVZ_fLOyDkHYjrROen_Pzzay79Bh29eXp_GRIPbIRg,37493
184
185
  claude_mpm/dashboard/static/js/components/build-tracker.js,sha256=IBfKpoSKWD5QMPN4tOZl-E84Q3QADYVsZ76ickrKW8E,11485
@@ -212,11 +213,12 @@ claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py,sha256=IZKE3cJok_gb4UGFEt
212
213
  claude_mpm/hooks/claude_hooks/hook_handler_original.py,sha256=AOcGOf2WiA_aaRsaENKBvaj3Vi_UzeL_zaEgN3zxCrk,42964
213
214
  claude_mpm/hooks/claude_hooks/hook_handler_refactored.py,sha256=e8phCM18f-IcovV9_xVNYSV8nndVKdzmFJa-xjKGkq8,12983
214
215
  claude_mpm/hooks/claude_hooks/hook_wrapper.sh,sha256=4lG3TlLVoVfTJipPj1X_ICUlS-KpnkbUp1U3oSq80Bw,2476
216
+ claude_mpm/hooks/claude_hooks/installer.py,sha256=IZ95d0lxRneUYQ3hIeHtzzDsEc-DqLaiwcwGEEqg-7A,15684
215
217
  claude_mpm/hooks/claude_hooks/memory_integration.py,sha256=TXLavDM9eEoakPX_n2WtnfXyqGn80N-xgAvcYgvoW8s,8832
216
218
  claude_mpm/hooks/claude_hooks/response_tracking.py,sha256=4RcM54LyYeINf3A_toaSOPuD3oXS6jZtiRstHxgSOao,14990
217
219
  claude_mpm/hooks/claude_hooks/tool_analysis.py,sha256=3_o2PP9D7wEMwLriCtIBOw0cj2fSZfepN7lI4P1meSQ,7862
218
220
  claude_mpm/hooks/claude_hooks/services/__init__.py,sha256=OIYOKsUNw1BHYawOCp-KFK5kmQKuj92cCqCEPO0nwo0,585
219
- claude_mpm/hooks/claude_hooks/services/connection_manager.py,sha256=brkw3wE5m5RWa3fOo4noRO0xl0GpLWUPVacxcP6QYpM,7496
221
+ claude_mpm/hooks/claude_hooks/services/connection_manager.py,sha256=brj_FrSRwusbzyQo8a8DRGruTRqucfNWZNSDiNkbLe8,8290
220
222
  claude_mpm/hooks/claude_hooks/services/connection_manager_http.py,sha256=-DZ2seh1tpdo_RQPo5qkkJBcbjEkSpIFWOMMij1V0So,7686
221
223
  claude_mpm/hooks/claude_hooks/services/duplicate_detector.py,sha256=Fh9LmEMsVmQM9t0U1v2l_fuBwvNpVkl_0EF8Wu5KLHQ,3882
222
224
  claude_mpm/hooks/claude_hooks/services/state_manager.py,sha256=c7OldfemaMU37YGJxgO2uEcTOuPc-C80SRhzEH07j7I,11072
@@ -258,7 +260,7 @@ claude_mpm/services/version_service.py,sha256=Ql2HKB9OoHGdqkfWyFFLSSVBwShap0dFIj
258
260
  claude_mpm/services/agents/__init__.py,sha256=8cRLDOXq_CGH3uVl6Uk816wsx7VY8HSDOYms2MPaFBA,2175
259
261
  claude_mpm/services/agents/agent_builder.py,sha256=l5scGcTeJcGwe-i1VUcrzWEwub_mcruZBn6Q51ZDaCM,14803
260
262
  claude_mpm/services/agents/deployment/__init__.py,sha256=iprW-Ww3LBtWu9pVFjAX45_CswfSqnPMoG0QoFPd1Dg,539
261
- claude_mpm/services/agents/deployment/agent_config_provider.py,sha256=_voUMuk_6IiJy_VHloDC6OA803-Z2wENOK60extV_ZU,13312
263
+ claude_mpm/services/agents/deployment/agent_config_provider.py,sha256=gtQcbGr0GspZYplbeRkGXd3BAXl3_pWhKSsbfiSVTww,15234
262
264
  claude_mpm/services/agents/deployment/agent_configuration_manager.py,sha256=5nf69hfo7lUa3_55sDcU5WfpzBtOZCMSTPYGr2dlIdY,12173
263
265
  claude_mpm/services/agents/deployment/agent_definition_factory.py,sha256=DaJ__b3-ADinfd-qNnW6LKWfclOaZbkBBcfuHgqlUic,2697
264
266
  claude_mpm/services/agents/deployment/agent_deployment.py,sha256=6YFg1ZcAMI_cb7xGhSm0e3qdPOrVNoQ_-o1qoc_PM2k,35514
@@ -385,13 +387,13 @@ claude_mpm/services/diagnostics/checks/common_issues_check.py,sha256=Yi73_1yGNcQ
385
387
  claude_mpm/services/diagnostics/checks/configuration_check.py,sha256=mgqFsyr4W73gFGMF7kz5u4lloUMhTty5BHuErf0I0Uo,11176
386
388
  claude_mpm/services/diagnostics/checks/filesystem_check.py,sha256=V5HoHDYlSuoK2lFv946Jhd81LrA0om71NWugnRxFvSE,8296
387
389
  claude_mpm/services/diagnostics/checks/installation_check.py,sha256=beGk3r-Kwdy-DaodBl-7z0zA1hqLwBNNxAhYkDw7Qr8,16064
388
- claude_mpm/services/diagnostics/checks/instructions_check.py,sha256=PzbJaDnX8fJDz2XJjbvFhDmy0efBgmTmw8KN6e8Se2Q,16339
390
+ claude_mpm/services/diagnostics/checks/instructions_check.py,sha256=6AgotHjLi2QgCshDfXAK5Bb-eTWU1SfWBUwpjUSSi9E,16317
389
391
  claude_mpm/services/diagnostics/checks/mcp_check.py,sha256=_eM210SIyHwAcWi1AxUeRoessxumpTrSeVdHVJK5ja0,12191
390
392
  claude_mpm/services/diagnostics/checks/monitor_check.py,sha256=NUx5G1yjHWlukZmwhUz4o8STRWgsQEx01YjIMReNC0A,10096
391
393
  claude_mpm/services/diagnostics/checks/startup_log_check.py,sha256=DrXdml2rHvmhFBdb_sntE3xmwaP_DZIKjdVbCn8Dy7E,12258
392
394
  claude_mpm/services/event_bus/__init__.py,sha256=ETCo4a6puIeyVWAv55uCDjjhzNyUwbVAHEcAVkVapx8,688
393
395
  claude_mpm/services/event_bus/config.py,sha256=MJdOBK3XgLpW66N81tetThslnKsFIWYtbqRamyTDxlU,4943
394
- claude_mpm/services/event_bus/direct_relay.py,sha256=F_N5oqE49u1pVM22Vx2V3rQrGKQmqxEyHt-UF7RJKAk,7253
396
+ claude_mpm/services/event_bus/direct_relay.py,sha256=HvI6pSvP-DFZCrUH1gprhQS0rrf3eYAw6rAtyZJXnhE,13490
395
397
  claude_mpm/services/event_bus/event_bus.py,sha256=KQ8FpbHGsEVlygZj6CTYgugXL7Ht6KGlf1FAT4WJKEI,11920
396
398
  claude_mpm/services/event_bus/relay.py,sha256=yQ6Ow2rOj3dtNtYi2Vh4ToTouo-1eOiigtjnBM2w2Wo,9352
397
399
  claude_mpm/services/events/__init__.py,sha256=dna3DFYCxt9Y1jgK-0f2KPlX-jFo4n2dJyy9WKZkNlA,1092
@@ -495,7 +497,7 @@ claude_mpm/services/socketio/migration_utils.py,sha256=1pK_zGZ8Pd57pCg1O-3gKT8i7
495
497
  claude_mpm/services/socketio/handlers/__init__.py,sha256=zc1eo5hR5xDtnOZCeX38JNo8j9Vs10kV1cxZF20ZS4A,789
496
498
  claude_mpm/services/socketio/handlers/base.py,sha256=DjUODCOLTQSsC_-NP9yr-8g77arawmsRrM5KC06aDmw,4845
497
499
  claude_mpm/services/socketio/handlers/connection.py,sha256=sa6Rg5Y9tcf-e4PEb6f4fNhFQcpZ9WbwdiGXmkzlFTs,26781
498
- claude_mpm/services/socketio/handlers/connection_handler.py,sha256=7TMfi41nn_-5UUu_Zfh2u3sskefQ6adljgd_RDhqFLE,13749
500
+ claude_mpm/services/socketio/handlers/connection_handler.py,sha256=DTY0pa--HQu4C6-WCgE1zskvHm3gVuEKWwaSFNBAoec,13287
499
501
  claude_mpm/services/socketio/handlers/file.py,sha256=itpPa5OAow5_OXrTOXk0vsyuEYm4iVmxwN9xowy7jiY,8341
500
502
  claude_mpm/services/socketio/handlers/git.py,sha256=xIjGGShyVNXzCtJfydbbnFTJhqzXwHLzGhLrqgy0JGQ,37934
501
503
  claude_mpm/services/socketio/handlers/hook.py,sha256=JVQufL_u85z3r-n3fnKExuziheJ2lzY6d0GDoUB9iXs,7786
@@ -504,10 +506,10 @@ claude_mpm/services/socketio/handlers/project.py,sha256=yYqWlPfPanA7zH7dgQnP3EpO
504
506
  claude_mpm/services/socketio/handlers/registry.py,sha256=f4eELY04c23F0S8A5cxm9PDfSiGFumnfNgg7Ua0TsGU,7946
505
507
  claude_mpm/services/socketio/server/__init__.py,sha256=S486w-i-hBo3rNW_AtzxbasEgP32By-uI9zz7hzKz-o,640
506
508
  claude_mpm/services/socketio/server/broadcaster.py,sha256=y_D-fDhSD2NZI0cP9wuoB2nlI7VkKjzW_EjVmP-xd5Y,21375
507
- claude_mpm/services/socketio/server/connection_manager.py,sha256=P22O3FxLdADUxMDCSr0Vzr0CxnExgLYYh_Y13att6T4,17747
508
- claude_mpm/services/socketio/server/core.py,sha256=nY-EpBB-qsPgiSH-w46C3rtbBCNmXbG72zyYFSX65gI,21301
509
+ claude_mpm/services/socketio/server/connection_manager.py,sha256=ovta_Ar9dPskBPTnY4YZtiDAx0PpHQL_1ThTXLpbM4E,21181
510
+ claude_mpm/services/socketio/server/core.py,sha256=yCTky7zBeiz_eLFMPLNwAm-sV0CVornBeIAhxIenkE8,22593
509
511
  claude_mpm/services/socketio/server/eventbus_integration.py,sha256=6LkK8W9wTiNd8d9KoAH2IY1b4osyGGgGaJ0DmwIwnVM,7790
510
- claude_mpm/services/socketio/server/main.py,sha256=uKsh03fY-5_8wK9JOKm8DJz679Gv0mFkfoFxqrF4mxI,16466
512
+ claude_mpm/services/socketio/server/main.py,sha256=nDkdMF96-PvXD8x69LAFSz-y35u58wVl0UwxSfAapZY,19226
511
513
  claude_mpm/services/ticket_services/__init__.py,sha256=I01W25n-tBWwZ0TD-dPA63nqzCU2KnpOvbqeysmaa2E,798
512
514
  claude_mpm/services/ticket_services/crud_service.py,sha256=4Ab1HONY219QSdRaLTgRInm6DNJXIUKiihyAree8y8A,11193
513
515
  claude_mpm/services/ticket_services/formatter_service.py,sha256=MQ981yaFuvXWUDLpHHiasc8BIFdeIeMS7Us0CgZHJ0A,9101
@@ -542,9 +544,9 @@ claude_mpm/utils/subprocess_utils.py,sha256=zgiwLqh_17WxHpySvUPH65pb4bzIeUGOAYUJ
542
544
  claude_mpm/validation/__init__.py,sha256=YZhwE3mhit-lslvRLuwfX82xJ_k4haZeKmh4IWaVwtk,156
543
545
  claude_mpm/validation/agent_validator.py,sha256=3Lo6LK-Mw9IdnL_bd3zl_R6FkgSVDYKUUM7EeVVD3jc,20865
544
546
  claude_mpm/validation/frontmatter_validator.py,sha256=u8g4Eyd_9O6ugj7Un47oSGh3kqv4wMkuks2i_CtWRvM,7028
545
- claude_mpm-4.1.6.dist-info/licenses/LICENSE,sha256=lpaivOlPuBZW1ds05uQLJJswy8Rp_HMNieJEbFlqvLk,1072
546
- claude_mpm-4.1.6.dist-info/METADATA,sha256=WzfyfF1uc4Ny1XukCgWXC1d884_DJAFtDzw0JHLTNu4,13386
547
- claude_mpm-4.1.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
548
- claude_mpm-4.1.6.dist-info/entry_points.txt,sha256=FDPZgz8JOvD-6iuXY2l9Zbo9zYVRuE4uz4Qr0vLeGOk,471
549
- claude_mpm-4.1.6.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
550
- claude_mpm-4.1.6.dist-info/RECORD,,
547
+ claude_mpm-4.1.8.dist-info/licenses/LICENSE,sha256=lpaivOlPuBZW1ds05uQLJJswy8Rp_HMNieJEbFlqvLk,1072
548
+ claude_mpm-4.1.8.dist-info/METADATA,sha256=aibiLTs5vPDFdsedewGyRvNB8Geo6-89Su9iHskowTU,13386
549
+ claude_mpm-4.1.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
550
+ claude_mpm-4.1.8.dist-info/entry_points.txt,sha256=FDPZgz8JOvD-6iuXY2l9Zbo9zYVRuE4uz4Qr0vLeGOk,471
551
+ claude_mpm-4.1.8.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
552
+ claude_mpm-4.1.8.dist-info/RECORD,,