overmind-mcp 2.0.6 → 2.0.7
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.
- package/README.md +145 -145
- package/dist/server.js +51 -51
- package/docs/INDEX.md +144 -144
- package/docs/api/prompt/Claude_code.md +74 -74
- package/docs/api/prompt/Kilo.md +74 -74
- package/docs/api/prompt/Kilo_Hermes.md +170 -170
- package/docs/api/prompt/Minimax4.md +96 -96
- package/docs/changelog/CHANGELOG.add.md +106 -106
- package/docs/guides/DEPLOYMENT.md +418 -418
- package/docs/guides/SWARM_USAGE.md +444 -444
- package/install-overmind-unix.sh +250 -250
- package/install-overmind-windows.bat +257 -257
- package/package.json +131 -127
- package/scripts/postinstall.mjs +465 -465
package/scripts/postinstall.mjs
CHANGED
|
@@ -1,465 +1,465 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* ═══════════════════════════════════════════════════════════════════════════════
|
|
4
|
-
* OVERMIND-MCP - POST-INSTALL AUTOMATIQUE
|
|
5
|
-
* ═════════════════════════════════════════════════════════════════════════════
|
|
6
|
-
* Script exécuté automatiquement après npm install -g overmind-mcp
|
|
7
|
-
* INSTALLE ET DÉMARRE TOUT AUTOMATIQUEMENT :
|
|
8
|
-
* - Vérifie Docker
|
|
9
|
-
* - Installe PostgreSQL + pgvector (si absent)
|
|
10
|
-
* - Copie .env.example → .env
|
|
11
|
-
* - Copie .mcp.json.example → .mcp.json
|
|
12
|
-
* - Télécharge et démarre TOUTE l'infrastructure Docker
|
|
13
|
-
* - Valide tous les services
|
|
14
|
-
* - Montre où les voir dans Docker Desktop
|
|
15
|
-
* ═══════════════════════════════════════════════════════════════════════════════
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import { execSync, spawn } from 'child_process';
|
|
19
|
-
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
|
|
20
|
-
import { join } from 'path';
|
|
21
|
-
import { fileURLToPath } from 'url';
|
|
22
|
-
import { dirname } from 'path';
|
|
23
|
-
|
|
24
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
25
|
-
const __dirname = dirname(__filename);
|
|
26
|
-
|
|
27
|
-
const INSTALL_DIR = join(
|
|
28
|
-
process.env.HOME || process.env.USERPROFILE || process.env.HOMEPATH,
|
|
29
|
-
'.overmind'
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
33
|
-
// COLORS
|
|
34
|
-
// ═════════════════════════════════════════════════════════════════════════════
|
|
35
|
-
|
|
36
|
-
const COLORS = {
|
|
37
|
-
cyan: '\x1b[36m',
|
|
38
|
-
green: '\x1b[32m',
|
|
39
|
-
yellow: '\x1b[33m',
|
|
40
|
-
red: '\x1b[31m',
|
|
41
|
-
white: '\x1b[37m',
|
|
42
|
-
reset: '\x1b[0m'
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
function log(color, str) {
|
|
46
|
-
console.log(`${color}${str}${COLORS.reset}`);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function logSection(title) {
|
|
50
|
-
console.log('\n╔══════════════════════════════════════════════════════════════════╗');
|
|
51
|
-
console.log(`║ ${title.padEnd(64)} ║`);
|
|
52
|
-
console.log('╚══════════════════════════════════════════════════════════════════╝');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function runCommand(cmd, options = {}) {
|
|
56
|
-
try {
|
|
57
|
-
return execSync(cmd, { stdio: 'pipe', encoding: 'utf8', ...options });
|
|
58
|
-
} catch {
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async function runCommandAsync(cmd, description) {
|
|
64
|
-
return new Promise((resolve, reject) => {
|
|
65
|
-
console.log(`🔧 ${description}`);
|
|
66
|
-
console.log(` $ ${cmd}`);
|
|
67
|
-
|
|
68
|
-
const child = spawn(cmd, { shell: true, stdio: 'inherit' });
|
|
69
|
-
|
|
70
|
-
child.on('close', (code) => {
|
|
71
|
-
if (code === 0) {
|
|
72
|
-
console.log(`✅ ${description} terminé`);
|
|
73
|
-
resolve(true);
|
|
74
|
-
} else {
|
|
75
|
-
console.error(`❌ Erreur (code ${code})`);
|
|
76
|
-
reject(new Error(`Command failed with code ${code}`));
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
child.on('error', (err) => {
|
|
81
|
-
console.error('❌ Erreur:', err.message);
|
|
82
|
-
reject(err);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
88
|
-
// INSTALLATION STEPS
|
|
89
|
-
// ═════════════════════════════════════════════════════════════════════════════
|
|
90
|
-
|
|
91
|
-
async function checkDocker() {
|
|
92
|
-
logSection('VÉRIFICATION DOCKER');
|
|
93
|
-
|
|
94
|
-
const version = runCommand('docker --version');
|
|
95
|
-
if (!version) {
|
|
96
|
-
log(COLORS.red, '❌ Docker non trouvé');
|
|
97
|
-
console.log('');
|
|
98
|
-
log(COLORS.yellow, '📥 Installation Docker requise:');
|
|
99
|
-
|
|
100
|
-
const platform = process.platform;
|
|
101
|
-
if (platform === 'win32') {
|
|
102
|
-
console.log(' Windows: https://www.docker.com/products/docker-desktop/');
|
|
103
|
-
} else if (platform === 'darwin') {
|
|
104
|
-
console.log(' macOS: https://www.docker.com/products/docker-desktop/');
|
|
105
|
-
} else {
|
|
106
|
-
console.log(' Linux: https://docs.docker.com/engine/install/');
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
log(COLORS.cyan, '\nAprès installation de Docker, relancez: npm install -g overmind-mcp');
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
log(COLORS.green, '✅ Docker détecté: ' + version.trim());
|
|
114
|
-
return true;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
async function setupPostgreSQL() {
|
|
118
|
-
logSection('INSTALLATION POSTGRESQL + PGVECTOR');
|
|
119
|
-
|
|
120
|
-
// Check if already exists
|
|
121
|
-
const existingContainer = runCommand(
|
|
122
|
-
'docker ps --filter "name=postgres-pgvector" --format "{{.Names}}"',
|
|
123
|
-
{ stdio: 'pipe' }
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
if (existingContainer) {
|
|
127
|
-
log(COLORS.green, '✅ PostgreSQL + pgvector déjà installé');
|
|
128
|
-
log(COLORS.cyan, ' Container: ' + existingContainer.trim());
|
|
129
|
-
return true;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
log(COLORS.yellow, '📦 Installation PostgreSQL + pgvector...');
|
|
133
|
-
|
|
134
|
-
try {
|
|
135
|
-
await runCommandAsync(
|
|
136
|
-
'docker pull pgvector/pgvector:pg16',
|
|
137
|
-
'Téléchargement image'
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
// Remove existing if stopped
|
|
141
|
-
runCommand('docker rm -f overmind-postgres-pgvector', { stdio: 'pipe' });
|
|
142
|
-
|
|
143
|
-
const runCmd = [
|
|
144
|
-
'docker', 'run', '-d',
|
|
145
|
-
'--name', 'overmind-postgres-pgvector',
|
|
146
|
-
'-p', '5432:5432',
|
|
147
|
-
'-e', 'POSTGRES_PASSWORD=overmind_temp_password_change_me',
|
|
148
|
-
'-e', 'POSTGRES_USER=postgres',
|
|
149
|
-
'-v', 'overmind_postgres_data:/var/lib/postgresql/data',
|
|
150
|
-
'--restart', 'unless-stopped',
|
|
151
|
-
'pgvector/pgvector:pg16'
|
|
152
|
-
].join(' ');
|
|
153
|
-
|
|
154
|
-
await runCommandAsync(runCmd, 'Démarrage PostgreSQL');
|
|
155
|
-
|
|
156
|
-
log(COLORS.cyan, '\n⏳ Attente démarrage PostgreSQL (20s)...');
|
|
157
|
-
await new Promise(resolve => setTimeout(resolve, 20000));
|
|
158
|
-
|
|
159
|
-
// Enable pgvector
|
|
160
|
-
await runCommandAsync(
|
|
161
|
-
`docker exec overmind-postgres-pgvector psql -U postgres -c "CREATE EXTENSION IF NOT EXISTS vector;"`,
|
|
162
|
-
'Activation pgvector'
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
log(COLORS.green, '\n✅ PostgreSQL + pgvector installés !');
|
|
166
|
-
return true;
|
|
167
|
-
} catch (error) {
|
|
168
|
-
log(COLORS.red, '❌ Erreur installation PostgreSQL: ' + error.message);
|
|
169
|
-
return false;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
async function setupInfrastructure() {
|
|
174
|
-
logSection('TÉLÉCHARGEMENT INFRASTRUCTURE');
|
|
175
|
-
|
|
176
|
-
mkdirSync(INSTALL_DIR, { recursive: true });
|
|
177
|
-
|
|
178
|
-
log(COLORS.yellow, '📥 Téléchargement fichiers docker-compose...');
|
|
179
|
-
|
|
180
|
-
const composeUrl = 'https://raw.githubusercontent.com/DeamonDev888/overmind-mcp/main/docker-compose.yml';
|
|
181
|
-
const exportersUrl = 'https://raw.githubusercontent.com/DeamonDev888/overmind-mcp/main/docker-compose.exporters.yml';
|
|
182
|
-
const envExampleUrl = 'https://raw.githubusercontent.com/DeamonDev888/overmind-mcp/main/.env.example';
|
|
183
|
-
const mcpExampleUrl = 'https://raw.githubusercontent.com/DeamonDev888/overmind-mcp/main/.mcp.json.example';
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
// Télécharger docker-compose.yml
|
|
187
|
-
const composeData = runCommand(`curl -sL ${composeUrl}`);
|
|
188
|
-
if (composeData) {
|
|
189
|
-
writeFileSync(join(INSTALL_DIR, 'docker-compose.yml'), composeData);
|
|
190
|
-
log(COLORS.green, '✅ docker-compose.yml téléchargé');
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Télécharger docker-compose.exporters.yml
|
|
194
|
-
const exportersData = runCommand(`curl -sL ${exportersUrl}`);
|
|
195
|
-
if (exportersData) {
|
|
196
|
-
writeFileSync(join(INSTALL_DIR, 'docker-compose.exporters.yml'), exportersData);
|
|
197
|
-
log(COLORS.green, '✅ docker-compose.exporters.yml téléchargé');
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Télécharger .env.example
|
|
201
|
-
const envExampleData = runCommand(`curl -sL ${envExampleUrl}`);
|
|
202
|
-
if (envExampleData) {
|
|
203
|
-
writeFileSync(join(INSTALL_DIR, '.env.example'), envExampleData);
|
|
204
|
-
log(COLORS.green, '✅ .env.example téléchargé');
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Télécharger .mcp.json.example
|
|
208
|
-
const mcpExampleData = runCommand(`curl -sL ${mcpExampleUrl}`);
|
|
209
|
-
if (mcpExampleData) {
|
|
210
|
-
writeFileSync(join(INSTALL_DIR, '.mcp.json.example'), mcpExampleData);
|
|
211
|
-
log(COLORS.green, '✅ .mcp.json.example téléchargé');
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return true;
|
|
215
|
-
} catch (error) {
|
|
216
|
-
log(COLORS.red, '❌ Erreur téléchargement: ' + error.message);
|
|
217
|
-
return false;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
function createEnvConfig() {
|
|
222
|
-
logSection('CRÉATION CONFIGURATION');
|
|
223
|
-
|
|
224
|
-
mkdirSync(INSTALL_DIR, { recursive: true });
|
|
225
|
-
|
|
226
|
-
const envFile = join(INSTALL_DIR, '.env');
|
|
227
|
-
const envExampleFile = join(INSTALL_DIR, '.env.example');
|
|
228
|
-
const mcpFile = join(INSTALL_DIR, '.mcp.json');
|
|
229
|
-
const mcpExampleFile = join(INSTALL_DIR, '.mcp.json.example');
|
|
230
|
-
|
|
231
|
-
// Copier .env.example → .env si existe
|
|
232
|
-
if (existsSync(envExampleFile) && !existsSync(envFile)) {
|
|
233
|
-
let envContent;
|
|
234
|
-
|
|
235
|
-
if (process.platform === 'win32') {
|
|
236
|
-
envContent = runCommand(`type "${envExampleFile}"`, { stdio: 'pipe' });
|
|
237
|
-
} else {
|
|
238
|
-
envContent = runCommand(`cat "${envExampleFile}"`, { stdio: 'pipe' });
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (envContent) {
|
|
242
|
-
writeFileSync(envFile, envContent);
|
|
243
|
-
log(COLORS.green, '✅ .env créé (à partir de .env.example)');
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// Créer .env minimal si n'existe pas
|
|
248
|
-
if (!existsSync(envFile)) {
|
|
249
|
-
const envContent = `# OverMind-MCP Environment Configuration
|
|
250
|
-
# Généré automatiquement par npm install
|
|
251
|
-
|
|
252
|
-
# PostgreSQL
|
|
253
|
-
POSTGRES_HOST=localhost
|
|
254
|
-
POSTGRES_PORT=5432
|
|
255
|
-
POSTGRES_USER=postgres
|
|
256
|
-
POSTGRES_PASSWORD=overmind_temp_password_change_me
|
|
257
|
-
POSTGRES_DB=overmind
|
|
258
|
-
|
|
259
|
-
# OpenTelemetry (optionnel)
|
|
260
|
-
OTEL_ENABLED=false
|
|
261
|
-
|
|
262
|
-
# Workspace
|
|
263
|
-
OVERMIND_WORKSPACE=${INSTALL_DIR}
|
|
264
|
-
`;
|
|
265
|
-
writeFileSync(envFile, envContent);
|
|
266
|
-
log(COLORS.green, '✅ Configuration .env créée: ' + envFile);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// Copier .mcp.json.example → .mcp.json si existe
|
|
270
|
-
if (existsSync(mcpExampleFile) && !existsSync(mcpFile)) {
|
|
271
|
-
let mcpContent;
|
|
272
|
-
|
|
273
|
-
if (process.platform === 'win32') {
|
|
274
|
-
mcpContent = runCommand(`type "${mcpExampleFile}"`, { stdio: 'pipe' });
|
|
275
|
-
} else {
|
|
276
|
-
mcpContent = runCommand(`cat "${mcpExampleFile}"`, { stdio: 'pipe' });
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (mcpContent) {
|
|
280
|
-
writeFileSync(mcpFile, mcpContent);
|
|
281
|
-
log(COLORS.green, '✅ .mcp.json créé (à partir de .mcp.json.example)');
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
async function startInfrastructure() {
|
|
287
|
-
logSection('DÉMARRAGE AUTOMATIQUE INFRASTRUCTURE COMPLÈTE');
|
|
288
|
-
|
|
289
|
-
const composeFile = join(INSTALL_DIR, 'docker-compose.yml');
|
|
290
|
-
|
|
291
|
-
if (!existsSync(composeFile)) {
|
|
292
|
-
log(COLORS.yellow, '⚠️ docker-compose.yml non trouvé. Téléchargement...');
|
|
293
|
-
const downloaded = await setupInfrastructure();
|
|
294
|
-
if (!downloaded) {
|
|
295
|
-
return false;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
try {
|
|
300
|
-
log(COLORS.yellow, '🚀 Démarrage automatique de TOUS les services...');
|
|
301
|
-
log(COLORS.cyan, ' (PostgreSQL, RabbitMQ, Temporal, Prometheus, Grafana, Jaeger, Redis)');
|
|
302
|
-
|
|
303
|
-
await runCommandAsync(
|
|
304
|
-
`cd "${INSTALL_DIR}" && docker-compose -f docker-compose.yml pull`,
|
|
305
|
-
'Téléchargement images Docker'
|
|
306
|
-
);
|
|
307
|
-
|
|
308
|
-
await runCommandAsync(
|
|
309
|
-
`cd "${INSTALL_DIR}" && docker-compose -f docker-compose.yml up -d`,
|
|
310
|
-
'Démarrage infrastructure complète'
|
|
311
|
-
);
|
|
312
|
-
|
|
313
|
-
log(COLORS.cyan, '\n⏳ Attente démarrage des services (20s)...');
|
|
314
|
-
await new Promise(resolve => setTimeout(resolve, 20000));
|
|
315
|
-
|
|
316
|
-
return true;
|
|
317
|
-
} catch (error) {
|
|
318
|
-
log(COLORS.red, '\n⚠️ Erreur démarrage infrastructure: ' + error.message);
|
|
319
|
-
log(COLORS.yellow, '\n💡 Solution manuelle:');
|
|
320
|
-
log(COLORS.white, ' cd ~/.overmind');
|
|
321
|
-
log(COLORS.white, ' docker-compose up -d');
|
|
322
|
-
return false;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
async function validateServices() {
|
|
327
|
-
logSection('VALIDATION DES SERVICES');
|
|
328
|
-
|
|
329
|
-
log(COLORS.yellow, '🔍 Vérification des containers Docker...\n');
|
|
330
|
-
|
|
331
|
-
const services = [
|
|
332
|
-
{ name: 'PostgreSQL + pgvector', filter: 'postgres', color: COLORS.green },
|
|
333
|
-
{ name: 'RabbitMQ', filter: 'rabbitmq', color: COLORS.green },
|
|
334
|
-
{ name: 'Temporal', filter: 'temporal', color: COLORS.green },
|
|
335
|
-
{ name: 'Prometheus', filter: 'prometheus', color: COLORS.green },
|
|
336
|
-
{ name: 'Grafana', filter: 'grafana', color: COLORS.green },
|
|
337
|
-
{ name: 'Jaeger', filter: 'jaeger', color: COLORS.green },
|
|
338
|
-
{ name: 'Redis', filter: 'redis', color: COLORS.green },
|
|
339
|
-
];
|
|
340
|
-
|
|
341
|
-
let allRunning = true;
|
|
342
|
-
|
|
343
|
-
for (const service of services) {
|
|
344
|
-
const containerName = runCommand(
|
|
345
|
-
`docker ps --filter "name=${service.filter}" --format "{{.Names}}"`,
|
|
346
|
-
{ stdio: 'pipe' }
|
|
347
|
-
);
|
|
348
|
-
|
|
349
|
-
if (containerName) {
|
|
350
|
-
log(service.color, ` ✅ ${service.name}: ${containerName.trim()}`);
|
|
351
|
-
} else {
|
|
352
|
-
log(COLORS.red, ` ❌ ${service.name}: Non trouvé`);
|
|
353
|
-
allRunning = false;
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
return allRunning;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
function showSummary() {
|
|
361
|
-
console.log('\n╔══════════════════════════════════════════════════════════════════╗');
|
|
362
|
-
console.log('║' + ' '.repeat(64) + '║');
|
|
363
|
-
console.log('║' + COLORS.green + ' ✅ INSTALLATION TERMINÉE !' + COLORS.reset + ' '.repeat(33) + '║');
|
|
364
|
-
console.log('║' + ' '.repeat(64) + '║');
|
|
365
|
-
console.log('╚══════════════════════════════════════════════════════════════════╝');
|
|
366
|
-
console.log('');
|
|
367
|
-
log(COLORS.yellow, '📋 SERVICES ACTIFS DANS DOCKER DESKTOP:');
|
|
368
|
-
console.log('');
|
|
369
|
-
console.log('┌─────────────────────────────────────────────────────────────────┐');
|
|
370
|
-
console.log('│ ' + COLORS.cyan + 'Ouvrez Docker Desktop → onglet "Containers"' + COLORS.reset + ' │');
|
|
371
|
-
console.log('│ ' + COLORS.cyan + 'Vous verrez tous les services OverMind actifs:' + COLORS.reset + ' │');
|
|
372
|
-
console.log('│ ' + COLORS.green + ' • PostgreSQL + pgvector' + COLORS.reset + ' │');
|
|
373
|
-
console.log('│ ' + COLORS.green + ' • RabbitMQ (Message Broker)' + COLORS.reset + ' │');
|
|
374
|
-
console.log('│ ' + COLORS.green + ' • Temporal (Workflow Engine)' + COLORS.reset + ' │');
|
|
375
|
-
console.log('│ ' + COLORS.green + ' • Prometheus (Métriques)' + COLORS.reset + ' │');
|
|
376
|
-
console.log('│ ' + COLORS.green + ' • Grafana (Dashboards)' + COLORS.reset + ' │');
|
|
377
|
-
console.log('│ ' + COLORS.green + ' • Jaeger (Tracing)' + COLORS.reset + ' │');
|
|
378
|
-
console.log('│ ' + COLORS.green + ' • Redis (Cache)' + COLORS.reset + ' │');
|
|
379
|
-
console.log('│ │');
|
|
380
|
-
console.log('│ ' + COLORS.yellow + 'URLs utiles:' + COLORS.reset + ' │');
|
|
381
|
-
console.log('│ • Prometheus: ' + COLORS.cyan + 'http://localhost:9090' + COLORS.reset + ' │');
|
|
382
|
-
console.log('│ • Grafana: ' + COLORS.cyan + 'http://localhost:3000' + COLORS.reset + ' (admin/admin)' + ' │');
|
|
383
|
-
console.log('│ • Jaeger: ' + COLORS.cyan + 'http://localhost:16686' + COLORS.reset + ' │');
|
|
384
|
-
console.log('│ • RabbitMQ: ' + COLORS.cyan + 'http://localhost:15672' + COLORS.reset + ' (guest/guest)' + ' │');
|
|
385
|
-
console.log('│ • Temporal: ' + COLORS.cyan + 'http://localhost:8233' + COLORS.reset + ' │');
|
|
386
|
-
console.log('└─────────────────────────────────────────────────────────────────┘');
|
|
387
|
-
console.log('');
|
|
388
|
-
log(COLORS.yellow, '📚 DOCUMENTATION:');
|
|
389
|
-
console.log(' • https://github.com/DeamonDev888/overmind-mcp');
|
|
390
|
-
console.log(' • https://www.npmjs.com/package/overmind-mcp');
|
|
391
|
-
console.log('');
|
|
392
|
-
log(COLORS.yellow, '🎉 PROCHAINE ÉTAPE:');
|
|
393
|
-
console.log(' • Créez votre premier agent: overmind create-agent');
|
|
394
|
-
console.log(' • Ou listez les agents: overmind list-agents');
|
|
395
|
-
console.log('');
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
// ═════════════════════════════════════════════════════════════════════════════
|
|
399
|
-
// MAIN
|
|
400
|
-
// ═════════════════════════════════════════════════════════════════════════════
|
|
401
|
-
|
|
402
|
-
async function main() {
|
|
403
|
-
console.log('╔══════════════════════════════════════════════════════════════════╗');
|
|
404
|
-
console.log('║' + ' '.repeat(64) + '║');
|
|
405
|
-
console.log('║' + COLORS.cyan + ' 🚀 OVERMIND-MCP - INSTALLATION AUTOMATIQUE' + COLORS.reset + ' '.repeat(25) + '║');
|
|
406
|
-
console.log('║' + ' '.repeat(64) + '║');
|
|
407
|
-
console.log('╚══════════════════════════════════════════════════════════════════╝');
|
|
408
|
-
console.log('');
|
|
409
|
-
|
|
410
|
-
// Banner
|
|
411
|
-
console.log(COLORS.cyan + 'Ce script VA installer automatiquement:' + COLORS.reset);
|
|
412
|
-
console.log(' ✓ Vérifier Docker');
|
|
413
|
-
console.log(' ✓ Installer PostgreSQL + pgvector (si absent)');
|
|
414
|
-
console.log(' ✓ Télécharger docker-compose.yml et configs');
|
|
415
|
-
console.log(' ✓ Démarrer TOUS les services Docker automatiquement');
|
|
416
|
-
console.log(' ✓ Copier .env.example → .env');
|
|
417
|
-
console.log(' ✓ Copier .mcp.json.example → .mcp.json');
|
|
418
|
-
console.log(' ✓ Valider tous les services');
|
|
419
|
-
console.log(' ✓ Montrer où les voir dans Docker Desktop');
|
|
420
|
-
console.log('');
|
|
421
|
-
|
|
422
|
-
// Step 1: Check Docker
|
|
423
|
-
const dockerOk = await checkDocker();
|
|
424
|
-
if (!dockerOk) {
|
|
425
|
-
return;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// Step 2: Setup PostgreSQL
|
|
429
|
-
await setupPostgreSQL();
|
|
430
|
-
|
|
431
|
-
// Step 3: Setup .env et .mcp.json
|
|
432
|
-
createEnvConfig();
|
|
433
|
-
|
|
434
|
-
// Step 4: Download infrastructure files
|
|
435
|
-
const downloaded = await setupInfrastructure();
|
|
436
|
-
|
|
437
|
-
// Step 5: Start ALL services automatically
|
|
438
|
-
if (downloaded) {
|
|
439
|
-
const started = await startInfrastructure();
|
|
440
|
-
if (!started) {
|
|
441
|
-
log(COLORS.yellow, '\n⚠️ Infrastructure non démarrée automatiquement.');
|
|
442
|
-
log(COLORS.yellow, ' PostgreSQL fonctionne, mais les autres services ne sont pas actifs.');
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
// Step 6: Validate ALL services
|
|
447
|
-
if (downloaded) {
|
|
448
|
-
const allOk = await validateServices();
|
|
449
|
-
if (allOk) {
|
|
450
|
-
logSection('✅ TOUS LES SERVICES SONT ACTIFS');
|
|
451
|
-
log(COLORS.green, '🎉 Installation complète réussie !');
|
|
452
|
-
} else {
|
|
453
|
-
logSection('⚠️ CERTAINS SERVICES NON DÉMARRÉS');
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
// Show final summary
|
|
458
|
-
showSummary();
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
// Run main
|
|
462
|
-
main().catch((error) => {
|
|
463
|
-
console.error('\n❌ ERREUR FATALE:', error.message);
|
|
464
|
-
process.exit(1);
|
|
465
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
4
|
+
* OVERMIND-MCP - POST-INSTALL AUTOMATIQUE
|
|
5
|
+
* ═════════════════════════════════════════════════════════════════════════════
|
|
6
|
+
* Script exécuté automatiquement après npm install -g overmind-mcp
|
|
7
|
+
* INSTALLE ET DÉMARRE TOUT AUTOMATIQUEMENT :
|
|
8
|
+
* - Vérifie Docker
|
|
9
|
+
* - Installe PostgreSQL + pgvector (si absent)
|
|
10
|
+
* - Copie .env.example → .env
|
|
11
|
+
* - Copie .mcp.json.example → .mcp.json
|
|
12
|
+
* - Télécharge et démarre TOUTE l'infrastructure Docker
|
|
13
|
+
* - Valide tous les services
|
|
14
|
+
* - Montre où les voir dans Docker Desktop
|
|
15
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { execSync, spawn } from 'child_process';
|
|
19
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
|
|
20
|
+
import { join } from 'path';
|
|
21
|
+
import { fileURLToPath } from 'url';
|
|
22
|
+
import { dirname } from 'path';
|
|
23
|
+
|
|
24
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
25
|
+
const __dirname = dirname(__filename);
|
|
26
|
+
|
|
27
|
+
const INSTALL_DIR = join(
|
|
28
|
+
process.env.HOME || process.env.USERPROFILE || process.env.HOMEPATH,
|
|
29
|
+
'.overmind'
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
33
|
+
// COLORS
|
|
34
|
+
// ═════════════════════════════════════════════════════════════════════════════
|
|
35
|
+
|
|
36
|
+
const COLORS = {
|
|
37
|
+
cyan: '\x1b[36m',
|
|
38
|
+
green: '\x1b[32m',
|
|
39
|
+
yellow: '\x1b[33m',
|
|
40
|
+
red: '\x1b[31m',
|
|
41
|
+
white: '\x1b[37m',
|
|
42
|
+
reset: '\x1b[0m'
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
function log(color, str) {
|
|
46
|
+
console.log(`${color}${str}${COLORS.reset}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function logSection(title) {
|
|
50
|
+
console.log('\n╔══════════════════════════════════════════════════════════════════╗');
|
|
51
|
+
console.log(`║ ${title.padEnd(64)} ║`);
|
|
52
|
+
console.log('╚══════════════════════════════════════════════════════════════════╝');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function runCommand(cmd, options = {}) {
|
|
56
|
+
try {
|
|
57
|
+
return execSync(cmd, { stdio: 'pipe', encoding: 'utf8', ...options });
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function runCommandAsync(cmd, description) {
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
console.log(`🔧 ${description}`);
|
|
66
|
+
console.log(` $ ${cmd}`);
|
|
67
|
+
|
|
68
|
+
const child = spawn(cmd, { shell: true, stdio: 'inherit' });
|
|
69
|
+
|
|
70
|
+
child.on('close', (code) => {
|
|
71
|
+
if (code === 0) {
|
|
72
|
+
console.log(`✅ ${description} terminé`);
|
|
73
|
+
resolve(true);
|
|
74
|
+
} else {
|
|
75
|
+
console.error(`❌ Erreur (code ${code})`);
|
|
76
|
+
reject(new Error(`Command failed with code ${code}`));
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
child.on('error', (err) => {
|
|
81
|
+
console.error('❌ Erreur:', err.message);
|
|
82
|
+
reject(err);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
88
|
+
// INSTALLATION STEPS
|
|
89
|
+
// ═════════════════════════════════════════════════════════════════════════════
|
|
90
|
+
|
|
91
|
+
async function checkDocker() {
|
|
92
|
+
logSection('VÉRIFICATION DOCKER');
|
|
93
|
+
|
|
94
|
+
const version = runCommand('docker --version');
|
|
95
|
+
if (!version) {
|
|
96
|
+
log(COLORS.red, '❌ Docker non trouvé');
|
|
97
|
+
console.log('');
|
|
98
|
+
log(COLORS.yellow, '📥 Installation Docker requise:');
|
|
99
|
+
|
|
100
|
+
const platform = process.platform;
|
|
101
|
+
if (platform === 'win32') {
|
|
102
|
+
console.log(' Windows: https://www.docker.com/products/docker-desktop/');
|
|
103
|
+
} else if (platform === 'darwin') {
|
|
104
|
+
console.log(' macOS: https://www.docker.com/products/docker-desktop/');
|
|
105
|
+
} else {
|
|
106
|
+
console.log(' Linux: https://docs.docker.com/engine/install/');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
log(COLORS.cyan, '\nAprès installation de Docker, relancez: npm install -g overmind-mcp');
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
log(COLORS.green, '✅ Docker détecté: ' + version.trim());
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async function setupPostgreSQL() {
|
|
118
|
+
logSection('INSTALLATION POSTGRESQL + PGVECTOR');
|
|
119
|
+
|
|
120
|
+
// Check if already exists
|
|
121
|
+
const existingContainer = runCommand(
|
|
122
|
+
'docker ps --filter "name=postgres-pgvector" --format "{{.Names}}"',
|
|
123
|
+
{ stdio: 'pipe' }
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
if (existingContainer) {
|
|
127
|
+
log(COLORS.green, '✅ PostgreSQL + pgvector déjà installé');
|
|
128
|
+
log(COLORS.cyan, ' Container: ' + existingContainer.trim());
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
log(COLORS.yellow, '📦 Installation PostgreSQL + pgvector...');
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
await runCommandAsync(
|
|
136
|
+
'docker pull pgvector/pgvector:pg16',
|
|
137
|
+
'Téléchargement image'
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
// Remove existing if stopped
|
|
141
|
+
runCommand('docker rm -f overmind-postgres-pgvector', { stdio: 'pipe' });
|
|
142
|
+
|
|
143
|
+
const runCmd = [
|
|
144
|
+
'docker', 'run', '-d',
|
|
145
|
+
'--name', 'overmind-postgres-pgvector',
|
|
146
|
+
'-p', '5432:5432',
|
|
147
|
+
'-e', 'POSTGRES_PASSWORD=overmind_temp_password_change_me',
|
|
148
|
+
'-e', 'POSTGRES_USER=postgres',
|
|
149
|
+
'-v', 'overmind_postgres_data:/var/lib/postgresql/data',
|
|
150
|
+
'--restart', 'unless-stopped',
|
|
151
|
+
'pgvector/pgvector:pg16'
|
|
152
|
+
].join(' ');
|
|
153
|
+
|
|
154
|
+
await runCommandAsync(runCmd, 'Démarrage PostgreSQL');
|
|
155
|
+
|
|
156
|
+
log(COLORS.cyan, '\n⏳ Attente démarrage PostgreSQL (20s)...');
|
|
157
|
+
await new Promise(resolve => setTimeout(resolve, 20000));
|
|
158
|
+
|
|
159
|
+
// Enable pgvector
|
|
160
|
+
await runCommandAsync(
|
|
161
|
+
`docker exec overmind-postgres-pgvector psql -U postgres -c "CREATE EXTENSION IF NOT EXISTS vector;"`,
|
|
162
|
+
'Activation pgvector'
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
log(COLORS.green, '\n✅ PostgreSQL + pgvector installés !');
|
|
166
|
+
return true;
|
|
167
|
+
} catch (error) {
|
|
168
|
+
log(COLORS.red, '❌ Erreur installation PostgreSQL: ' + error.message);
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async function setupInfrastructure() {
|
|
174
|
+
logSection('TÉLÉCHARGEMENT INFRASTRUCTURE');
|
|
175
|
+
|
|
176
|
+
mkdirSync(INSTALL_DIR, { recursive: true });
|
|
177
|
+
|
|
178
|
+
log(COLORS.yellow, '📥 Téléchargement fichiers docker-compose...');
|
|
179
|
+
|
|
180
|
+
const composeUrl = 'https://raw.githubusercontent.com/DeamonDev888/overmind-mcp/main/docker-compose.yml';
|
|
181
|
+
const exportersUrl = 'https://raw.githubusercontent.com/DeamonDev888/overmind-mcp/main/docker-compose.exporters.yml';
|
|
182
|
+
const envExampleUrl = 'https://raw.githubusercontent.com/DeamonDev888/overmind-mcp/main/.env.example';
|
|
183
|
+
const mcpExampleUrl = 'https://raw.githubusercontent.com/DeamonDev888/overmind-mcp/main/.mcp.json.example';
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
// Télécharger docker-compose.yml
|
|
187
|
+
const composeData = runCommand(`curl -sL ${composeUrl}`);
|
|
188
|
+
if (composeData) {
|
|
189
|
+
writeFileSync(join(INSTALL_DIR, 'docker-compose.yml'), composeData);
|
|
190
|
+
log(COLORS.green, '✅ docker-compose.yml téléchargé');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Télécharger docker-compose.exporters.yml
|
|
194
|
+
const exportersData = runCommand(`curl -sL ${exportersUrl}`);
|
|
195
|
+
if (exportersData) {
|
|
196
|
+
writeFileSync(join(INSTALL_DIR, 'docker-compose.exporters.yml'), exportersData);
|
|
197
|
+
log(COLORS.green, '✅ docker-compose.exporters.yml téléchargé');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Télécharger .env.example
|
|
201
|
+
const envExampleData = runCommand(`curl -sL ${envExampleUrl}`);
|
|
202
|
+
if (envExampleData) {
|
|
203
|
+
writeFileSync(join(INSTALL_DIR, '.env.example'), envExampleData);
|
|
204
|
+
log(COLORS.green, '✅ .env.example téléchargé');
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Télécharger .mcp.json.example
|
|
208
|
+
const mcpExampleData = runCommand(`curl -sL ${mcpExampleUrl}`);
|
|
209
|
+
if (mcpExampleData) {
|
|
210
|
+
writeFileSync(join(INSTALL_DIR, '.mcp.json.example'), mcpExampleData);
|
|
211
|
+
log(COLORS.green, '✅ .mcp.json.example téléchargé');
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return true;
|
|
215
|
+
} catch (error) {
|
|
216
|
+
log(COLORS.red, '❌ Erreur téléchargement: ' + error.message);
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function createEnvConfig() {
|
|
222
|
+
logSection('CRÉATION CONFIGURATION');
|
|
223
|
+
|
|
224
|
+
mkdirSync(INSTALL_DIR, { recursive: true });
|
|
225
|
+
|
|
226
|
+
const envFile = join(INSTALL_DIR, '.env');
|
|
227
|
+
const envExampleFile = join(INSTALL_DIR, '.env.example');
|
|
228
|
+
const mcpFile = join(INSTALL_DIR, '.mcp.json');
|
|
229
|
+
const mcpExampleFile = join(INSTALL_DIR, '.mcp.json.example');
|
|
230
|
+
|
|
231
|
+
// Copier .env.example → .env si existe
|
|
232
|
+
if (existsSync(envExampleFile) && !existsSync(envFile)) {
|
|
233
|
+
let envContent;
|
|
234
|
+
|
|
235
|
+
if (process.platform === 'win32') {
|
|
236
|
+
envContent = runCommand(`type "${envExampleFile}"`, { stdio: 'pipe' });
|
|
237
|
+
} else {
|
|
238
|
+
envContent = runCommand(`cat "${envExampleFile}"`, { stdio: 'pipe' });
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (envContent) {
|
|
242
|
+
writeFileSync(envFile, envContent);
|
|
243
|
+
log(COLORS.green, '✅ .env créé (à partir de .env.example)');
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Créer .env minimal si n'existe pas
|
|
248
|
+
if (!existsSync(envFile)) {
|
|
249
|
+
const envContent = `# OverMind-MCP Environment Configuration
|
|
250
|
+
# Généré automatiquement par npm install
|
|
251
|
+
|
|
252
|
+
# PostgreSQL
|
|
253
|
+
POSTGRES_HOST=localhost
|
|
254
|
+
POSTGRES_PORT=5432
|
|
255
|
+
POSTGRES_USER=postgres
|
|
256
|
+
POSTGRES_PASSWORD=overmind_temp_password_change_me
|
|
257
|
+
POSTGRES_DB=overmind
|
|
258
|
+
|
|
259
|
+
# OpenTelemetry (optionnel)
|
|
260
|
+
OTEL_ENABLED=false
|
|
261
|
+
|
|
262
|
+
# Workspace
|
|
263
|
+
OVERMIND_WORKSPACE=${INSTALL_DIR}
|
|
264
|
+
`;
|
|
265
|
+
writeFileSync(envFile, envContent);
|
|
266
|
+
log(COLORS.green, '✅ Configuration .env créée: ' + envFile);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Copier .mcp.json.example → .mcp.json si existe
|
|
270
|
+
if (existsSync(mcpExampleFile) && !existsSync(mcpFile)) {
|
|
271
|
+
let mcpContent;
|
|
272
|
+
|
|
273
|
+
if (process.platform === 'win32') {
|
|
274
|
+
mcpContent = runCommand(`type "${mcpExampleFile}"`, { stdio: 'pipe' });
|
|
275
|
+
} else {
|
|
276
|
+
mcpContent = runCommand(`cat "${mcpExampleFile}"`, { stdio: 'pipe' });
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (mcpContent) {
|
|
280
|
+
writeFileSync(mcpFile, mcpContent);
|
|
281
|
+
log(COLORS.green, '✅ .mcp.json créé (à partir de .mcp.json.example)');
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
async function startInfrastructure() {
|
|
287
|
+
logSection('DÉMARRAGE AUTOMATIQUE INFRASTRUCTURE COMPLÈTE');
|
|
288
|
+
|
|
289
|
+
const composeFile = join(INSTALL_DIR, 'docker-compose.yml');
|
|
290
|
+
|
|
291
|
+
if (!existsSync(composeFile)) {
|
|
292
|
+
log(COLORS.yellow, '⚠️ docker-compose.yml non trouvé. Téléchargement...');
|
|
293
|
+
const downloaded = await setupInfrastructure();
|
|
294
|
+
if (!downloaded) {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
try {
|
|
300
|
+
log(COLORS.yellow, '🚀 Démarrage automatique de TOUS les services...');
|
|
301
|
+
log(COLORS.cyan, ' (PostgreSQL, RabbitMQ, Temporal, Prometheus, Grafana, Jaeger, Redis)');
|
|
302
|
+
|
|
303
|
+
await runCommandAsync(
|
|
304
|
+
`cd "${INSTALL_DIR}" && docker-compose -f docker-compose.yml pull`,
|
|
305
|
+
'Téléchargement images Docker'
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
await runCommandAsync(
|
|
309
|
+
`cd "${INSTALL_DIR}" && docker-compose -f docker-compose.yml up -d`,
|
|
310
|
+
'Démarrage infrastructure complète'
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
log(COLORS.cyan, '\n⏳ Attente démarrage des services (20s)...');
|
|
314
|
+
await new Promise(resolve => setTimeout(resolve, 20000));
|
|
315
|
+
|
|
316
|
+
return true;
|
|
317
|
+
} catch (error) {
|
|
318
|
+
log(COLORS.red, '\n⚠️ Erreur démarrage infrastructure: ' + error.message);
|
|
319
|
+
log(COLORS.yellow, '\n💡 Solution manuelle:');
|
|
320
|
+
log(COLORS.white, ' cd ~/.overmind');
|
|
321
|
+
log(COLORS.white, ' docker-compose up -d');
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
async function validateServices() {
|
|
327
|
+
logSection('VALIDATION DES SERVICES');
|
|
328
|
+
|
|
329
|
+
log(COLORS.yellow, '🔍 Vérification des containers Docker...\n');
|
|
330
|
+
|
|
331
|
+
const services = [
|
|
332
|
+
{ name: 'PostgreSQL + pgvector', filter: 'postgres', color: COLORS.green },
|
|
333
|
+
{ name: 'RabbitMQ', filter: 'rabbitmq', color: COLORS.green },
|
|
334
|
+
{ name: 'Temporal', filter: 'temporal', color: COLORS.green },
|
|
335
|
+
{ name: 'Prometheus', filter: 'prometheus', color: COLORS.green },
|
|
336
|
+
{ name: 'Grafana', filter: 'grafana', color: COLORS.green },
|
|
337
|
+
{ name: 'Jaeger', filter: 'jaeger', color: COLORS.green },
|
|
338
|
+
{ name: 'Redis', filter: 'redis', color: COLORS.green },
|
|
339
|
+
];
|
|
340
|
+
|
|
341
|
+
let allRunning = true;
|
|
342
|
+
|
|
343
|
+
for (const service of services) {
|
|
344
|
+
const containerName = runCommand(
|
|
345
|
+
`docker ps --filter "name=${service.filter}" --format "{{.Names}}"`,
|
|
346
|
+
{ stdio: 'pipe' }
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
if (containerName) {
|
|
350
|
+
log(service.color, ` ✅ ${service.name}: ${containerName.trim()}`);
|
|
351
|
+
} else {
|
|
352
|
+
log(COLORS.red, ` ❌ ${service.name}: Non trouvé`);
|
|
353
|
+
allRunning = false;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return allRunning;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function showSummary() {
|
|
361
|
+
console.log('\n╔══════════════════════════════════════════════════════════════════╗');
|
|
362
|
+
console.log('║' + ' '.repeat(64) + '║');
|
|
363
|
+
console.log('║' + COLORS.green + ' ✅ INSTALLATION TERMINÉE !' + COLORS.reset + ' '.repeat(33) + '║');
|
|
364
|
+
console.log('║' + ' '.repeat(64) + '║');
|
|
365
|
+
console.log('╚══════════════════════════════════════════════════════════════════╝');
|
|
366
|
+
console.log('');
|
|
367
|
+
log(COLORS.yellow, '📋 SERVICES ACTIFS DANS DOCKER DESKTOP:');
|
|
368
|
+
console.log('');
|
|
369
|
+
console.log('┌─────────────────────────────────────────────────────────────────┐');
|
|
370
|
+
console.log('│ ' + COLORS.cyan + 'Ouvrez Docker Desktop → onglet "Containers"' + COLORS.reset + ' │');
|
|
371
|
+
console.log('│ ' + COLORS.cyan + 'Vous verrez tous les services OverMind actifs:' + COLORS.reset + ' │');
|
|
372
|
+
console.log('│ ' + COLORS.green + ' • PostgreSQL + pgvector' + COLORS.reset + ' │');
|
|
373
|
+
console.log('│ ' + COLORS.green + ' • RabbitMQ (Message Broker)' + COLORS.reset + ' │');
|
|
374
|
+
console.log('│ ' + COLORS.green + ' • Temporal (Workflow Engine)' + COLORS.reset + ' │');
|
|
375
|
+
console.log('│ ' + COLORS.green + ' • Prometheus (Métriques)' + COLORS.reset + ' │');
|
|
376
|
+
console.log('│ ' + COLORS.green + ' • Grafana (Dashboards)' + COLORS.reset + ' │');
|
|
377
|
+
console.log('│ ' + COLORS.green + ' • Jaeger (Tracing)' + COLORS.reset + ' │');
|
|
378
|
+
console.log('│ ' + COLORS.green + ' • Redis (Cache)' + COLORS.reset + ' │');
|
|
379
|
+
console.log('│ │');
|
|
380
|
+
console.log('│ ' + COLORS.yellow + 'URLs utiles:' + COLORS.reset + ' │');
|
|
381
|
+
console.log('│ • Prometheus: ' + COLORS.cyan + 'http://localhost:9090' + COLORS.reset + ' │');
|
|
382
|
+
console.log('│ • Grafana: ' + COLORS.cyan + 'http://localhost:3000' + COLORS.reset + ' (admin/admin)' + ' │');
|
|
383
|
+
console.log('│ • Jaeger: ' + COLORS.cyan + 'http://localhost:16686' + COLORS.reset + ' │');
|
|
384
|
+
console.log('│ • RabbitMQ: ' + COLORS.cyan + 'http://localhost:15672' + COLORS.reset + ' (guest/guest)' + ' │');
|
|
385
|
+
console.log('│ • Temporal: ' + COLORS.cyan + 'http://localhost:8233' + COLORS.reset + ' │');
|
|
386
|
+
console.log('└─────────────────────────────────────────────────────────────────┘');
|
|
387
|
+
console.log('');
|
|
388
|
+
log(COLORS.yellow, '📚 DOCUMENTATION:');
|
|
389
|
+
console.log(' • https://github.com/DeamonDev888/overmind-mcp');
|
|
390
|
+
console.log(' • https://www.npmjs.com/package/overmind-mcp');
|
|
391
|
+
console.log('');
|
|
392
|
+
log(COLORS.yellow, '🎉 PROCHAINE ÉTAPE:');
|
|
393
|
+
console.log(' • Créez votre premier agent: overmind create-agent');
|
|
394
|
+
console.log(' • Ou listez les agents: overmind list-agents');
|
|
395
|
+
console.log('');
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// ═════════════════════════════════════════════════════════════════════════════
|
|
399
|
+
// MAIN
|
|
400
|
+
// ═════════════════════════════════════════════════════════════════════════════
|
|
401
|
+
|
|
402
|
+
async function main() {
|
|
403
|
+
console.log('╔══════════════════════════════════════════════════════════════════╗');
|
|
404
|
+
console.log('║' + ' '.repeat(64) + '║');
|
|
405
|
+
console.log('║' + COLORS.cyan + ' 🚀 OVERMIND-MCP - INSTALLATION AUTOMATIQUE' + COLORS.reset + ' '.repeat(25) + '║');
|
|
406
|
+
console.log('║' + ' '.repeat(64) + '║');
|
|
407
|
+
console.log('╚══════════════════════════════════════════════════════════════════╝');
|
|
408
|
+
console.log('');
|
|
409
|
+
|
|
410
|
+
// Banner
|
|
411
|
+
console.log(COLORS.cyan + 'Ce script VA installer automatiquement:' + COLORS.reset);
|
|
412
|
+
console.log(' ✓ Vérifier Docker');
|
|
413
|
+
console.log(' ✓ Installer PostgreSQL + pgvector (si absent)');
|
|
414
|
+
console.log(' ✓ Télécharger docker-compose.yml et configs');
|
|
415
|
+
console.log(' ✓ Démarrer TOUS les services Docker automatiquement');
|
|
416
|
+
console.log(' ✓ Copier .env.example → .env');
|
|
417
|
+
console.log(' ✓ Copier .mcp.json.example → .mcp.json');
|
|
418
|
+
console.log(' ✓ Valider tous les services');
|
|
419
|
+
console.log(' ✓ Montrer où les voir dans Docker Desktop');
|
|
420
|
+
console.log('');
|
|
421
|
+
|
|
422
|
+
// Step 1: Check Docker
|
|
423
|
+
const dockerOk = await checkDocker();
|
|
424
|
+
if (!dockerOk) {
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Step 2: Setup PostgreSQL
|
|
429
|
+
await setupPostgreSQL();
|
|
430
|
+
|
|
431
|
+
// Step 3: Setup .env et .mcp.json
|
|
432
|
+
createEnvConfig();
|
|
433
|
+
|
|
434
|
+
// Step 4: Download infrastructure files
|
|
435
|
+
const downloaded = await setupInfrastructure();
|
|
436
|
+
|
|
437
|
+
// Step 5: Start ALL services automatically
|
|
438
|
+
if (downloaded) {
|
|
439
|
+
const started = await startInfrastructure();
|
|
440
|
+
if (!started) {
|
|
441
|
+
log(COLORS.yellow, '\n⚠️ Infrastructure non démarrée automatiquement.');
|
|
442
|
+
log(COLORS.yellow, ' PostgreSQL fonctionne, mais les autres services ne sont pas actifs.');
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Step 6: Validate ALL services
|
|
447
|
+
if (downloaded) {
|
|
448
|
+
const allOk = await validateServices();
|
|
449
|
+
if (allOk) {
|
|
450
|
+
logSection('✅ TOUS LES SERVICES SONT ACTIFS');
|
|
451
|
+
log(COLORS.green, '🎉 Installation complète réussie !');
|
|
452
|
+
} else {
|
|
453
|
+
logSection('⚠️ CERTAINS SERVICES NON DÉMARRÉS');
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Show final summary
|
|
458
|
+
showSummary();
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// Run main
|
|
462
|
+
main().catch((error) => {
|
|
463
|
+
console.error('\n❌ ERREUR FATALE:', error.message);
|
|
464
|
+
process.exit(1);
|
|
465
|
+
});
|