claude-flow 2.0.0-alpha.62 → 2.0.0-alpha.64

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.
Files changed (104) hide show
  1. package/.claude/commands/analysis/COMMAND_COMPLIANCE_REPORT.md +54 -0
  2. package/.claude/commands/analysis/token-efficiency.md +2 -1
  3. package/.claude/commands/automation/self-healing.md +47 -2
  4. package/.claude/commands/automation/session-memory.md +39 -10
  5. package/.claude/commands/automation/smart-agents.md +36 -8
  6. package/.claude/commands/github/code-review-swarm.md +80 -15
  7. package/.claude/commands/github/github-modes.md +14 -14
  8. package/.claude/commands/github/issue-tracker.md +19 -16
  9. package/.claude/commands/github/multi-repo-swarm.md +114 -16
  10. package/.claude/commands/github/pr-manager.md +5 -4
  11. package/.claude/commands/github/project-board-sync.md +38 -5
  12. package/.claude/commands/github/release-manager.md +19 -19
  13. package/.claude/commands/github/release-swarm.md +102 -13
  14. package/.claude/commands/github/repo-architect.md +6 -6
  15. package/.claude/commands/github/swarm-issue.md +139 -17
  16. package/.claude/commands/github/swarm-pr.md +49 -15
  17. package/.claude/commands/github/sync-coordinator.md +33 -33
  18. package/.claude/commands/github/workflow-automation.md +37 -10
  19. package/.claude/commands/hooks/overview.md +2 -2
  20. package/.claude/commands/hooks/setup.md +7 -7
  21. package/.claude/commands/memory/neural.md +10 -5
  22. package/.claude/commands/memory/usage.md +9 -5
  23. package/.claude/commands/monitoring/agents.md +7 -5
  24. package/.claude/commands/monitoring/status.md +8 -5
  25. package/.claude/commands/optimization/auto-topology.md +13 -1
  26. package/.claude/commands/optimization/parallel-execution.md +7 -1
  27. package/.claude/commands/sparc/analyzer.md +28 -2
  28. package/.claude/commands/sparc/architect.md +27 -1
  29. package/.claude/commands/sparc/batch-executor.md +27 -1
  30. package/.claude/commands/sparc/coder.md +27 -1
  31. package/.claude/commands/sparc/debugger.md +27 -1
  32. package/.claude/commands/sparc/designer.md +27 -1
  33. package/.claude/commands/sparc/documenter.md +27 -1
  34. package/.claude/commands/sparc/innovator.md +27 -1
  35. package/.claude/commands/sparc/memory-manager.md +27 -1
  36. package/.claude/commands/sparc/optimizer.md +27 -1
  37. package/.claude/commands/sparc/orchestrator.md +106 -2
  38. package/.claude/commands/sparc/researcher.md +27 -1
  39. package/.claude/commands/sparc/reviewer.md +27 -1
  40. package/.claude/commands/sparc/sparc-modes.md +137 -5
  41. package/.claude/commands/sparc/swarm-coordinator.md +27 -1
  42. package/.claude/commands/sparc/tdd.md +27 -1
  43. package/.claude/commands/sparc/tester.md +27 -1
  44. package/.claude/commands/sparc/workflow-manager.md +27 -1
  45. package/.claude/commands/swarm/analysis.md +82 -5
  46. package/.claude/commands/swarm/development.md +83 -6
  47. package/.claude/commands/swarm/examples.md +141 -3
  48. package/.claude/commands/swarm/maintenance.md +92 -8
  49. package/.claude/commands/swarm/optimization.md +107 -9
  50. package/.claude/commands/swarm/research.md +126 -8
  51. package/.claude/commands/swarm/testing.md +121 -9
  52. package/.claude/commands/training/neural-patterns.md +27 -2
  53. package/.claude/commands/training/specialization.md +13 -3
  54. package/.claude/commands/workflows/development.md +43 -4
  55. package/.claude/commands/workflows/research.md +26 -2
  56. package/CHANGELOG.md +34 -0
  57. package/README.md +8 -0
  58. package/bin/claude-flow +1 -1
  59. package/dist/cli/simple-commands/hive-mind/mcp-wrapper.d.ts +66 -0
  60. package/dist/cli/simple-commands/hive-mind/mcp-wrapper.d.ts.map +1 -1
  61. package/dist/cli/simple-commands/hive-mind/mcp-wrapper.js +220 -2
  62. package/dist/cli/simple-commands/hive-mind/mcp-wrapper.js.map +1 -1
  63. package/dist/cli/simple-commands/hive-mind.d.ts.map +1 -1
  64. package/dist/cli/simple-commands/hive-mind.js +83 -5
  65. package/dist/cli/simple-commands/hive-mind.js.map +1 -1
  66. package/dist/memory/fallback-store.d.ts +1 -0
  67. package/dist/memory/fallback-store.d.ts.map +1 -1
  68. package/dist/memory/fallback-store.js +25 -3
  69. package/dist/memory/fallback-store.js.map +1 -1
  70. package/dist/memory/sqlite-store.d.ts +34 -0
  71. package/dist/memory/sqlite-store.d.ts.map +1 -0
  72. package/dist/memory/sqlite-store.js +2 -3
  73. package/dist/memory/sqlite-store.js.map +1 -1
  74. package/dist/memory/sqlite-wrapper.d.ts +38 -0
  75. package/dist/memory/sqlite-wrapper.d.ts.map +1 -0
  76. package/dist/memory/sqlite-wrapper.js +157 -0
  77. package/dist/memory/sqlite-wrapper.js.map +1 -0
  78. package/package.json +1 -1
  79. package/src/api/claude-api-errors.ts +248 -0
  80. package/src/api/claude-client-enhanced.ts +616 -0
  81. package/src/api/claude-client.ts +282 -14
  82. package/src/cli/help-text.js +4 -3
  83. package/src/cli/simple-cli.js +1 -1
  84. package/src/cli/simple-commands/coordination.js +73 -49
  85. package/src/cli/simple-commands/hive-mind/auto-save-middleware.js +6 -6
  86. package/src/cli/simple-commands/hive-mind/mcp-wrapper.js +327 -8
  87. package/src/cli/simple-commands/hive-mind/session-manager.js +330 -108
  88. package/src/cli/simple-commands/hive-mind.js +192 -11
  89. package/src/cli/simple-commands/init/claude-commands/optimized-slash-commands.js +53 -28
  90. package/src/cli/simple-commands/init/claude-commands/slash-commands.js +36 -14
  91. package/src/cli/simple-commands/init/claude-commands/sparc-commands.js +107 -30
  92. package/src/cli/simple-commands/init/copy-revised-templates.js +175 -0
  93. package/src/cli/simple-commands/init/index.js +156 -235
  94. package/src/cli/simple-commands/init/template-copier.js +583 -0
  95. package/src/cli/simple-commands/init/templates/claude-flow-universal +1 -1
  96. package/src/cli/simple-commands/init/templates/coordination.md +16 -0
  97. package/src/cli/simple-commands/init/templates/memory-bank.md +16 -0
  98. package/src/cli/simple-commands/init/templates/settings.json.enhanced +35 -0
  99. package/src/cli/simple-commands/init/templates/sparc-modes.js +634 -23
  100. package/src/hive-mind/core/DatabaseManager.ts +75 -16
  101. package/src/memory/backends/sqlite.ts +21 -3
  102. package/src/memory/fallback-store.js +35 -3
  103. package/src/memory/sqlite-store.js +2 -3
  104. package/src/memory/sqlite-wrapper.js +173 -0
@@ -3,25 +3,77 @@
3
3
  * Handles session persistence and resume functionality for swarms
4
4
  */
5
5
 
6
- import Database from 'better-sqlite3';
7
6
  import path from 'path';
8
7
  import { existsSync, mkdirSync } from 'fs';
9
8
  import { readFile, writeFile } from 'fs/promises';
10
9
  import chalk from 'chalk';
11
10
  import { cwd } from '../../node-compat.js';
11
+ import { createDatabase, isSQLiteAvailable, isWindows } from '../../../memory/sqlite-wrapper.js';
12
12
 
13
13
  export class HiveMindSessionManager {
14
14
  constructor(hiveMindDir = null) {
15
15
  this.hiveMindDir = hiveMindDir || path.join(cwd(), '.hive-mind');
16
16
  this.sessionsDir = path.join(this.hiveMindDir, 'sessions');
17
17
  this.dbPath = path.join(this.hiveMindDir, 'hive.db');
18
+ this.db = null;
19
+ this.isInMemory = false;
20
+ this.memoryStore = null;
18
21
 
19
22
  // Ensure directories exist
20
23
  this.ensureDirectories();
21
24
 
22
25
  // Initialize database connection
23
- this.db = new Database(this.dbPath);
24
- this.initializeSchema();
26
+ this.initializeDatabase();
27
+ }
28
+
29
+ /**
30
+ * Initialize database with fallback support
31
+ */
32
+ async initializeDatabase() {
33
+ try {
34
+ const sqliteAvailable = await isSQLiteAvailable();
35
+
36
+ if (!sqliteAvailable) {
37
+ console.warn('SQLite not available, using in-memory session storage');
38
+ this.initializeInMemoryFallback();
39
+ return;
40
+ }
41
+
42
+ this.db = await createDatabase(this.dbPath);
43
+ this.initializeSchema();
44
+ } catch (error) {
45
+ console.error('Failed to create SQLite database:', error.message);
46
+ console.warn('Falling back to in-memory session storage');
47
+ this.initializeInMemoryFallback();
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Ensure database is initialized before use
53
+ */
54
+ async ensureInitialized() {
55
+ if (this.db === null && !this.isInMemory) {
56
+ await this.initializeDatabase();
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Initialize in-memory fallback for session storage
62
+ */
63
+ initializeInMemoryFallback() {
64
+ this.isInMemory = true;
65
+ this.memoryStore = {
66
+ sessions: new Map(),
67
+ checkpoints: new Map(),
68
+ logs: new Map()
69
+ };
70
+
71
+ if (isWindows()) {
72
+ console.info(`
73
+ Note: Session data will not persist between runs on Windows without SQLite.
74
+ To enable persistence, see: https://github.com/ruvnet/claude-code-flow/docs/windows-installation.md
75
+ `);
76
+ }
25
77
  }
26
78
 
27
79
  /**
@@ -110,18 +162,38 @@ export class HiveMindSessionManager {
110
162
  /**
111
163
  * Create a new session for a swarm
112
164
  */
113
- createSession(swarmId, swarmName, objective, metadata = {}) {
165
+ async createSession(swarmId, swarmName, objective, metadata = {}) {
166
+ await this.ensureInitialized();
167
+
114
168
  const sessionId = `session-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
115
169
 
116
- const stmt = this.db.prepare(`
117
- INSERT INTO sessions (id, swarm_id, swarm_name, objective, metadata, parent_pid)
118
- VALUES (?, ?, ?, ?, ?, ?)
119
- `);
120
-
121
- stmt.run(sessionId, swarmId, swarmName, objective, JSON.stringify(metadata), process.pid);
170
+ if (this.isInMemory) {
171
+ // Use in-memory storage
172
+ const sessionData = {
173
+ id: sessionId,
174
+ swarm_id: swarmId,
175
+ swarm_name: swarmName,
176
+ objective,
177
+ status: 'active',
178
+ created_at: new Date().toISOString(),
179
+ updated_at: new Date().toISOString(),
180
+ metadata: JSON.stringify(metadata),
181
+ parent_pid: process.pid,
182
+ child_pids: '[]'
183
+ };
184
+ this.memoryStore.sessions.set(sessionId, sessionData);
185
+ } else {
186
+ // Use SQLite
187
+ const stmt = this.db.prepare(`
188
+ INSERT INTO sessions (id, swarm_id, swarm_name, objective, metadata, parent_pid)
189
+ VALUES (?, ?, ?, ?, ?, ?)
190
+ `);
191
+
192
+ stmt.run(sessionId, swarmId, swarmName, objective, JSON.stringify(metadata), process.pid);
193
+ }
122
194
 
123
195
  // Log session creation
124
- this.logSessionEvent(sessionId, 'info', 'Session created', null, {
196
+ await this.logSessionEvent(sessionId, 'info', 'Session created', null, {
125
197
  swarmId,
126
198
  swarmName,
127
199
  objective,
@@ -135,24 +207,49 @@ export class HiveMindSessionManager {
135
207
  * Save session checkpoint
136
208
  */
137
209
  async saveCheckpoint(sessionId, checkpointName, checkpointData) {
210
+ await this.ensureInitialized();
211
+
138
212
  const checkpointId = `checkpoint-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
139
213
 
140
- // Save to database
141
- const stmt = this.db.prepare(`
142
- INSERT INTO session_checkpoints (id, session_id, checkpoint_name, checkpoint_data)
143
- VALUES (?, ?, ?, ?)
144
- `);
145
-
146
- stmt.run(checkpointId, sessionId, checkpointName, JSON.stringify(checkpointData));
147
-
148
- // Update session checkpoint data and timestamp
149
- const updateStmt = this.db.prepare(`
150
- UPDATE sessions
151
- SET checkpoint_data = ?, updated_at = CURRENT_TIMESTAMP
152
- WHERE id = ?
153
- `);
154
-
155
- updateStmt.run(JSON.stringify(checkpointData), sessionId);
214
+ if (this.isInMemory) {
215
+ // Use in-memory storage
216
+ const checkpointEntry = {
217
+ id: checkpointId,
218
+ session_id: sessionId,
219
+ checkpoint_name: checkpointName,
220
+ checkpoint_data: JSON.stringify(checkpointData),
221
+ created_at: new Date().toISOString()
222
+ };
223
+
224
+ if (!this.memoryStore.checkpoints.has(sessionId)) {
225
+ this.memoryStore.checkpoints.set(sessionId, []);
226
+ }
227
+ this.memoryStore.checkpoints.get(sessionId).push(checkpointEntry);
228
+
229
+ // Update session data
230
+ const session = this.memoryStore.sessions.get(sessionId);
231
+ if (session) {
232
+ session.checkpoint_data = JSON.stringify(checkpointData);
233
+ session.updated_at = new Date().toISOString();
234
+ }
235
+ } else {
236
+ // Save to database
237
+ const stmt = this.db.prepare(`
238
+ INSERT INTO session_checkpoints (id, session_id, checkpoint_name, checkpoint_data)
239
+ VALUES (?, ?, ?, ?)
240
+ `);
241
+
242
+ stmt.run(checkpointId, sessionId, checkpointName, JSON.stringify(checkpointData));
243
+
244
+ // Update session checkpoint data and timestamp
245
+ const updateStmt = this.db.prepare(`
246
+ UPDATE sessions
247
+ SET checkpoint_data = ?, updated_at = CURRENT_TIMESTAMP
248
+ WHERE id = ?
249
+ `);
250
+
251
+ updateStmt.run(JSON.stringify(checkpointData), sessionId);
252
+ }
156
253
 
157
254
  // Save checkpoint file for backup
158
255
  const checkpointFile = path.join(this.sessionsDir, `${sessionId}-${checkpointName}.json`);
@@ -171,7 +268,7 @@ export class HiveMindSessionManager {
171
268
  ),
172
269
  );
173
270
 
174
- this.logSessionEvent(sessionId, 'info', `Checkpoint saved: ${checkpointName}`, null, {
271
+ await this.logSessionEvent(sessionId, 'info', `Checkpoint saved: ${checkpointName}`, null, {
175
272
  checkpointId,
176
273
  });
177
274
 
@@ -181,38 +278,91 @@ export class HiveMindSessionManager {
181
278
  /**
182
279
  * Get active sessions
183
280
  */
184
- getActiveSessions() {
185
- const stmt = this.db.prepare(`
186
- SELECT s.*,
187
- COUNT(DISTINCT a.id) as agent_count,
188
- COUNT(DISTINCT t.id) as task_count,
189
- SUM(CASE WHEN t.status = 'completed' THEN 1 ELSE 0 END) as completed_tasks
190
- FROM sessions s
191
- LEFT JOIN agents a ON s.swarm_id = a.swarm_id
192
- LEFT JOIN tasks t ON s.swarm_id = t.swarm_id
193
- WHERE s.status = 'active' OR s.status = 'paused'
194
- GROUP BY s.id
195
- ORDER BY s.updated_at DESC
196
- `);
197
-
198
- const sessions = stmt.all();
199
-
200
- // Parse JSON fields
201
- return sessions.map((session) => ({
202
- ...session,
203
- metadata: session.metadata ? JSON.parse(session.metadata) : {},
204
- checkpoint_data: session.checkpoint_data ? JSON.parse(session.checkpoint_data) : null,
205
- completion_percentage:
206
- session.task_count > 0
207
- ? Math.round((session.completed_tasks / session.task_count) * 100)
208
- : 0,
209
- }));
281
+ async getActiveSessions() {
282
+ await this.ensureInitialized();
283
+
284
+ if (this.isInMemory) {
285
+ // Use in-memory storage
286
+ const sessions = [];
287
+ for (const [sessionId, session] of this.memoryStore.sessions) {
288
+ if (session.status === 'active' || session.status === 'paused') {
289
+ sessions.push({
290
+ ...session,
291
+ metadata: session.metadata ? JSON.parse(session.metadata) : {},
292
+ checkpoint_data: session.checkpoint_data ? JSON.parse(session.checkpoint_data) : null,
293
+ agent_count: 0, // Not tracked in memory mode
294
+ task_count: 0, // Not tracked in memory mode
295
+ completed_tasks: 0, // Not tracked in memory mode
296
+ completion_percentage: 0
297
+ });
298
+ }
299
+ }
300
+ return sessions.sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at));
301
+ } else {
302
+ // Use SQLite
303
+ const stmt = this.db.prepare(`
304
+ SELECT s.*,
305
+ COUNT(DISTINCT a.id) as agent_count,
306
+ COUNT(DISTINCT t.id) as task_count,
307
+ SUM(CASE WHEN t.status = 'completed' THEN 1 ELSE 0 END) as completed_tasks
308
+ FROM sessions s
309
+ LEFT JOIN agents a ON s.swarm_id = a.swarm_id
310
+ LEFT JOIN tasks t ON s.swarm_id = t.swarm_id
311
+ WHERE s.status = 'active' OR s.status = 'paused'
312
+ GROUP BY s.id
313
+ ORDER BY s.updated_at DESC
314
+ `);
315
+
316
+ const sessions = stmt.all();
317
+
318
+ // Parse JSON fields
319
+ return sessions.map((session) => ({
320
+ ...session,
321
+ metadata: session.metadata ? JSON.parse(session.metadata) : {},
322
+ checkpoint_data: session.checkpoint_data ? JSON.parse(session.checkpoint_data) : null,
323
+ completion_percentage:
324
+ session.task_count > 0
325
+ ? Math.round((session.completed_tasks / session.task_count) * 100)
326
+ : 0,
327
+ }));
328
+ }
210
329
  }
211
330
 
212
331
  /**
213
332
  * Get session by ID with full details
214
333
  */
215
- getSession(sessionId) {
334
+ async getSession(sessionId) {
335
+ await this.ensureInitialized();
336
+
337
+ if (this.isInMemory) {
338
+ // Use in-memory storage
339
+ const session = this.memoryStore.sessions.get(sessionId);
340
+ if (!session) {
341
+ return null;
342
+ }
343
+
344
+ // Return simplified session data for in-memory mode
345
+ return {
346
+ ...session,
347
+ metadata: session.metadata ? JSON.parse(session.metadata) : {},
348
+ checkpoint_data: session.checkpoint_data ? JSON.parse(session.checkpoint_data) : null,
349
+ swarm: null, // Not available in memory mode
350
+ agents: [], // Not available in memory mode
351
+ tasks: [], // Not available in memory mode
352
+ checkpoints: this.memoryStore.checkpoints.get(sessionId) || [],
353
+ recentLogs: this.memoryStore.logs.get(sessionId) || [],
354
+ statistics: {
355
+ totalAgents: 0,
356
+ activeAgents: 0,
357
+ totalTasks: 0,
358
+ completedTasks: 0,
359
+ pendingTasks: 0,
360
+ inProgressTasks: 0,
361
+ completionPercentage: session.completion_percentage || 0,
362
+ },
363
+ };
364
+ }
365
+
216
366
  const session = this.db
217
367
  .prepare(
218
368
  `
@@ -307,28 +457,45 @@ export class HiveMindSessionManager {
307
457
  /**
308
458
  * Pause a session
309
459
  */
310
- pauseSession(sessionId) {
311
- const stmt = this.db.prepare(`
312
- UPDATE sessions
313
- SET status = 'paused', paused_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP
314
- WHERE id = ?
315
- `);
316
-
317
- const result = stmt.run(sessionId);
318
-
319
- if (result.changes > 0) {
320
- this.logSessionEvent(sessionId, 'info', 'Session paused');
321
-
322
- // Update swarm status
323
- const session = this.db.prepare('SELECT swarm_id FROM sessions WHERE id = ?').get(sessionId);
460
+ async pauseSession(sessionId) {
461
+ await this.ensureInitialized();
462
+
463
+ if (this.isInMemory) {
464
+ // Use in-memory storage
465
+ const session = this.memoryStore.sessions.get(sessionId);
324
466
  if (session) {
325
- this.db
326
- .prepare('UPDATE swarms SET status = ? WHERE id = ?')
327
- .run('paused', session.swarm_id);
467
+ session.status = 'paused';
468
+ session.paused_at = new Date().toISOString();
469
+ session.updated_at = new Date().toISOString();
470
+
471
+ await this.logSessionEvent(sessionId, 'info', 'Session paused');
472
+ return true;
473
+ }
474
+ return false;
475
+ } else {
476
+ // Use SQLite
477
+ const stmt = this.db.prepare(`
478
+ UPDATE sessions
479
+ SET status = 'paused', paused_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP
480
+ WHERE id = ?
481
+ `);
482
+
483
+ const result = stmt.run(sessionId);
484
+
485
+ if (result.changes > 0) {
486
+ await this.logSessionEvent(sessionId, 'info', 'Session paused');
487
+
488
+ // Update swarm status
489
+ const session = this.db.prepare('SELECT swarm_id FROM sessions WHERE id = ?').get(sessionId);
490
+ if (session) {
491
+ this.db
492
+ .prepare('UPDATE swarms SET status = ? WHERE id = ?')
493
+ .run('paused', session.swarm_id);
494
+ }
328
495
  }
329
- }
330
496
 
331
- return result.changes > 0;
497
+ return result.changes > 0;
498
+ }
332
499
  }
333
500
 
334
501
  /**
@@ -452,13 +619,35 @@ export class HiveMindSessionManager {
452
619
  /**
453
620
  * Log session event
454
621
  */
455
- logSessionEvent(sessionId, logLevel, message, agentId = null, data = null) {
456
- const stmt = this.db.prepare(`
457
- INSERT INTO session_logs (session_id, log_level, message, agent_id, data)
458
- VALUES (?, ?, ?, ?, ?)
459
- `);
460
-
461
- stmt.run(sessionId, logLevel, message, agentId, data ? JSON.stringify(data) : null);
622
+ async logSessionEvent(sessionId, logLevel, message, agentId = null, data = null) {
623
+ await this.ensureInitialized();
624
+
625
+ if (this.isInMemory) {
626
+ // Use in-memory storage for logs
627
+ const logId = `log-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
628
+ const logEntry = {
629
+ id: logId,
630
+ session_id: sessionId,
631
+ timestamp: new Date().toISOString(),
632
+ log_level: logLevel,
633
+ message,
634
+ agent_id: agentId,
635
+ data: data ? JSON.stringify(data) : null
636
+ };
637
+
638
+ if (!this.memoryStore.logs.has(sessionId)) {
639
+ this.memoryStore.logs.set(sessionId, []);
640
+ }
641
+ this.memoryStore.logs.get(sessionId).push(logEntry);
642
+ } else {
643
+ // Use SQLite
644
+ const stmt = this.db.prepare(`
645
+ INSERT INTO session_logs (session_id, log_level, message, agent_id, data)
646
+ VALUES (?, ?, ?, ?, ?)
647
+ `);
648
+
649
+ stmt.run(sessionId, logLevel, message, agentId, data ? JSON.stringify(data) : null);
650
+ }
462
651
  }
463
652
 
464
653
  /**
@@ -483,14 +672,26 @@ export class HiveMindSessionManager {
483
672
  /**
484
673
  * Update session progress
485
674
  */
486
- updateSessionProgress(sessionId, completionPercentage) {
487
- const stmt = this.db.prepare(`
488
- UPDATE sessions
489
- SET completion_percentage = ?, updated_at = CURRENT_TIMESTAMP
490
- WHERE id = ?
491
- `);
492
-
493
- stmt.run(completionPercentage, sessionId);
675
+ async updateSessionProgress(sessionId, completionPercentage) {
676
+ await this.ensureInitialized();
677
+
678
+ if (this.isInMemory) {
679
+ // Use in-memory storage
680
+ const session = this.memoryStore.sessions.get(sessionId);
681
+ if (session) {
682
+ session.completion_percentage = completionPercentage;
683
+ session.updated_at = new Date().toISOString();
684
+ }
685
+ } else {
686
+ // Use SQLite
687
+ const stmt = this.db.prepare(`
688
+ UPDATE sessions
689
+ SET completion_percentage = ?, updated_at = CURRENT_TIMESTAMP
690
+ WHERE id = ?
691
+ `);
692
+
693
+ stmt.run(completionPercentage, sessionId);
694
+ }
494
695
  }
495
696
 
496
697
  /**
@@ -652,33 +853,42 @@ export class HiveMindSessionManager {
652
853
  /**
653
854
  * Get all child PIDs for a session
654
855
  */
655
- getChildPids(sessionId) {
656
- const session = this.db.prepare('SELECT child_pids FROM sessions WHERE id = ?').get(sessionId);
657
- if (!session || !session.child_pids) return [];
658
-
659
- return JSON.parse(session.child_pids);
856
+ async getChildPids(sessionId) {
857
+ await this.ensureInitialized();
858
+
859
+ if (this.isInMemory) {
860
+ // Use in-memory storage
861
+ const session = this.memoryStore.sessions.get(sessionId);
862
+ if (!session || !session.child_pids) return [];
863
+ return JSON.parse(session.child_pids);
864
+ } else {
865
+ // Use SQLite
866
+ const session = this.db.prepare('SELECT child_pids FROM sessions WHERE id = ?').get(sessionId);
867
+ if (!session || !session.child_pids) return [];
868
+ return JSON.parse(session.child_pids);
869
+ }
660
870
  }
661
871
 
662
872
  /**
663
873
  * Stop a session and terminate all child processes
664
874
  */
665
875
  async stopSession(sessionId) {
666
- const session = this.getSession(sessionId);
876
+ const session = await this.getSession(sessionId);
667
877
  if (!session) {
668
878
  throw new Error(`Session ${sessionId} not found`);
669
879
  }
670
880
 
671
881
  // Get child PIDs
672
- const childPids = this.getChildPids(sessionId);
882
+ const childPids = await this.getChildPids(sessionId);
673
883
 
674
884
  // Terminate child processes
675
885
  for (const pid of childPids) {
676
886
  try {
677
887
  process.kill(pid, 'SIGTERM');
678
- this.logSessionEvent(sessionId, 'info', 'Child process terminated', null, { pid });
888
+ await this.logSessionEvent(sessionId, 'info', 'Child process terminated', null, { pid });
679
889
  } catch (err) {
680
890
  // Process might already be dead
681
- this.logSessionEvent(sessionId, 'warning', 'Failed to terminate child process', null, {
891
+ await this.logSessionEvent(sessionId, 'warning', 'Failed to terminate child process', null, {
682
892
  pid,
683
893
  error: err.message,
684
894
  });
@@ -686,18 +896,28 @@ export class HiveMindSessionManager {
686
896
  }
687
897
 
688
898
  // Update session status
689
- const stmt = this.db.prepare(`
690
- UPDATE sessions
691
- SET status = 'stopped', updated_at = CURRENT_TIMESTAMP
692
- WHERE id = ?
693
- `);
899
+ if (this.isInMemory) {
900
+ // Use in-memory storage
901
+ const sessionData = this.memoryStore.sessions.get(sessionId);
902
+ if (sessionData) {
903
+ sessionData.status = 'stopped';
904
+ sessionData.updated_at = new Date().toISOString();
905
+ }
906
+ } else {
907
+ // Use SQLite
908
+ const stmt = this.db.prepare(`
909
+ UPDATE sessions
910
+ SET status = 'stopped', updated_at = CURRENT_TIMESTAMP
911
+ WHERE id = ?
912
+ `);
694
913
 
695
- stmt.run(sessionId);
914
+ stmt.run(sessionId);
696
915
 
697
- // Update swarm status
698
- this.db.prepare('UPDATE swarms SET status = ? WHERE id = ?').run('stopped', session.swarm_id);
916
+ // Update swarm status
917
+ this.db.prepare('UPDATE swarms SET status = ? WHERE id = ?').run('stopped', session.swarm_id);
918
+ }
699
919
 
700
- this.logSessionEvent(sessionId, 'info', 'Session stopped');
920
+ await this.logSessionEvent(sessionId, 'info', 'Session stopped');
701
921
 
702
922
  return true;
703
923
  }
@@ -766,7 +986,9 @@ export class HiveMindSessionManager {
766
986
  * Clean up and close database connection
767
987
  */
768
988
  close() {
769
- this.db.close();
989
+ if (this.db && !this.isInMemory) {
990
+ this.db.close();
991
+ }
770
992
  }
771
993
  }
772
994