overmind-mcp 2.0.2 → 2.0.4

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.
@@ -0,0 +1,327 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ═══════════════════════════════════════════════════════════════════════════════
4
+ * OVERMIND-MCP - INSTALLATION AUTOMATIQUE (POST-INSTALL)
5
+ * ═══════════════════════════════════════════════════════════════════════════════
6
+ * Ce script est exécuté automatiquement après npm install -g
7
+ * Il installe et configure TOUT :
8
+ * - Docker Desktop (vérification)
9
+ * - PostgreSQL + pgvector (si absent)
10
+ * - Infrastructure complète
11
+ * - Invite l'utilisateur à voir les services dans Docker Desktop
12
+ * ═══════════════════════════════════════════════════════════════════════════════
13
+ */
14
+
15
+ import { execSync, spawn } from 'child_process';
16
+ import { existsSync, mkdirSync, writeFileSync } from 'fs';
17
+ import { join } from 'path';
18
+ import { fileURLToPath } from 'url';
19
+ import { dirname } from 'path';
20
+ import { createInterface } from 'readline';
21
+
22
+ const __filename = fileURLToPath(import.meta.url);
23
+ const __dirname = dirname(__filename);
24
+
25
+ // ═══════════════════════════════════════════════════════════════════════════════
26
+ // CONFIG
27
+ // ═══════════════════════════════════════════════════════════════════════════════
28
+
29
+ const INSTALL_DIR = join(
30
+ process.env.HOME || process.env.USERPROFILE || process.env.HOMEPATH,
31
+ '.overmind'
32
+ );
33
+
34
+ // ═══════════════════════════════════════════════════════════════════════════════
35
+ // UTILS
36
+ // ═══════════════════════════════════════════════════════════════════════════════
37
+
38
+ function logSection(title) {
39
+ console.log('\n╔══════════════════════════════════════════════════════════════════╗');
40
+ console.log(`║ ${title.padEnd(64)} ║`);
41
+ console.log('╚══════════════════════════════════════════════════════════════════╝');
42
+ }
43
+
44
+ function runCommand(cmd, options = {}) {
45
+ try {
46
+ return execSync(cmd, { stdio: 'pipe', encoding: 'utf8', ...options });
47
+ } catch {
48
+ return null;
49
+ }
50
+ }
51
+
52
+ async function promptYesNo(question) {
53
+ const rl = createInterface({
54
+ input: process.stdin,
55
+ output: process.stdout,
56
+ });
57
+
58
+ return new Promise((resolve) => {
59
+ rl.question(`${question} (y/N): `, (answer) => {
60
+ rl.close();
61
+ resolve(answer.toLowerCase().startsWith('y'));
62
+ });
63
+ });
64
+ }
65
+
66
+ async function runCommandAsync(cmd, description) {
67
+ return new Promise((resolve, reject) => {
68
+ console.log(`🔧 ${description}`);
69
+ console.log(` $ ${cmd}`);
70
+
71
+ const child = spawn(cmd, { shell: true, stdio: 'inherit' });
72
+
73
+ child.on('close', (code) => {
74
+ if (code === 0) {
75
+ console.log(`✅ ${description} terminé`);
76
+ resolve(true);
77
+ } else {
78
+ console.error(`❌ Erreur (code ${code})`);
79
+ reject(new Error(`Command failed with code ${code}`));
80
+ }
81
+ });
82
+
83
+ child.on('error', (err) => {
84
+ console.error('❌ Erreur:', err.message);
85
+ reject(err);
86
+ });
87
+ });
88
+ }
89
+
90
+ // ═══════════════════════════════════════════════════════════════════════════════
91
+ // INSTALLATION STEPS
92
+ // ═══════════════════════════════════════════════════════════════════════════════
93
+
94
+ async function checkDocker() {
95
+ logSection('VÉRIFICATION DOCKER');
96
+
97
+ const version = runCommand('docker --version');
98
+ if (!version) {
99
+ console.log('❌ Docker non trouvé');
100
+ console.log('');
101
+ console.log('📥 Installation Docker requise:');
102
+
103
+ const platform = process.platform;
104
+ if (platform === 'win32') {
105
+ console.log(' Windows: https://www.docker.com/products/docker-desktop/');
106
+ } else if (platform === 'darwin') {
107
+ console.log(' macOS: https://www.docker.com/products/docker-desktop/');
108
+ } else {
109
+ console.log(' Linux: https://docs.docker.com/engine/install/');
110
+ }
111
+
112
+ const answer = await promptYesNo('Voulez-vous ouvrir le site de téléchargement ?');
113
+ if (answer) {
114
+ const url = 'https://www.docker.com/products/docker-desktop/';
115
+ const openCmd = process.platform === 'win32' ? 'start' :
116
+ process.platform === 'darwin' ? 'open' : 'xdg-open';
117
+ runCommand(`${openCmd} ${url}`, { stdio: 'ignore' });
118
+ console.log('✅ Navigateur ouvert. Installez Docker, puis relancez: npm install -g overmind-mcp');
119
+ }
120
+
121
+ return false;
122
+ }
123
+
124
+ console.log('✅ Docker détecté:', version.trim());
125
+ return true;
126
+ }
127
+
128
+ async function setupInfrastructure() {
129
+ logSection('TÉLÉCHARGEMENT INFRASTRUCTURE');
130
+
131
+ mkdirSync(INSTALL_DIR, { recursive: true });
132
+
133
+ console.log('📥 Téléchargement docker-compose.yml...');
134
+
135
+ const composeUrl = 'https://raw.githubusercontent.com/DeamonDev888/overmind-mcp/main/docker-compose.yml';
136
+ const exportersUrl = 'https://raw.githubusercontent.com/DeamonDev888/overmind-mcp/main/docker-compose.exporters.yml';
137
+
138
+ try {
139
+ const composeData = runCommand(`curl -sL ${composeUrl}`);
140
+ if (composeData) {
141
+ writeFileSync(join(INSTALL_DIR, 'docker-compose.yml'), composeData);
142
+ console.log('✅ docker-compose.yml téléchargé');
143
+ }
144
+
145
+ const exportersData = runCommand(`curl -sL ${exportersUrl}`);
146
+ if (exportersData) {
147
+ writeFileSync(join(INSTALL_DIR, 'docker-compose.exporters.yml'), exportersData);
148
+ console.log('✅ docker-compose.exporters.yml téléchargé');
149
+ }
150
+
151
+ return true;
152
+ } catch (error) {
153
+ console.error('❌ Erreur téléchargement:', error.message);
154
+ return false;
155
+ }
156
+ }
157
+
158
+ async function startInfrastructure() {
159
+ logSection('DÉMARRAGE INFRASTRUCTURE DOCKER');
160
+
161
+ const composeFile = join(INSTALL_DIR, 'docker-compose.yml');
162
+
163
+ if (!existsSync(composeFile)) {
164
+ console.log('⚠️ docker-compose.yml non trouvé. Installation infrastructure skippée.');
165
+ return false;
166
+ }
167
+
168
+ try {
169
+ console.log('🚀 Démarrage des services...');
170
+ await runCommandAsync(
171
+ `cd "${INSTALL_DIR}" && docker-compose -f docker-compose.yml up -d`,
172
+ 'Démarrage infrastructure'
173
+ );
174
+
175
+ console.log('');
176
+ console.log('⏳ Attente démarrage des services (15s)...');
177
+ await new Promise(resolve => setTimeout(resolve, 15000));
178
+
179
+ return true;
180
+ } catch (error) {
181
+ console.error('❌ Erreur démarrage:', error.message);
182
+ return false;
183
+ }
184
+ }
185
+
186
+ async function validateServices() {
187
+ logSection('VALIDATION DES SERVICES');
188
+
189
+ console.log('🔍 Vérification des containers...');
190
+ console.log('');
191
+
192
+ const services = [
193
+ { name: 'PostgreSQL', filter: 'postgres', check: 'pg_isready' },
194
+ { name: 'RabbitMQ', filter: 'rabbitmq', check: null },
195
+ { name: 'Temporal', filter: 'temporal', check: null },
196
+ { name: 'Prometheus', filter: 'prometheus', check: null },
197
+ { name: 'Grafana', filter: 'grafana', check: null },
198
+ { name: 'Jaeger', filter: 'jaeger', check: null },
199
+ ];
200
+
201
+ let allRunning = true;
202
+
203
+ for (const service of services) {
204
+ const containerName = runCommand(
205
+ `docker ps --filter "name=${service.filter}" --format "{{.Names}}"`,
206
+ { stdio: 'pipe' }
207
+ );
208
+
209
+ if (containerName) {
210
+ const name = containerName.trim();
211
+ console.log(`✅ ${service.name}: ${name}`);
212
+ } else {
213
+ console.log(`❌ ${service.name}: Non trouvé`);
214
+ allRunning = false;
215
+ }
216
+ }
217
+
218
+ return allRunning;
219
+ }
220
+
221
+ async function createEnvConfig() {
222
+ const envFile = join(INSTALL_DIR, '.env');
223
+
224
+ if (!existsSync(envFile)) {
225
+ logSection('CRÉATION CONFIGURATION');
226
+
227
+ const envContent = `# OverMind-MCP Environment Configuration
228
+ # Généré automatiquement par npm install
229
+
230
+ # PostgreSQL
231
+ POSTGRES_HOST=localhost
232
+ POSTGRES_PORT=5432
233
+ POSTGRES_USER=postgres
234
+ POSTGRES_PASSWORD=overmind_temp_password_change_me
235
+ POSTGRES_DB=overmind
236
+
237
+ # OpenTelemetry (optionnel)
238
+ OTEL_ENABLED=false
239
+
240
+ # Workspace
241
+ OVERMIND_WORKSPACE=${INSTALL_DIR}
242
+ `;
243
+
244
+ writeFileSync(envFile, envContent);
245
+ console.log('✅ Configuration créée:', envFile);
246
+ }
247
+ }
248
+
249
+ function showSummary() {
250
+ console.log('\n╔══════════════════════════════════════════════════════════════════╗');
251
+ console.log('║ ✅ INSTALLATION TERMINÉE ! ║');
252
+ console.log('╚══════════════════════════════════════════════════════════════════╝');
253
+ console.log('');
254
+ console.log('📋 SERVICES DISPONIBLES:');
255
+ console.log('');
256
+ console.log('┌─────────────────────────────────────────────────────────────────┐');
257
+ console.log('│ Ouvrez Docker Desktop pour voir tous les containers │');
258
+ console.log('│ │');
259
+ console.log('│ URLs utiles: │');
260
+ console.log('│ • Prometheus: http://localhost:9090 │');
261
+ console.log('│ • Grafana: http://localhost:3000 (admin/admin) │');
262
+ console.log('│ • Jaeger: http://localhost:16686 │');
263
+ console.log('│ • RabbitMQ: http://localhost:15672 (guest/guest) │');
264
+ console.log('│ • Temporal: http://localhost:8233 │');
265
+ console.log('└─────────────────────────────────────────────────────────────────┘');
266
+ console.log('');
267
+ console.log('📚 DOCUMENTATION:');
268
+ console.log(' • https://github.com/DeamonDev888/overmind-mcp');
269
+ console.log(' • https://www.npmjs.com/package/overmind-mcp');
270
+ console.log('');
271
+ console.log('🎉 PROCHAINE ÉTAPE:');
272
+ console.log(' • Créez votre premier agent: overmind create-agent');
273
+ console.log(' • Ou utilisez: overmind-setup --full');
274
+ console.log('');
275
+ }
276
+
277
+ // ═══════════════════════════════════════════════════════════════════════════════
278
+ // MAIN
279
+ // ═══════════════════════════════════════════════════════════════════════════════
280
+
281
+ async function main() {
282
+ console.log('╔══════════════════════════════════════════════════════════════════╗');
283
+ console.log('║ ║');
284
+ console.log('║ 🚀 OVERMIND-MCP - INSTALLATION AUTOMATIQUE ║');
285
+ console.log('║ npm install -g overmind-mcp ║');
286
+ console.log('║ ║');
287
+ console.log('╚══════════════════════════════════════════════════════════════════╝');
288
+ console.log('');
289
+
290
+ // Step 1: Check Docker
291
+ const dockerOk = await checkDocker();
292
+ if (!dockerOk) {
293
+ console.log('\n⚠️ Relancez après installation de Docker: npm install -g overmind-mcp');
294
+ return;
295
+ }
296
+
297
+ // Step 2: Setup .env
298
+ await createEnvConfig();
299
+
300
+ // Step 3: Download docker-compose files
301
+ const downloaded = await setupInfrastructure();
302
+ if (!downloaded) {
303
+ console.log('\n⚠️ Impossible de télécharger l\'infrastructure. Continue en mode minimal.');
304
+ showSummary();
305
+ return;
306
+ }
307
+
308
+ // Step 4: Start infrastructure
309
+ const started = await startInfrastructure();
310
+ if (!started) {
311
+ console.log('\n⚠️ Infrastructure non démarrée. Continue en mode minimal.');
312
+ showSummary();
313
+ return;
314
+ }
315
+
316
+ // Step 5: Validate services
317
+ await validateServices();
318
+
319
+ // Show summary
320
+ showSummary();
321
+ }
322
+
323
+ // Run main
324
+ main().catch((error) => {
325
+ console.error('\n❌ ERREUR FATALE:', error.message);
326
+ process.exit(1);
327
+ });