overmind-mcp 3.2.5 → 3.2.6

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.
@@ -148,15 +148,27 @@ if [ "$OS" = "Darwin" ]; then
148
148
  track_warn "Homebrew non trouvé — installez: https://brew.sh"
149
149
  track_warn "Bypass: installez Docker et utilisez overmind-postgres-mcp up"
150
150
  else
151
- # PostgreSQL
152
- if brew list postgresql@18 >/dev/null 2>&1; then
153
- ok "postgresql@18 déjà installé"
154
- else
155
- log "Installation postgresql@18 via brew..."
156
- brew install postgresql@18 2>/dev/null || {
157
- track_warn "postgresql@18 non disponible, fallback postgresql@16"
158
- brew install postgresql@16 2>/dev/null || track_error "brew install postgresql a échoué"
151
+ # PostgreSQL — brew a postgresql@17 en stable, @18 peut ne pas exister encore
152
+ PG_BREW_VER=""
153
+ for pgver in postgresql@18 postgresql@17 postgresql@16 postgresql@15 postgresql@14 postgresql; do
154
+ if brew list "$pgver" >/dev/null 2>&1; then
155
+ PG_BREW_VER="$pgver"
156
+ ok "$pgver déjà installé"
157
+ break
158
+ fi
159
+ done
160
+ if [ -z "$PG_BREW_VER" ]; then
161
+ log "Installation PostgreSQL via brew (dernière version stable)..."
162
+ brew install postgresql 2>/dev/null && PG_BREW_VER="postgresql" || {
163
+ # Fallback: essayer les versions numérotées
164
+ for pgver in postgresql@17 postgresql@16 postgresql@15; do
165
+ log "Tentative $pgver..."
166
+ brew install "$pgver" 2>/dev/null && PG_BREW_VER="$pgver" && break
167
+ done
159
168
  }
169
+ if [ -z "$PG_BREW_VER" ]; then
170
+ track_error "brew install postgresql a échoué"
171
+ fi
160
172
  fi
161
173
 
162
174
  # pgvector
@@ -164,14 +176,22 @@ if [ "$OS" = "Darwin" ]; then
164
176
  ok "pgvector déjà installé"
165
177
  else
166
178
  log "Installation pgvector via brew..."
167
- brew install pgvector 2>/dev/null || track_warn "pgvector non disponible via brew — installez manuellement"
179
+ brew install pgvector 2>/dev/null || {
180
+ track_warn "pgvector non disponible via brew — compilation depuis source..."
181
+ (
182
+ cd /tmp && git clone --depth 1 https://github.com/pgvector/pgvector.git 2>/dev/null && \
183
+ cd pgvector && make 2>/dev/null && make install 2>/dev/null
184
+ ) && ok "pgvector compilé depuis source" || track_warn "pgvector compilation échouée"
185
+ }
168
186
  fi
169
187
 
170
188
  # Démarrer le service
171
- brew services start postgresql@18 2>/dev/null || brew services start postgresql@16 2>/dev/null || true
172
- sleep 3
173
- PG_INSTALLED=true
174
- ok "Service PostgreSQL démarré via brew"
189
+ if [ -n "$PG_BREW_VER" ]; then
190
+ brew services start "$PG_BREW_VER" 2>/dev/null || true
191
+ sleep 3
192
+ PG_INSTALLED=true
193
+ ok "Service $PG_BREW_VER démarré via brew"
194
+ fi
175
195
  fi
176
196
 
177
197
  elif [ "$OS" = "Linux" ]; then
@@ -239,7 +259,27 @@ fi
239
259
  step "Base de données + pgvector"
240
260
 
241
261
  if [ "$PG_INSTALLED" = "true" ]; then
242
- sleep 2 # Laisser PG démarrer
262
+ # Wait for PostgreSQL to be ready (max 15s)
263
+ log "Attente démarrage PostgreSQL..."
264
+ PG_READY=false
265
+ for i in 1 2 3 4 5 6 7 8 9 10; do
266
+ if [ "$OS" = "Darwin" ]; then
267
+ if psql -U "$PG_SUPERUSER" -d postgres -c "SELECT 1" >/dev/null 2>&1; then
268
+ PG_READY=true; break
269
+ fi
270
+ else
271
+ if $SUDO -u postgres psql -c "SELECT 1" >/dev/null 2>&1; then
272
+ PG_READY=true; break
273
+ fi
274
+ fi
275
+ sleep 2
276
+ done
277
+
278
+ if [ "$PG_READY" = "true" ]; then
279
+ ok "PostgreSQL prêt"
280
+ else
281
+ track_warn "PostgreSQL ne répond pas après 20s"
282
+ fi
243
283
 
244
284
  # Créer la DB si elle n'existe pas
245
285
  DB_EXISTS=false
@@ -454,6 +494,67 @@ UNIT
454
494
  fi
455
495
 
456
496
  $SUDO systemctl daemon-reload
497
+
498
+ # ─── Gestion des conflits de port ────────────────────────────
499
+ # Tue UNIQUEMENT les zombies/doublons, jamais un service sain.
500
+ for port in $MCP_PORT_CORE $MCP_PORT_PG; do
501
+ # Récupérer TOUS les PIDs sur ce port
502
+ PIDS_ON_PORT=$(lsof -tiTCP:$port -sTCP:LISTEN 2>/dev/null || ss -tlnp 2>/dev/null | grep ":$port " | grep -oP 'pid=\K[0-9]+' | head -5)
503
+
504
+ if [ -n "$PIDS_ON_PORT" ]; then
505
+ PID_COUNT=$(echo "$PIDS_ON_PORT" | wc -w)
506
+
507
+ for pid in $PIDS_ON_PORT; do
508
+ [ -z "$pid" ] && continue
509
+
510
+ # Vérifier si c'est un process zombie (Z état)
511
+ PID_STATE=$(ps -o stat= -p "$pid" 2>/dev/null | head -1)
512
+ PID_CMD=$(ps -o args= -p "$pid" 2>/dev/null | head -1)
513
+
514
+ # Cas 1: Zombie → kill certain
515
+ if echo "$PID_STATE" | grep -q 'Z'; then
516
+ warn "Port :$port — PID $pid est un ZOMBIE → kill"
517
+ kill -9 "$pid" 2>/dev/null || $SUDO kill -9 "$pid" 2>/dev/null || true
518
+ sleep 1
519
+ continue
520
+ fi
521
+
522
+ # Cas 2: Pas un process overmind/node → doublon parasite → kill
523
+ if ! echo "$PID_CMD" | grep -qE 'overmind|cli\.js|dist/index\.js'; then
524
+ warn "Port :$port — PID $pid est un doublon parasite ($PID_CMD) → kill"
525
+ kill "$pid" 2>/dev/null || $SUDO kill "$pid" 2>/dev/null || true
526
+ sleep 2
527
+ continue
528
+ fi
529
+
530
+ # Cas 3: Doublon (plusieurs process overmind sur le même port)
531
+ if [ "$PID_COUNT" -gt 1 ]; then
532
+ warn "Port :$port — doublon détecté ($PID_COUNT process) → kill du plus ancien ($pid)"
533
+ kill "$pid" 2>/dev/null || $SUDO kill "$pid" 2>/dev/null || true
534
+ sleep 2
535
+ continue
536
+ fi
537
+
538
+ # Cas 4: Process overmind unique et sain → on garde, systemd fera un restart
539
+ ok "Port :$port — PID $pid (overmind sain) — préservé, systemd takeover"
540
+ done
541
+
542
+ # Vérification finale
543
+ sleep 1
544
+ PID_AFTER=$(lsof -tiTCP:$port -sTCP:LISTEN 2>/dev/null | head -1)
545
+ if [ -n "$PID_AFTER" ]; then
546
+ AFTER_CMD=$(ps -o args= -p "$PID_AFTER" 2>/dev/null | head -1)
547
+ if echo "$AFTER_CMD" | grep -qE 'overmind|cli\.js|dist/index\.js'; then
548
+ ok "Port :$port — process overmind sain conservé (PID $PID_AFTER)"
549
+ else
550
+ track_warn "Port :$port — toujours occupé par un process non-overmind"
551
+ fi
552
+ else
553
+ ok "Port :$port libéré"
554
+ fi
555
+ fi
556
+ done
557
+
457
558
  $SUDO systemctl enable --now overmind-mcp.service 2>/dev/null || track_warn "systemctl enable overmind-mcp"
458
559
  ok "overmind-mcp.service: $($SUDO systemctl is-active overmind-mcp.service 2>/dev/null || echo '?')"
459
560
 
@@ -502,6 +603,53 @@ elif [ "$OS" = "Darwin" ]; then
502
603
  PLIST
503
604
  launchctl bootout gui/$(id -u) "$plist" 2>/dev/null || true
504
605
  launchctl bootstrap gui/$(id -u) "$plist" 2>/dev/null || true
606
+
607
+ # ─── Gestion des conflits de port (macOS) ───────────────────
608
+ # Tue UNIQUEMENT zombies/doublons, jamais un process overmind sain.
609
+ PIDS_ON_PORT=$(lsof -tiTCP:$port -sTCP:LISTEN 2>/dev/null)
610
+ if [ -n "$PIDS_ON_PORT" ]; then
611
+ PID_COUNT=$(echo "$PIDS_ON_PORT" | wc -w)
612
+ for pid in $PIDS_ON_PORT; do
613
+ [ -z "$pid" ] && continue
614
+ PID_STATE=$(ps -o stat= -p "$pid" 2>/dev/null | head -1)
615
+ PID_CMD=$(ps -o args= -p "$pid" 2>/dev/null | head -1)
616
+
617
+ # Cas 1: Zombie → kill
618
+ if echo "$PID_STATE" | grep -q 'Z'; then
619
+ warn "Port :$port — PID $pid est un ZOMBIE → kill"
620
+ kill -9 "$pid" 2>/dev/null || true
621
+ sleep 1
622
+ continue
623
+ fi
624
+
625
+ # Cas 2: Process non-overmind → parasite → kill
626
+ if ! echo "$PID_CMD" | grep -qE 'overmind|cli\.js|dist/index\.js'; then
627
+ warn "Port :$port — PID $pid parasite ($PID_CMD) → kill"
628
+ kill "$pid" 2>/dev/null || true
629
+ sleep 2
630
+ continue
631
+ fi
632
+
633
+ # Cas 3: Doublon overmind
634
+ if [ "$PID_COUNT" -gt 1 ]; then
635
+ warn "Port :$port — doublon ($PID_COUNT process) → kill $pid"
636
+ kill "$pid" 2>/dev/null || true
637
+ sleep 2
638
+ continue
639
+ fi
640
+
641
+ # Cas 4: overmind sain unique → préservé
642
+ ok "Port :$port — PID $pid (overmind sain) préservé"
643
+ done
644
+
645
+ sleep 1
646
+ PID_AFTER=$(lsof -tiTCP:$port -sTCP:LISTEN 2>/dev/null | head -1)
647
+ if [ -z "$PID_AFTER" ]; then
648
+ ok "Port :$port libéré"
649
+ # Re-bootstrap après libération
650
+ launchctl bootstrap gui/$(id -u) "$plist" 2>/dev/null || true
651
+ fi
652
+ fi
505
653
  ok "launchd: com.overmind.${name} chargé"
506
654
  }
507
655
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "overmind-mcp",
3
- "version": "3.2.5",
3
+ "version": "3.2.6",
4
4
  "description": "Orchestrateur universel agents IA multi-modeles via MCP. Inclut le protocole 'Custom-Nickname' pour identifier vos agents avec des surnoms originaux (The Chaos Prophet, Shadow Sniper, etc.), l'isolation mémoire (Private Memory Context) et le support pour QwenCli et Nous Hermes. Installation automatique des dépendances Docker (PostgreSQL, pgvector) inclus.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -43,9 +43,10 @@ function logSection(title) {
43
43
 
44
44
  function runCommand(cmd, options = {}) {
45
45
  try {
46
- return execSync(cmd, { stdio: 'inherit', ...options });
47
- } catch (error) {
48
- return null;
46
+ const result = execSync(cmd, { stdio: 'pipe', encoding: 'utf8', ...options });
47
+ return typeof result === 'string' ? result : String(result ?? '');
48
+ } catch {
49
+ return '';
49
50
  }
50
51
  }
51
52
 
@@ -82,8 +83,14 @@ function commandUp() {
82
83
  const pgDb = getEnvVar('POSTGRES_DATABASE') || getEnvVar('POSTGRES_DB') || 'overmind_memory';
83
84
  const pgPort = getEnvVar('POSTGRES_PORT') || '5432';
84
85
 
85
- // Remove ancien container stopped
86
- runCommand('docker rm -f overmind-postgres-pgvector 2>/dev/null', { stdio: 'pipe' });
86
+ // Remove ancien container SEULEMENT s'il est stopped (jamais un running)
87
+ const isRunning = runCommand('docker ps --filter "name=overmind-postgres-pgvector" --format "{{.Names}}"', { stdio: 'pipe' });
88
+ if (!isRunning || isRunning.trim().length === 0) {
89
+ const isStopped = runCommand('docker ps -a --filter "name=overmind-postgres-pgvector" --filter "status=exited" --format "{{.Names}}"', { stdio: 'pipe' });
90
+ if (isStopped && isStopped.trim().length > 0) {
91
+ runCommand('docker rm -f overmind-postgres-pgvector 2>/dev/null', { stdio: 'pipe' });
92
+ }
93
+ }
87
94
 
88
95
  console.log('🚀 Démarrage PostgreSQL + pgvector...');
89
96
  const result = runCommand(
@@ -197,8 +197,11 @@ async function setupPostgreSQL() {
197
197
  'Téléchargement image'
198
198
  );
199
199
 
200
- // Remove existing if stopped
201
- runCommand('docker rm -f overmind-postgres-pgvector', { stdio: 'pipe' });
200
+ // Remove existing ONLY if stopped (never kill a running container)
201
+ const existingStopped = runCommand('docker ps -a --filter "name=overmind-postgres-pgvector" --filter "status=exited" --format "{{.Names}}"', { stdio: 'pipe' });
202
+ if (existingStopped) {
203
+ runCommand('docker rm -f overmind-postgres-pgvector', { stdio: 'pipe' });
204
+ }
202
205
 
203
206
  const runCmd = [
204
207
  'docker', 'run', '-d',