overmind-mcp 3.4.2 → 3.5.0

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,249 @@
1
+ /**
2
+ * HermesGatewayRunner — HTTP-based runner for the Hermes API Server.
3
+ *
4
+ * ╔══════════════════════════════════════════════════════════════════════╗
5
+ * ║ ARCHITECTURE (v3.5 — Gateway Integration) ║
6
+ * ║ ║
7
+ * ║ Replaces the subprocess spawn in HermesRunner with HTTP+SSE calls ║
8
+ * ║ to the Hermes API Server (gateway/platforms/api_server.py). ║
9
+ * ║ ║
10
+ * ║ BENEFITS over HermesRunner (spawn): ║
11
+ * ║ - No Python startup per call (~5-10s saved) ║
12
+ * ║ - SSE streaming output in real-time ║
13
+ * ║ - Native session management via X-Hermes-Session-Id header ║
14
+ * ║ - Proper abort via fetch AbortController ║
15
+ * ║ - Model/provider swap via config, not CLI flags ║
16
+ * ║ ║
17
+ * ║ ENDPOINTS USED: ║
18
+ * ║ POST /v1/chat/completions → main chat (streaming SSE or JSON) ║
19
+ * ║ GET /health → connectivity check ║
20
+ * ║ ║
21
+ * ║ FALLBACK: ║
22
+ * ║ If the API server is not running, falls back to HermesRunner ║
23
+ * ║ (subprocess spawn) for backward compatibility. ║
24
+ * ╚══════════════════════════════════════════════════════════════════════╝
25
+ */
26
+ import { HermesGatewayManager } from './HermesGatewayManager.js';
27
+ import { registerLiveAgent, appendLiveOutput, setLiveStatus, unregisterLiveAgent, } from '../lib/agent_lifecycle.js';
28
+ import { registerProcess } from '../lib/processRegistry.js';
29
+ import { withSpan } from '../lib/telemetry.js';
30
+ import { rootLogger } from '../lib/logger.js';
31
+ import { saveSessionId, getLastSessionId } from '../lib/sessions.js';
32
+ import { getWorkspaceDir } from '../lib/config.js';
33
+ const logger = rootLogger.child({ module: 'HermesGatewayRunner' });
34
+ /** Pseudo-PID for gateway runs (no real OS process to track) */
35
+ let gatewayPidCounter = 70000;
36
+ /** In-memory session map for gateway runs: agentName → sessionId */
37
+ const gatewaySessions = new Map();
38
+ /**
39
+ * Runner that talks to the Hermes API Server via HTTP+SSE.
40
+ *
41
+ * Falls back to HermesRunner (subprocess spawn) if the API server is not
42
+ * available — ensuring zero downtime during the migration.
43
+ */
44
+ export class HermesGatewayRunner {
45
+ manager;
46
+ constructor() {
47
+ this.manager = HermesGatewayManager.getInstance();
48
+ }
49
+ /**
50
+ * Run a prompt against the Hermes API Server.
51
+ *
52
+ * If the server is not reachable, returns an error with transport='fallback-spawn'
53
+ * so the caller can decide to use the old HermesRunner.
54
+ */
55
+ async runAgent(options) {
56
+ const { agentName } = options;
57
+ let { sessionId } = options;
58
+ // ─── Resolve session ──────────────────────────────────────────────────
59
+ if (options.autoResume && agentName && !sessionId) {
60
+ // Try in-memory gateway sessions first
61
+ const gwSession = gatewaySessions.get(agentName);
62
+ if (gwSession) {
63
+ sessionId = gwSession;
64
+ }
65
+ else {
66
+ // Fall back to persisted sessions (from spawn mode)
67
+ const lastId = await getLastSessionId(agentName, getWorkspaceDir(), 'hermes');
68
+ if (lastId) {
69
+ sessionId = lastId;
70
+ logger.info({ sessionId }, '[GatewayRunner] Auto-resume from persisted sessions.');
71
+ }
72
+ }
73
+ }
74
+ return withSpan('hermes.gateway.runAgent', async (span) => {
75
+ span.setAttribute('agentName', agentName || '');
76
+ span.setAttribute('transport', 'gateway-http');
77
+ // ─── Ensure gateway is ready ──────────────────────────────────────
78
+ const gw = await this.manager.ensureReady();
79
+ if (!gw) {
80
+ return {
81
+ result: '',
82
+ error: 'GATEWAY_NOT_READY',
83
+ transport: 'fallback-spawn',
84
+ };
85
+ }
86
+ // ─── Register a pseudo-agent for lifecycle tracking ───────────────
87
+ const pseudoPid = ++gatewayPidCounter;
88
+ const abortController = new AbortController();
89
+ registerLiveAgent({
90
+ pid: pseudoPid,
91
+ runner: 'hermes-gateway',
92
+ agentName: agentName || 'anonymous',
93
+ sessionId: sessionId || '',
94
+ abortController,
95
+ cleanupFn: async () => {
96
+ abortController.abort();
97
+ },
98
+ childRef: null, // No child process — HTTP-based
99
+ });
100
+ // Also register in processRegistry for cross-system visibility
101
+ void registerProcess(pseudoPid, {
102
+ agentName: agentName || '',
103
+ runner: 'hermes-gateway',
104
+ configPath: getWorkspaceDir(),
105
+ });
106
+ try {
107
+ const result = await this.executeChat(gw, options, sessionId, pseudoPid, abortController.signal);
108
+ // Save session linkage
109
+ if (result.sessionId && agentName) {
110
+ gatewaySessions.set(agentName, result.sessionId);
111
+ await saveSessionId(agentName, result.sessionId, getWorkspaceDir(), 'hermes');
112
+ }
113
+ setLiveStatus(pseudoPid, result.error ? 'failed' : 'done', result.error ? 1 : 0);
114
+ return result;
115
+ }
116
+ catch (error) {
117
+ const errMsg = error instanceof Error ? error.message : String(error);
118
+ logger.error({ error: errMsg, agentName }, '[GatewayRunner] Run failed.');
119
+ setLiveStatus(pseudoPid, 'failed', 1);
120
+ return {
121
+ result: '',
122
+ error: `GATEWAY_ERROR: ${errMsg}`,
123
+ transport: 'gateway-http',
124
+ };
125
+ }
126
+ finally {
127
+ unregisterLiveAgent(pseudoPid);
128
+ }
129
+ }, { agentName: agentName || '', transport: 'gateway-http' });
130
+ }
131
+ /**
132
+ * Execute a chat completion against the API server.
133
+ *
134
+ * Uses streaming SSE to get real-time output, assembling the final
135
+ * text from delta chunks.
136
+ */
137
+ async executeChat(gw, options, sessionId, pseudoPid, externalSignal) {
138
+ const { prompt, agentName, silent } = options;
139
+ // Build request headers
140
+ const headers = {
141
+ 'Content-Type': 'application/json',
142
+ Authorization: `Bearer ${gw.apiKey}`,
143
+ };
144
+ // Session management via header
145
+ if (sessionId) {
146
+ headers['X-Hermes-Session-Id'] = sessionId;
147
+ }
148
+ // Profile selection via header (maps to -p <profile>)
149
+ const profile = options.profile || agentName;
150
+ if (profile && profile !== 'default') {
151
+ headers['X-Hermes-Profile'] = profile;
152
+ }
153
+ // Build request body (OpenAI chat completions format)
154
+ const body = {
155
+ model: options.model || 'hermes-agent',
156
+ messages: [{ role: 'user', content: prompt }],
157
+ stream: true, // Always stream — we assemble the final text
158
+ };
159
+ // Combine abort signals
160
+ const combinedSignal = externalSignal;
161
+ logger.info({ url: gw.url, agentName, sessionId: sessionId?.slice(0, 20), profile }, '[GatewayRunner] POST /v1/chat/completions (streaming)');
162
+ const response = await fetch(`${gw.url}/v1/chat/completions`, {
163
+ method: 'POST',
164
+ headers,
165
+ body: JSON.stringify(body),
166
+ signal: combinedSignal,
167
+ });
168
+ if (!response.ok) {
169
+ const errText = await response.text().catch(() => '(no body)');
170
+ return {
171
+ result: '',
172
+ error: `HTTP_${response.status}: ${errText.slice(0, 500)}`,
173
+ transport: 'gateway-http',
174
+ };
175
+ }
176
+ // ─── Parse SSE stream ────────────────────────────────────────────────
177
+ const fullText = await this.parseSSEStream(response, pseudoPid, silent, agentName);
178
+ // Extract session ID from response headers
179
+ const responseSessionId = response.headers.get('x-hermes-session-id') || undefined;
180
+ return {
181
+ result: fullText.trim(),
182
+ sessionId: responseSessionId || sessionId,
183
+ rawOutput: fullText,
184
+ model: options.model,
185
+ transport: 'gateway-http',
186
+ };
187
+ }
188
+ /**
189
+ * Parse the SSE stream from /v1/chat/completions.
190
+ *
191
+ * Format (OpenAI-compatible):
192
+ * data: {"choices":[{"delta":{"content":"hello"}}]}
193
+ * data: {"choices":[{"delta":{"content":" world"}}]}
194
+ * data: [DONE]
195
+ *
196
+ * Assembles full text, streams chunks to agent_lifecycle in real-time.
197
+ */
198
+ async parseSSEStream(response, pseudoPid, silent, agentName) {
199
+ let fullText = '';
200
+ const reader = response.body?.getReader();
201
+ if (!reader) {
202
+ throw new Error('No response body for SSE stream');
203
+ }
204
+ const decoder = new TextDecoder();
205
+ let buffer = '';
206
+ try {
207
+ while (true) {
208
+ const { done, value } = await reader.read();
209
+ if (done)
210
+ break;
211
+ buffer += decoder.decode(value, { stream: true });
212
+ // Process complete SSE events (separated by \n\n)
213
+ const events = buffer.split('\n\n');
214
+ buffer = events.pop() || ''; // Keep incomplete chunk in buffer
215
+ for (const event of events) {
216
+ const line = event.trim();
217
+ if (!line.startsWith('data: '))
218
+ continue;
219
+ const data = line.slice(6); // Remove "data: " prefix
220
+ // End of stream
221
+ if (data === '[DONE]')
222
+ continue;
223
+ try {
224
+ const parsed = JSON.parse(data);
225
+ const delta = parsed.choices?.[0]?.delta;
226
+ if (delta?.content) {
227
+ const chunk = delta.content;
228
+ fullText += chunk;
229
+ // Stream to agent_lifecycle for real-time output
230
+ appendLiveOutput(pseudoPid, chunk);
231
+ // Also write to stderr for live monitoring (matching HermesRunner pattern)
232
+ if (!silent && agentName) {
233
+ process.stderr.write(`[HermesGW:${agentName}] ${chunk}`);
234
+ }
235
+ }
236
+ }
237
+ catch {
238
+ // Non-JSON line (e.g., comments) — skip
239
+ }
240
+ }
241
+ }
242
+ }
243
+ finally {
244
+ reader.releaseLock?.();
245
+ }
246
+ return fullText;
247
+ }
248
+ }
249
+ //# sourceMappingURL=HermesGatewayRunner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HermesGatewayRunner.js","sourceRoot":"","sources":["../../src/services/HermesGatewayRunner.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"run_hermes.d.ts","sourceRoot":"","sources":["../../src/tools/run_hermes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,eAAe;;;;;;;;;;;;iBAqBZ,CAAC;AAIjB,wBAAsB,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC;;;;;;;;;;;;GA8FzE"}
1
+ {"version":3,"file":"run_hermes.d.ts","sourceRoot":"","sources":["../../src/tools/run_hermes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,eAAe;;;;;;;;;;;;iBAqBZ,CAAC;AAIjB,wBAAsB,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC;;;;;;;;;;;;GAsHzE"}
@@ -1,5 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { HermesRunner } from '../services/HermesRunner.js';
3
+ import { HermesGatewayRunner } from '../services/HermesGatewayRunner.js';
3
4
  import { storeRun } from '../memory/MemoryFactory.js';
4
5
  import { getWorkspaceDir } from '../lib/config.js';
5
6
  import { deleteSessionId } from '../lib/sessions.js';
@@ -35,32 +36,34 @@ export async function runHermesAgent(args) {
35
36
  isError: true,
36
37
  };
37
38
  }
38
- const runner = new HermesRunner();
39
39
  const { prompt, agentName, autoResume, sessionId, path: argPath, config: argConfig, silent, model, provider, signal, overmindMode, } = args;
40
40
  const finalPath = argPath || getWorkspaceDir();
41
41
  const finalConfig = argConfig || getWorkspaceDir();
42
42
  const start = Date.now();
43
- let result = await runner.runAgent({
43
+ // ─── Try Gateway HTTP first, fall back to subprocess spawn ────────────────
44
+ // The Hermes API Server (port 8642) provides HTTP+SSE chat without the
45
+ // ~5-10s Python startup overhead per call. If it's not running, we
46
+ // transparently fall back to the old HermesRunner (subprocess spawn).
47
+ const gatewayRunner = new HermesGatewayRunner();
48
+ const gwResult = await gatewayRunner.runAgent({
44
49
  prompt,
45
50
  agentName,
46
51
  autoResume,
47
52
  sessionId,
48
- cwd: finalPath,
49
- configPath: finalConfig,
50
- silent,
51
53
  model,
52
54
  provider,
53
55
  signal,
56
+ silent,
54
57
  });
55
- // Retry if session invalid
56
- if (result.error?.includes('session') || result.error?.includes('EXIT_CODE_1')) {
57
- if (agentName)
58
- await deleteSessionId(agentName, finalConfig, 'hermes');
59
- result = await runner.runAgent({
58
+ let result;
59
+ // If gateway returned GATEWAY_NOT_READY, fall back to subprocess spawn
60
+ if (gwResult.transport === 'fallback-spawn' || gwResult.error === 'GATEWAY_NOT_READY') {
61
+ const spawnRunner = new HermesRunner();
62
+ result = await spawnRunner.runAgent({
60
63
  prompt,
61
64
  agentName,
62
- autoResume: false,
63
- sessionId: undefined,
65
+ autoResume,
66
+ sessionId,
64
67
  cwd: finalPath,
65
68
  configPath: finalConfig,
66
69
  silent,
@@ -68,6 +71,26 @@ export async function runHermesAgent(args) {
68
71
  provider,
69
72
  signal,
70
73
  });
74
+ // Retry if session invalid (spawn mode only — gateway handles sessions natively)
75
+ if (result.error?.includes('session') || result.error?.includes('EXIT_CODE_1')) {
76
+ if (agentName)
77
+ await deleteSessionId(agentName, finalConfig, 'hermes');
78
+ result = await spawnRunner.runAgent({
79
+ prompt,
80
+ agentName,
81
+ autoResume: false,
82
+ sessionId: undefined,
83
+ cwd: finalPath,
84
+ configPath: finalConfig,
85
+ silent,
86
+ model,
87
+ provider,
88
+ signal,
89
+ });
90
+ }
91
+ }
92
+ else {
93
+ result = gwResult;
71
94
  }
72
95
  const durationMs = Date.now() - start;
73
96
  // En mode Overmind (appel MCP), le run est déjà stocké par le MCP Server via memory_runs
@@ -1 +1 @@
1
- {"version":3,"file":"run_hermes.js","sourceRoot":"","sources":["../../src/tools/run_hermes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run_hermes.js","sourceRoot":"","sources":["../../src/tools/run_hermes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,108 @@
1
+ # Kanban Roadmap — Overmind v4.0 (FUTURE)
2
+
3
+ > Statut: **DRAFT** — pas implémenté. Sauvegardé comme roadmap possible.
4
+ > Date: 2026-07-08
5
+
6
+ ## Vision
7
+
8
+ Overmind devient l'orchestrateur. Hermes Gateway devient le backbone d'exécution.
9
+ Le Kanban Hermes est exposé via MCP comme **UN SEUL outil** `kanban_hub` (pas 15 outils séparés).
10
+
11
+ ## Architecture cible
12
+
13
+ ```
14
+ OVERMIND MCP (:3099) → Management + Orchestration
15
+ └─ kanban_hub (1 tool MCP) → Wrappe `hermes kanban` CLI
16
+ └─ a2a_hub (1 tool MCP) → Communication inter-workers
17
+ └─ run_agent, memory_*, etc → Multi-runner + PostgreSQL
18
+
19
+ HERMES GATEWAY (backbone) → Execution engine natif
20
+ └─ Dispatcher (tick 60s)
21
+ └─ Kanban board (kanban.db)
22
+ └─ 9 kanban_* tools (injectés aux workers)
23
+ └─ Dashboard + /kanban slash
24
+ └─ Remote gateway (OAuth)
25
+ ```
26
+
27
+ ## Outil MCP unique: `kanban_hub`
28
+
29
+ UN SEUL outil MCP avec `action` enum (comme `a2a_hub` et `agent_control`):
30
+
31
+ ```typescript
32
+ kanban_hub({
33
+ action: "create", // create|list|show|complete|block|unblock|comment|link|dispatch|stats|archive|boards|watch|init
34
+ title: "...", // pour create
35
+ assignee: "sniperbot", // pour create
36
+ taskId: "t_abc123", // pour show/complete/block/unblock/comment/archive
37
+ body: "...", // pour create/comment
38
+ parents: ["t_001"], // pour create (dependencies)
39
+ reason: "...", // pour block
40
+ status: "running", // pour list (filter)
41
+ board: "my-project", // multi-board
42
+ // ... etc
43
+ })
44
+ ```
45
+
46
+ Avantages d'un seul outil:
47
+ - Schema compact (1 entrée dans tools/list au lieu de 15)
48
+ - L'agent découvre toutes les actions dans la description
49
+ - Pattern identique à a2a_hub et agent_control (cohérent)
50
+ - Moins de pollution du context window de l'agent
51
+
52
+ ## Ce qui serait supprimé d'Overmind (redondant)
53
+
54
+ | Fichier | Raison |
55
+ |---------|--------|
56
+ | `src/services/KanbanAdapter.ts` (420 lignes) | Remplacé par `kanban_hub` MCP tool |
57
+ | `src/lib/orchestration/dispatcher.ts` | Gateway dispatcher natif |
58
+ | `src/bridge/ScenarioLoader.ts` (17KB) | Kanban pipeline + decompose natif |
59
+ | YOLO_CONFIG | Retry/circuit-breaker natifs du dispatcher |
60
+
61
+ ## Ce qui reste dans Overmind (son vrai rôle wrapper)
62
+
63
+ - `run_agent` — Multi-runner spawn direct (Mode A)
64
+ - `create_agent` / `list_agents` / `delete_agent` / `update_agent_config`
65
+ - `memory_search` / `memory_store` / `memory_runs` — PostgreSQL vector
66
+ - `agent_control` — Process lifecycle
67
+ - `a2a_hub` — Communication inter-workers HTTP
68
+ - `kanban_hub` — Wrap Kanban Hermes (NOUVEAU, futur)
69
+ - `config_example` / `create_prompt` / `edit_prompt`
70
+ - `run_agents_parallel` — Pour runners non-Hermes
71
+
72
+ ## Phases d'implémentation (futur)
73
+
74
+ ### Phase 1 — Nettoyage
75
+ - Supprimer KanbanAdapter.ts, dispatcher.ts, ScenarioLoader.ts
76
+ - Nettoyer imports
77
+ - Build + test
78
+
79
+ ### Phase 2 — Outil `kanban_hub` MCP unique
80
+ - Créer `src/tools/kanban_hub.ts`
81
+ - 1 schéma Zod avec `action` enum
82
+ - Chaque action appelle `hermes kanban <verb>` via CLI
83
+ - Enregistrer dans server.ts
84
+ - Build + lint + test
85
+
86
+ ### Phase 3 — Gateway lifecycle
87
+ - `gateway_control` intégré à `agent_control` (action: "gateway_start/stop/status")
88
+ - Modifier install-overmind-native.sh pour démarrer gateway
89
+ - systemd service inclut `hermes gateway start`
90
+
91
+ ### Phase 4 — Install scripts
92
+ - postinstall.mjs détecte Hermes, propose install
93
+ - verify-install.mjs vérifie gateway + kanban.db
94
+
95
+ ### Phase 5 — Remote Gateway
96
+ - Documenter Desktop → Server Gateway (OAuth)
97
+ - `docs/REMOTE_GATEWAY.md`
98
+
99
+ ### Phase 6 — A2A + Kanban fusion
100
+ - a2a_hub utilise kanban_create comme fallback durable
101
+ - Si worker HTTP injoignable → tâche kanban
102
+
103
+ ## Prérequis
104
+
105
+ - Hermes Agent installé sur le serveur (`pip install hermes-agent` ou `hermes setup`)
106
+ - `hermes gateway start` fonctionnel
107
+ - `~/.hermes/kanban.db` accessible (symlink ~/.hermes → ~/.overmind/hermes)
108
+ - Hermes v0.18.1+ (Kanban v1 complet)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "overmind-mcp",
3
- "version": "3.4.2",
3
+ "version": "3.5.0",
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",
@@ -17,6 +17,7 @@ import { existsSync, mkdirSync, writeFileSync } from 'fs';
17
17
  import { join } from 'path';
18
18
  import { fileURLToPath } from 'url';
19
19
  import { dirname } from 'path';
20
+ import { randomBytes } from 'crypto';
20
21
  import { createInterface } from 'readline';
21
22
 
22
23
  const __filename = fileURLToPath(import.meta.url);
@@ -219,6 +220,7 @@ async function createEnvConfig() {
219
220
  if (!existsSync(envFile)) {
220
221
  logSection('CRÉATION CONFIGURATION');
221
222
 
223
+ const randomPwd = randomBytes(18).toString('base64url');
222
224
  const envContent = `# OverMind-MCP Environment Configuration
223
225
  # Généré automatiquement par npm install
224
226
 
@@ -226,8 +228,8 @@ async function createEnvConfig() {
226
228
  POSTGRES_HOST=localhost
227
229
  POSTGRES_PORT=5432
228
230
  POSTGRES_USER=postgres
229
- POSTGRES_PASSWORD=overmind_temp_password_change_me
230
- POSTGRES_DB=overmind
231
+ POSTGRES_PASSWORD=${randomPwd}
232
+ POSTGRES_DATABASE=overmind_memory
231
233
 
232
234
  # OpenTelemetry (optionnel)
233
235
  OTEL_ENABLED=false
@@ -16,6 +16,7 @@ import { existsSync } from 'fs';
16
16
  import { join } from 'path';
17
17
  import { fileURLToPath } from 'url';
18
18
  import { dirname } from 'path';
19
+ import { randomBytes } from 'crypto';
19
20
  import { createInterface } from 'readline';
20
21
 
21
22
  const __filename = fileURLToPath(import.meta.url);
@@ -299,8 +300,9 @@ async function installPostgreSQLDocker() {
299
300
  'docker', 'run', '-d',
300
301
  '--name', containerName,
301
302
  '-p', '5432:5432',
302
- '-e', 'POSTGRES_PASSWORD=overmind_temp_password_change_me',
303
+ '-e', `POSTGRES_PASSWORD=${randomBytes(18).toString('base64url')}`,
303
304
  '-e', 'POSTGRES_USER=postgres',
305
+ '-e', 'POSTGRES_DB=overmind_memory',
304
306
  '-v', 'overmind_postgres_data:/var/lib/postgresql/data',
305
307
  '--restart', 'unless-stopped',
306
308
  'pgvector/pgvector:pg16'
@@ -348,7 +350,7 @@ async function installPostgreSQLDocker() {
348
350
  console.log(` Container: ${containerName}`);
349
351
  console.log(' Port: 5432');
350
352
  console.log(' User: postgres');
351
- console.log(' Password: overmind_temp_password_change_me (À CHANGER !)');
353
+ console.log(' Password: (généré automatiquement — voir ~/.overmind/.env)');
352
354
  console.log(' Extension: vector (pgvector)');
353
355
 
354
356
  return { type: 'docker', container: containerName, hasPgvector: true };
@@ -442,7 +444,7 @@ async function main() {
442
444
  • Container: ${installResult.container}
443
445
  • Port: 5432
444
446
  • User: postgres
445
- • Password: overmind_temp_password_change_me (CHANGEZ-LE !)
447
+ • Password: (généré automatiquement — voir ~/.overmind/.env)
446
448
  • Extension: vector (pgvector)
447
449
 
448
450
  ═════════════════════════════════════════════════════════════════════