overmind-mcp 2.0.5 → 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.
@@ -1,368 +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 configure TOUT :
8
- * - Vérifie Docker
9
- * - Installe PostgreSQL + pgvector (si absent)
10
- * - Télécharge et lance l'infrastructure Docker complète
11
- * - Valide tous les services
12
- * - Montre à l'utilisateur où voir les services dans Docker Desktop
13
- * ═══════════════════════════════════════════════════════════════════════════════
14
- */
15
-
16
- import { execSync, spawn } from 'child_process';
17
- import { existsSync, mkdirSync, writeFileSync } from 'fs';
18
- import { join } from 'path';
19
- import { fileURLToPath } from 'url';
20
- import { dirname } from 'path';
21
-
22
- const __filename = fileURLToPath(import.meta.url);
23
- const __dirname = dirname(__filename);
24
-
25
- const INSTALL_DIR = join(
26
- process.env.HOME || process.env.USERPROFILE || process.env.HOMEPATH,
27
- '.overmind'
28
- );
29
-
30
- // ═══════════════════════════════════════════════════════════════════════════════
31
- // CONFIG & COLORS
32
- // ═══════════════════════════════════════════════════════════════════════════════
33
-
34
- const COLORS = {
35
- cyan: '\x1b[36m',
36
- green: '\x1b[32m',
37
- yellow: '\x1b[33m',
38
- red: '\x1b[31m',
39
- white: '\x1b[37m',
40
- reset: '\x1b[0m'
41
- };
42
-
43
- function log(color, str) {
44
- console.log(`${color}${str}${COLORS.reset}`);
45
- }
46
-
47
- function logSection(title) {
48
- console.log('\n╔══════════════════════════════════════════════════════════════════╗');
49
- console.log(`║ ${title.padEnd(64)} ║`);
50
- console.log('╚══════════════════════════════════════════════════════════════════╝');
51
- }
52
-
53
- function runCommand(cmd, options = {}) {
54
- try {
55
- return execSync(cmd, { stdio: 'pipe', encoding: 'utf8', ...options });
56
- } catch {
57
- return null;
58
- }
59
- }
60
-
61
- async function runCommandAsync(cmd, description) {
62
- return new Promise((resolve, reject) => {
63
- console.log(`🔧 ${description}`);
64
- console.log(` $ ${cmd}`);
65
-
66
- const child = spawn(cmd, { shell: true, stdio: 'inherit' });
67
-
68
- child.on('close', (code) => {
69
- if (code === 0) {
70
- console.log(`✅ ${description} terminé`);
71
- resolve(true);
72
- } else {
73
- console.error(`❌ Erreur (code ${code})`);
74
- reject(new Error(`Command failed with code ${code}`));
75
- }
76
- });
77
-
78
- child.on('error', (err) => {
79
- console.error('❌ Erreur:', err.message);
80
- reject(err);
81
- });
82
- });
83
- }
84
-
85
- // ═══════════════════════════════════════════════════════════════════════════════
86
- // INSTALLATION STEPS
87
- // ═══════════════════════════════════════════════════════════════════════════════
88
-
89
- async function checkDocker() {
90
- logSection('VÉRIFICATION DOCKER');
91
-
92
- const version = runCommand('docker --version');
93
- if (!version) {
94
- log(COLORS.red, '❌ Docker non trouvé');
95
- console.log('');
96
- log(COLORS.yellow, '📥 Installation Docker requise:');
97
-
98
- const platform = process.platform;
99
- if (platform === 'win32') {
100
- console.log(' Windows: https://www.docker.com/products/docker-desktop/');
101
- } else if (platform === 'darwin') {
102
- console.log(' macOS: https://www.docker.com/products/docker-desktop/');
103
- } else {
104
- console.log(' Linux: https://docs.docker.com/engine/install/');
105
- }
106
-
107
- log(COLORS.cyan, '\n📥 Après installation de Docker, relancez: npm install -g overmind-mcp');
108
- return false;
109
- }
110
-
111
- log(COLORS.green, '✅ Docker détecté: ' + version.trim());
112
- return true;
113
- }
114
-
115
- async function setupPostgreSQL() {
116
- logSection('INSTALLATION POSTGRESQL + PGVECTOR');
117
-
118
- // Check if already exists
119
- const existingContainer = runCommand(
120
- 'docker ps --filter "name=postgres-pgvector" --format "{{.Names}}"',
121
- { stdio: 'pipe' }
122
- );
123
-
124
- if (existingContainer) {
125
- log(COLORS.green, '✅ PostgreSQL + pgvector déjà installé');
126
- log(COLORS.cyan, ' Container: ' + existingContainer.trim());
127
- return true;
128
- }
129
-
130
- log(COLORS.yellow, '📦 Installation PostgreSQL + pgvector...');
131
-
132
- try {
133
- await runCommandAsync(
134
- 'docker pull pgvector/pgvector:pg16',
135
- 'Téléchargement image'
136
- );
137
-
138
- // Remove existing if stopped
139
- runCommand('docker rm -f overmind-postgres-pgvector', { stdio: 'pipe' });
140
-
141
- const runCmd = [
142
- 'docker', 'run', '-d',
143
- '--name', 'overmind-postgres-pgvector',
144
- '-p', '5432:5432',
145
- '-e', 'POSTGRES_PASSWORD=overmind_temp_password_change_me',
146
- '-e', 'POSTGRES_USER=postgres',
147
- '-v', 'overmind_postgres_data:/var/lib/postgresql/data',
148
- '--restart', 'unless-stopped',
149
- 'pgvector/pgvector:pg16'
150
- ].join(' ');
151
-
152
- await runCommandAsync(runCmd, 'Démarrage PostgreSQL');
153
-
154
- log(COLORS.cyan, '\n⏳ Attente démarrage PostgreSQL (20s)...');
155
- await new Promise(resolve => setTimeout(resolve, 20000));
156
-
157
- // Enable pgvector
158
- await runCommandAsync(
159
- `docker exec overmind-postgres-pgvector psql -U postgres -c "CREATE EXTENSION IF NOT EXISTS vector;"`,
160
- 'Activation pgvector'
161
- );
162
-
163
- log(COLORS.green, '\n✅ PostgreSQL + pgvector installés !');
164
- return true;
165
- } catch (error) {
166
- log(COLORS.red, '❌ Erreur installation PostgreSQL: ' + error.message);
167
- return false;
168
- }
169
- }
170
-
171
- async function setupInfrastructure() {
172
- logSection('TÉLÉCHARGEMENT INFRASTRUCTURE DOCKER');
173
-
174
- mkdirSync(INSTALL_DIR, { recursive: true });
175
-
176
- log(COLORS.yellow, '📥 Téléchargement docker-compose.yml...');
177
-
178
- const composeUrl = 'https://raw.githubusercontent.com/DeamonDev888/overmind-mcp/main/docker-compose.yml';
179
- const exportersUrl = 'https://raw.githubusercontent.com/DeamonDev888/overmind-mcp/main/docker-compose.exporters.yml';
180
-
181
- try {
182
- const composeData = runCommand(`curl -sL ${composeUrl}`);
183
- if (composeData) {
184
- writeFileSync(join(INSTALL_DIR, 'docker-compose.yml'), composeData);
185
- log(COLORS.green, '✅ docker-compose.yml téléchargé');
186
- }
187
-
188
- const exportersData = runCommand(`curl -sL ${exportersUrl}`);
189
- if (exportersData) {
190
- writeFileSync(join(INSTALL_DIR, 'docker-compose.exporters.yml'), exportersData);
191
- log(COLORS.green, '✅ docker-compose.exporters.yml téléchargé');
192
- }
193
-
194
- return true;
195
- } catch (error) {
196
- log(COLORS.red, '❌ Erreur téléchargement: ' + error.message);
197
- return false;
198
- }
199
- }
200
-
201
- async function startInfrastructure() {
202
- logSection('DÉMARRAGE INFRASTRUCTURE');
203
-
204
- const composeFile = join(INSTALL_DIR, 'docker-compose.yml');
205
-
206
- if (!existsSync(composeFile)) {
207
- log(COLORS.yellow, '⚠️ docker-compose.yml non trouvé. Téléchargement...');
208
- return false;
209
- }
210
-
211
- log(COLORS.cyan, '💡 Infrastructure Docker téléchargée.');
212
- log(COLORS.yellow, '⚠️ Pour démarrer tous les services (RabbitMQ, Temporal, Prometheus, Grafana, Jaeger):');
213
- log(COLORS.white, ' → overmind-setup --full');
214
- log(COLORS.white, ' → Ou manuellement: cd ~/.overmind && docker-compose up -d');
215
- log(COLORS.white, ' ');
216
- log(COLORS.green, ' PostgreSQL + pgvector sont déjà prêts !');
217
-
218
- return true;
219
- }
220
-
221
- async function validateServices() {
222
- logSection('VALIDATION DES SERVICES');
223
-
224
- log(COLORS.yellow, '🔍 Vérification des containers...\n');
225
-
226
- const services = [
227
- { name: 'PostgreSQL + pgvector', filter: 'postgres', color: COLORS.green },
228
- { name: 'RabbitMQ', filter: 'rabbitmq', color: COLORS.green },
229
- { name: 'Temporal', filter: 'temporal', color: COLORS.green },
230
- { name: 'Prometheus', filter: 'prometheus', color: COLORS.green },
231
- { name: 'Grafana', filter: 'grafana', color: COLORS.green },
232
- { name: 'Jaeger', filter: 'jaeger', color: COLORS.green },
233
- ];
234
-
235
- let allRunning = true;
236
-
237
- for (const service of services) {
238
- const containerName = runCommand(
239
- `docker ps --filter "name=${service.filter}" --format "{{.Names}}"`,
240
- { stdio: 'pipe' }
241
- );
242
-
243
- if (containerName) {
244
- log(service.color, ` ✅ ${service.name}: ${containerName.trim()}`);
245
- } else {
246
- log(COLORS.red, ` ❌ ${service.name}: Non trouvé`);
247
- allRunning = false;
248
- }
249
- }
250
-
251
- return allRunning;
252
- }
253
-
254
- function createEnvConfig() {
255
- mkdirSync(INSTALL_DIR, { recursive: true });
256
-
257
- const envFile = join(INSTALL_DIR, '.env');
258
-
259
- if (!existsSync(envFile)) {
260
- const envContent = `# OverMind-MCP Environment Configuration
261
- # Généré automatiquement par npm install
262
-
263
- # PostgreSQL
264
- POSTGRES_HOST=localhost
265
- POSTGRES_PORT=5432
266
- POSTGRES_USER=postgres
267
- POSTGRES_PASSWORD=overmind_temp_password_change_me
268
- POSTGRES_DB=overmind
269
-
270
- # OpenTelemetry (optionnel)
271
- OTEL_ENABLED=false
272
-
273
- # Workspace
274
- OVERMIND_WORKSPACE=${INSTALL_DIR}
275
- `;
276
-
277
- writeFileSync(envFile, envContent);
278
- log(COLORS.green, '✅ Configuration créée: ' + envFile);
279
- }
280
- }
281
-
282
- function showSummary() {
283
- console.log('\n╔══════════════════════════════════════════════════════════════════╗');
284
- console.log('║' + ' '.repeat(64) + '║');
285
- console.log('║' + COLORS.green + ' ✅ INSTALLATION TERMINÉE !' + COLORS.reset + ' '.repeat(33) + '║');
286
- console.log('║' + ' '.repeat(64) + '║');
287
- console.log('╚══════════════════════════════════════════════════════════════════╝');
288
- console.log('');
289
- log(COLORS.yellow, '📋 SERVICES DISPONIBLES:');
290
- console.log('');
291
- console.log('┌─────────────────────────────────────────────────────────────────┐');
292
- console.log('│ ' + COLORS.cyan + 'Ouvrez Docker Desktop pour voir tous les containers' + COLORS.reset + ' │');
293
- console.log('│ │');
294
- console.log('│ ' + COLORS.yellow + 'URLs utiles:' + COLORS.reset + ' │');
295
- console.log('│ • Prometheus: ' + COLORS.cyan + 'http://localhost:9090' + COLORS.reset + ' │');
296
- console.log('│ • Grafana: ' + COLORS.cyan + 'http://localhost:3000' + COLORS.reset + ' (admin/admin)' + ' │');
297
- console.log('│ • Jaeger: ' + COLORS.cyan + 'http://localhost:16686' + COLORS.reset + ' │');
298
- console.log('│ • RabbitMQ: ' + COLORS.cyan + 'http://localhost:15672' + COLORS.reset + ' (guest/guest)' + ' │');
299
- console.log('│ • Temporal: ' + COLORS.cyan + 'http://localhost:8233' + COLORS.reset + ' │');
300
- console.log('└─────────────────────────────────────────────────────────────────┘');
301
- console.log('');
302
- log(COLORS.yellow, '📚 DOCUMENTATION:');
303
- console.log(' • https://github.com/DeamonDev888/overmind-mcp');
304
- console.log(' • https://www.npmjs.com/package/overmind-mcp');
305
- console.log('');
306
- log(COLORS.yellow, '🎉 PROCHAINE ÉTAPE:');
307
- console.log(' • Créez votre premier agent: overmind create-agent');
308
- console.log(' • Ou listez les agents: overmind list-agents');
309
- console.log('');
310
- }
311
-
312
- // ═══════════════════════════════════════════════════════════════════════════════
313
- // MAIN
314
- // ═══════════════════════════════════════════════════════════════════════════════
315
-
316
- async function main() {
317
- console.log('╔══════════════════════════════════════════════════════════════════╗');
318
- console.log('║' + ' '.repeat(64) + '║');
319
- console.log('║' + COLORS.cyan + ' 🚀 OVERMIND-MCP - INSTALLATION AUTOMATIQUE' + COLORS.reset + ' '.repeat(25) + '║');
320
- console.log('║' + ' '.repeat(64) + '║');
321
- console.log('╚══════════════════════════════════════════════════════════════════╝');
322
- console.log('');
323
-
324
- // Banner
325
- console.log(COLORS.cyan + 'Ce script va:' + COLORS.reset);
326
- console.log(' ✓ Vérifier Docker');
327
- console.log(' Installer PostgreSQL + pgvector (si absent)');
328
- console.log(' ✓ Télécharger l\'infrastructure Docker');
329
- console.log(' Démarrer tous les services');
330
- console.log(' ✓ Valider l\'installation');
331
- console.log('');
332
-
333
- // Step 1: Check Docker
334
- const dockerOk = await checkDocker();
335
- if (!dockerOk) {
336
- return;
337
- }
338
-
339
- // Step 2: Setup .env
340
- createEnvConfig();
341
-
342
- // Step 3: Install PostgreSQL if needed
343
- await setupPostgreSQL();
344
-
345
- // Step 4: Download infrastructure files
346
- await setupInfrastructure();
347
-
348
- // Step 5: Show how to start full infrastructure
349
- await startInfrastructure();
350
-
351
- // Step 6: Show PostgreSQL is ready
352
- logSection('POSTGRESQL PRÊT');
353
- log(COLORS.green, '✅ PostgreSQL + pgvector sont installés et prêts !');
354
- log(COLORS.cyan, '');
355
- log(COLORS.yellow, '🚀 Pour activer toutes les features (Swarm, Workflows, Observabilité):');
356
- log(COLORS.white, ' Option 1: overmind-setup --full');
357
- log(COLORS.white, ' Option 2: cd ~/.overmind && docker-compose up -d');
358
- log(COLORS.white, '');
359
-
360
- // Show summary
361
- showSummary();
362
- }
363
-
364
- // Run main
365
- main().catch((error) => {
366
- console.error('\n❌ ERREUR FATALE:', error.message);
367
- process.exit(1);
368
- });
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
+ });