claude-flow 2.0.0-alpha.63 → 2.0.0-alpha.65

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 (106) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/bin/claude-flow +1 -1
  3. package/dist/api/claude-api-errors.d.ts +115 -0
  4. package/dist/api/claude-api-errors.d.ts.map +1 -0
  5. package/dist/api/claude-api-errors.js +198 -0
  6. package/dist/api/claude-api-errors.js.map +1 -0
  7. package/dist/api/claude-client-enhanced.d.ts +109 -0
  8. package/dist/api/claude-client-enhanced.d.ts.map +1 -0
  9. package/dist/api/claude-client-enhanced.js +479 -0
  10. package/dist/api/claude-client-enhanced.js.map +1 -0
  11. package/dist/api/claude-client.d.ts +42 -0
  12. package/dist/api/claude-client.d.ts.map +1 -1
  13. package/dist/api/claude-client.js +217 -14
  14. package/dist/api/claude-client.js.map +1 -1
  15. package/dist/cli/commands/hive-mind/pause.d.ts.map +1 -1
  16. package/dist/cli/commands/hive-mind/pause.js +6 -5
  17. package/dist/cli/commands/hive-mind/pause.js.map +1 -1
  18. package/dist/cli/commands/hive-mind/ps.js.map +1 -1
  19. package/dist/cli/commands/hive-mind/resume.d.ts.map +1 -1
  20. package/dist/cli/commands/hive-mind/resume.js +4 -3
  21. package/dist/cli/commands/hive-mind/resume.js.map +1 -1
  22. package/dist/cli/commands/hive-mind/stop.js.map +1 -1
  23. package/dist/cli/repl.d.ts.map +1 -1
  24. package/dist/cli/repl.js +44 -22
  25. package/dist/cli/repl.js.map +1 -1
  26. package/dist/cli/simple-cli.js +4 -3
  27. package/dist/cli/simple-cli.js.map +1 -1
  28. package/dist/cli/simple-commands/coordination.js +60 -40
  29. package/dist/cli/simple-commands/coordination.js.map +1 -1
  30. package/dist/cli/simple-commands/hive-mind/auto-save-middleware.d.ts +3 -4
  31. package/dist/cli/simple-commands/hive-mind/auto-save-middleware.d.ts.map +1 -1
  32. package/dist/cli/simple-commands/hive-mind/auto-save-middleware.js +6 -6
  33. package/dist/cli/simple-commands/hive-mind/auto-save-middleware.js.map +1 -1
  34. package/dist/cli/simple-commands/hive-mind/mcp-wrapper.d.ts +1 -1
  35. package/dist/cli/simple-commands/hive-mind/mcp-wrapper.d.ts.map +1 -1
  36. package/dist/cli/simple-commands/hive-mind/mcp-wrapper.js +64 -7
  37. package/dist/cli/simple-commands/hive-mind/mcp-wrapper.js.map +1 -1
  38. package/dist/cli/simple-commands/hive-mind/session-manager.d.ts +139 -0
  39. package/dist/cli/simple-commands/hive-mind/session-manager.d.ts.map +1 -0
  40. package/dist/cli/simple-commands/hive-mind/session-manager.js +308 -95
  41. package/dist/cli/simple-commands/hive-mind/session-manager.js.map +1 -1
  42. package/dist/cli/simple-commands/hive-mind.d.ts.map +1 -1
  43. package/dist/cli/simple-commands/hive-mind.js +88 -10
  44. package/dist/cli/simple-commands/hive-mind.js.map +1 -1
  45. package/dist/cli/simple-commands/init/claude-commands/optimized-slash-commands.d.ts.map +1 -1
  46. package/dist/cli/simple-commands/init/claude-commands/optimized-slash-commands.js +45 -22
  47. package/dist/cli/simple-commands/init/claude-commands/optimized-slash-commands.js.map +1 -1
  48. package/dist/cli/simple-commands/init/claude-commands/slash-commands.d.ts.map +1 -1
  49. package/dist/cli/simple-commands/init/claude-commands/slash-commands.js +34 -13
  50. package/dist/cli/simple-commands/init/claude-commands/slash-commands.js.map +1 -1
  51. package/dist/cli/simple-commands/init/claude-commands/sparc-commands.d.ts.map +1 -1
  52. package/dist/cli/simple-commands/init/claude-commands/sparc-commands.js +107 -30
  53. package/dist/cli/simple-commands/init/claude-commands/sparc-commands.js.map +1 -1
  54. package/dist/cli/simple-commands/init/copy-revised-templates.d.ts +29 -0
  55. package/dist/cli/simple-commands/init/copy-revised-templates.d.ts.map +1 -0
  56. package/dist/cli/simple-commands/init/copy-revised-templates.js +159 -0
  57. package/dist/cli/simple-commands/init/copy-revised-templates.js.map +1 -0
  58. package/dist/cli/simple-commands/init/index.d.ts.map +1 -1
  59. package/dist/cli/simple-commands/init/index.js +139 -196
  60. package/dist/cli/simple-commands/init/index.js.map +1 -1
  61. package/dist/cli/simple-commands/init/template-copier.d.ts +27 -0
  62. package/dist/cli/simple-commands/init/template-copier.d.ts.map +1 -0
  63. package/dist/cli/simple-commands/init/template-copier.js +510 -0
  64. package/dist/cli/simple-commands/init/template-copier.js.map +1 -0
  65. package/dist/cli/simple-commands/init/templates/sparc-modes.d.ts.map +1 -1
  66. package/dist/cli/simple-commands/init/templates/sparc-modes.js +634 -23
  67. package/dist/cli/simple-commands/init/templates/sparc-modes.js.map +1 -1
  68. package/dist/cli/simple-orchestrator.d.ts.map +1 -1
  69. package/dist/cli/simple-orchestrator.js +2 -1
  70. package/dist/cli/simple-orchestrator.js.map +1 -1
  71. package/dist/cli/ui/compatible-ui.js +1 -1
  72. package/dist/cli/ui/compatible-ui.js.map +1 -1
  73. package/dist/cli/ui/index.d.ts.map +1 -1
  74. package/dist/cli/ui/index.js +4 -2
  75. package/dist/cli/ui/index.js.map +1 -1
  76. package/dist/cli/utils/environment-detector.d.ts +5 -0
  77. package/dist/cli/utils/environment-detector.d.ts.map +1 -1
  78. package/dist/cli/utils/environment-detector.js.map +1 -1
  79. package/dist/core/logger.d.ts +2 -0
  80. package/dist/core/logger.d.ts.map +1 -1
  81. package/dist/core/logger.js +3 -0
  82. package/dist/core/logger.js.map +1 -1
  83. package/dist/hive-mind/core/DatabaseManager.d.ts +6 -0
  84. package/dist/hive-mind/core/DatabaseManager.d.ts.map +1 -1
  85. package/dist/hive-mind/core/DatabaseManager.js +66 -15
  86. package/dist/hive-mind/core/DatabaseManager.js.map +1 -1
  87. package/dist/memory/backends/sqlite.d.ts +1 -0
  88. package/dist/memory/backends/sqlite.d.ts.map +1 -1
  89. package/dist/memory/backends/sqlite.js +17 -2
  90. package/dist/memory/backends/sqlite.js.map +1 -1
  91. package/package.json +1 -1
  92. package/src/cli/commands/hive-mind/pause.ts +6 -5
  93. package/src/cli/commands/hive-mind/ps.ts +4 -4
  94. package/src/cli/commands/hive-mind/resume.ts +4 -3
  95. package/src/cli/commands/hive-mind/stop.ts +1 -1
  96. package/src/cli/help-text.js +2 -2
  97. package/src/cli/repl.ts +44 -22
  98. package/src/cli/simple-cli.js +1 -1
  99. package/src/cli/simple-cli.ts +11 -10
  100. package/src/cli/simple-commands/init/index.js +1 -0
  101. package/src/cli/simple-commands/init/templates/claude-flow-universal +1 -1
  102. package/src/cli/simple-orchestrator.ts +2 -1
  103. package/src/cli/ui/compatible-ui.ts +1 -1
  104. package/src/cli/ui/index.ts +4 -2
  105. package/src/cli/utils/environment-detector.ts +2 -2
  106. package/src/core/logger.ts +5 -0
@@ -0,0 +1,139 @@
1
+ export class HiveMindSessionManager {
2
+ constructor(hiveMindDir?: null);
3
+ hiveMindDir: string;
4
+ sessionsDir: string;
5
+ dbPath: string;
6
+ db: any;
7
+ isInMemory: boolean;
8
+ memoryStore: {
9
+ sessions: Map<any, any>;
10
+ checkpoints: Map<any, any>;
11
+ logs: Map<any, any>;
12
+ } | null;
13
+ /**
14
+ * Initialize database with fallback support
15
+ */
16
+ initializeDatabase(): Promise<void>;
17
+ /**
18
+ * Ensure database is initialized before use
19
+ */
20
+ ensureInitialized(): Promise<void>;
21
+ /**
22
+ * Initialize in-memory fallback for session storage
23
+ */
24
+ initializeInMemoryFallback(): void;
25
+ /**
26
+ * Ensure required directories exist
27
+ */
28
+ ensureDirectories(): void;
29
+ /**
30
+ * Initialize database schema for sessions
31
+ */
32
+ initializeSchema(): void;
33
+ /**
34
+ * Run database migrations
35
+ */
36
+ runMigrations(): void;
37
+ /**
38
+ * Create a new session for a swarm
39
+ */
40
+ createSession(swarmId: any, swarmName: any, objective: any, metadata?: {}): Promise<string>;
41
+ /**
42
+ * Save session checkpoint
43
+ */
44
+ saveCheckpoint(sessionId: any, checkpointName: any, checkpointData: any): Promise<string>;
45
+ /**
46
+ * Get active sessions
47
+ */
48
+ getActiveSessions(): Promise<any>;
49
+ /**
50
+ * Get session by ID with full details
51
+ */
52
+ getSession(sessionId: any): Promise<any>;
53
+ /**
54
+ * Pause a session
55
+ */
56
+ pauseSession(sessionId: any): Promise<boolean>;
57
+ /**
58
+ * Resume any previous session (paused, stopped, or inactive)
59
+ */
60
+ resumeSession(sessionId: any): Promise<any>;
61
+ /**
62
+ * Mark session as completed
63
+ */
64
+ completeSession(sessionId: any): boolean;
65
+ /**
66
+ * Archive old sessions
67
+ */
68
+ archiveSessions(daysOld?: number): Promise<any>;
69
+ /**
70
+ * Log session event
71
+ */
72
+ logSessionEvent(sessionId: any, logLevel: any, message: any, agentId?: null, data?: null): Promise<void>;
73
+ /**
74
+ * Get session logs
75
+ */
76
+ getSessionLogs(sessionId: any, limit?: number, offset?: number): any;
77
+ /**
78
+ * Update session progress
79
+ */
80
+ updateSessionProgress(sessionId: any, completionPercentage: any): Promise<void>;
81
+ /**
82
+ * Generate session summary
83
+ */
84
+ generateSessionSummary(sessionId: any): {
85
+ sessionId: any;
86
+ swarmName: any;
87
+ objective: any;
88
+ status: any;
89
+ duration: number;
90
+ statistics: any;
91
+ tasksByType: any;
92
+ checkpointCount: any;
93
+ lastCheckpoint: any;
94
+ timeline: {
95
+ created: any;
96
+ lastUpdated: any;
97
+ paused: any;
98
+ resumed: any;
99
+ };
100
+ } | null;
101
+ /**
102
+ * Export session data
103
+ */
104
+ exportSession(sessionId: any, exportPath?: null): Promise<string>;
105
+ /**
106
+ * Import session data
107
+ */
108
+ importSession(importPath: any): Promise<string>;
109
+ /**
110
+ * Add a child process PID to session
111
+ */
112
+ addChildPid(sessionId: any, pid: any): boolean;
113
+ /**
114
+ * Remove a child process PID from session
115
+ */
116
+ removeChildPid(sessionId: any, pid: any): boolean;
117
+ /**
118
+ * Get all child PIDs for a session
119
+ */
120
+ getChildPids(sessionId: any): Promise<any>;
121
+ /**
122
+ * Stop a session and terminate all child processes
123
+ */
124
+ stopSession(sessionId: any): Promise<boolean>;
125
+ /**
126
+ * Get active sessions with process information
127
+ */
128
+ getActiveSessionsWithProcessInfo(): any;
129
+ /**
130
+ * Clean up orphaned processes
131
+ */
132
+ cleanupOrphanedProcesses(): number;
133
+ /**
134
+ * Clean up and close database connection
135
+ */
136
+ close(): void;
137
+ }
138
+ export default HiveMindSessionManager;
139
+ //# sourceMappingURL=session-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../../../src/cli/simple-commands/hive-mind/session-manager.js"],"names":[],"mappings":"AAYA;IACE,gCAaC;IAZC,oBAAgE;IAChE,oBAA0D;IAC1D,eAAoD;IACpD,QAAc;IACd,oBAAuB;IACvB;;;;aAAuB;IASzB;;OAEG;IACH,oCAiBC;IAED;;OAEG;IACH,mCAIC;IAED;;OAEG;IACH,mCAcC;IAED;;OAEG;IACH,0BAOC;IAED;;OAEG;IACH,yBA0CC;IAED;;OAEG;IACH,sBAmBC;IAED;;OAEG;IACH,4FAuCC;IAED;;OAEG;IACH,0FAmEC;IAED;;OAEG;IACH,kCAgDC;IAED;;OAEG;IACH,yCAyHC;IAED;;OAEG;IACH,+CAuCC;IAED;;OAEG;IACH,4CAkDC;IAED;;OAEG;IACH,yCAsBC;IAED;;OAEG;IACH,gDA+BC;IAED;;OAEG;IACH,yGA6BC;IAED;;OAEG;IACH,qEAcC;IAED;;OAEG;IACH,gFAoBC;IAED;;OAEG;IACH;;;;;;;;;;;;;;;;aAgDC;IAED;;OAEG;IACH,kEAYC;IAED;;OAEG;IACH,gDAgCC;IAED;;OAEG;IACH,+CAmBC;IAED;;OAEG;IACH,kDAoBC;IAED;;OAEG;IACH,2CAcC;IAED;;OAEG;IACH,8CAgDC;IAED;;OAEG;IACH,wCAyBC;IAED;;OAEG;IACH,mCAyBC;IAED;;OAEG;IACH,cAIC;CACF"}
@@ -2,22 +2,69 @@
2
2
  * Hive Mind Session Manager
3
3
  * Handles session persistence and resume functionality for swarms
4
4
  */
5
- import Database from 'better-sqlite3';
6
5
  import path from 'path';
7
6
  import { existsSync, mkdirSync } from 'fs';
8
7
  import { readFile, writeFile } from 'fs/promises';
9
8
  import chalk from 'chalk';
10
9
  import { cwd } from '../../node-compat.js';
10
+ import { createDatabase, isSQLiteAvailable, isWindows } from '../../../memory/sqlite-wrapper.js';
11
11
  export class HiveMindSessionManager {
12
12
  constructor(hiveMindDir = null) {
13
13
  this.hiveMindDir = hiveMindDir || path.join(cwd(), '.hive-mind');
14
14
  this.sessionsDir = path.join(this.hiveMindDir, 'sessions');
15
15
  this.dbPath = path.join(this.hiveMindDir, 'hive.db');
16
+ this.db = null;
17
+ this.isInMemory = false;
18
+ this.memoryStore = null;
16
19
  // Ensure directories exist
17
20
  this.ensureDirectories();
18
21
  // Initialize database connection
19
- this.db = new Database(this.dbPath);
20
- this.initializeSchema();
22
+ this.initializeDatabase();
23
+ }
24
+ /**
25
+ * Initialize database with fallback support
26
+ */
27
+ async initializeDatabase() {
28
+ try {
29
+ const sqliteAvailable = await isSQLiteAvailable();
30
+ if (!sqliteAvailable) {
31
+ console.warn('SQLite not available, using in-memory session storage');
32
+ this.initializeInMemoryFallback();
33
+ return;
34
+ }
35
+ this.db = await createDatabase(this.dbPath);
36
+ this.initializeSchema();
37
+ }
38
+ catch (error) {
39
+ console.error('Failed to create SQLite database:', error.message);
40
+ console.warn('Falling back to in-memory session storage');
41
+ this.initializeInMemoryFallback();
42
+ }
43
+ }
44
+ /**
45
+ * Ensure database is initialized before use
46
+ */
47
+ async ensureInitialized() {
48
+ if (this.db === null && !this.isInMemory) {
49
+ await this.initializeDatabase();
50
+ }
51
+ }
52
+ /**
53
+ * Initialize in-memory fallback for session storage
54
+ */
55
+ initializeInMemoryFallback() {
56
+ this.isInMemory = true;
57
+ this.memoryStore = {
58
+ sessions: new Map(),
59
+ checkpoints: new Map(),
60
+ logs: new Map()
61
+ };
62
+ if (isWindows()) {
63
+ console.info(`
64
+ Note: Session data will not persist between runs on Windows without SQLite.
65
+ To enable persistence, see: https://github.com/ruvnet/claude-code-flow/docs/windows-installation.md
66
+ `);
67
+ }
21
68
  }
22
69
  /**
23
70
  * Ensure required directories exist
@@ -100,15 +147,35 @@ export class HiveMindSessionManager {
100
147
  /**
101
148
  * Create a new session for a swarm
102
149
  */
103
- createSession(swarmId, swarmName, objective, metadata = {}) {
150
+ async createSession(swarmId, swarmName, objective, metadata = {}) {
151
+ await this.ensureInitialized();
104
152
  const sessionId = `session-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
105
- const stmt = this.db.prepare(`
106
- INSERT INTO sessions (id, swarm_id, swarm_name, objective, metadata, parent_pid)
107
- VALUES (?, ?, ?, ?, ?, ?)
108
- `);
109
- stmt.run(sessionId, swarmId, swarmName, objective, JSON.stringify(metadata), process.pid);
153
+ if (this.isInMemory) {
154
+ // Use in-memory storage
155
+ const sessionData = {
156
+ id: sessionId,
157
+ swarm_id: swarmId,
158
+ swarm_name: swarmName,
159
+ objective,
160
+ status: 'active',
161
+ created_at: new Date().toISOString(),
162
+ updated_at: new Date().toISOString(),
163
+ metadata: JSON.stringify(metadata),
164
+ parent_pid: process.pid,
165
+ child_pids: '[]'
166
+ };
167
+ this.memoryStore.sessions.set(sessionId, sessionData);
168
+ }
169
+ else {
170
+ // Use SQLite
171
+ const stmt = this.db.prepare(`
172
+ INSERT INTO sessions (id, swarm_id, swarm_name, objective, metadata, parent_pid)
173
+ VALUES (?, ?, ?, ?, ?, ?)
174
+ `);
175
+ stmt.run(sessionId, swarmId, swarmName, objective, JSON.stringify(metadata), process.pid);
176
+ }
110
177
  // Log session creation
111
- this.logSessionEvent(sessionId, 'info', 'Session created', null, {
178
+ await this.logSessionEvent(sessionId, 'info', 'Session created', null, {
112
179
  swarmId,
113
180
  swarmName,
114
181
  objective,
@@ -120,20 +187,43 @@ export class HiveMindSessionManager {
120
187
  * Save session checkpoint
121
188
  */
122
189
  async saveCheckpoint(sessionId, checkpointName, checkpointData) {
190
+ await this.ensureInitialized();
123
191
  const checkpointId = `checkpoint-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
124
- // Save to database
125
- const stmt = this.db.prepare(`
126
- INSERT INTO session_checkpoints (id, session_id, checkpoint_name, checkpoint_data)
127
- VALUES (?, ?, ?, ?)
128
- `);
129
- stmt.run(checkpointId, sessionId, checkpointName, JSON.stringify(checkpointData));
130
- // Update session checkpoint data and timestamp
131
- const updateStmt = this.db.prepare(`
132
- UPDATE sessions
133
- SET checkpoint_data = ?, updated_at = CURRENT_TIMESTAMP
134
- WHERE id = ?
135
- `);
136
- updateStmt.run(JSON.stringify(checkpointData), sessionId);
192
+ if (this.isInMemory) {
193
+ // Use in-memory storage
194
+ const checkpointEntry = {
195
+ id: checkpointId,
196
+ session_id: sessionId,
197
+ checkpoint_name: checkpointName,
198
+ checkpoint_data: JSON.stringify(checkpointData),
199
+ created_at: new Date().toISOString()
200
+ };
201
+ if (!this.memoryStore.checkpoints.has(sessionId)) {
202
+ this.memoryStore.checkpoints.set(sessionId, []);
203
+ }
204
+ this.memoryStore.checkpoints.get(sessionId).push(checkpointEntry);
205
+ // Update session data
206
+ const session = this.memoryStore.sessions.get(sessionId);
207
+ if (session) {
208
+ session.checkpoint_data = JSON.stringify(checkpointData);
209
+ session.updated_at = new Date().toISOString();
210
+ }
211
+ }
212
+ else {
213
+ // Save to database
214
+ const stmt = this.db.prepare(`
215
+ INSERT INTO session_checkpoints (id, session_id, checkpoint_name, checkpoint_data)
216
+ VALUES (?, ?, ?, ?)
217
+ `);
218
+ stmt.run(checkpointId, sessionId, checkpointName, JSON.stringify(checkpointData));
219
+ // Update session checkpoint data and timestamp
220
+ const updateStmt = this.db.prepare(`
221
+ UPDATE sessions
222
+ SET checkpoint_data = ?, updated_at = CURRENT_TIMESTAMP
223
+ WHERE id = ?
224
+ `);
225
+ updateStmt.run(JSON.stringify(checkpointData), sessionId);
226
+ }
137
227
  // Save checkpoint file for backup
138
228
  const checkpointFile = path.join(this.sessionsDir, `${sessionId}-${checkpointName}.json`);
139
229
  await writeFile(checkpointFile, JSON.stringify({
@@ -143,7 +233,7 @@ export class HiveMindSessionManager {
143
233
  timestamp: new Date().toISOString(),
144
234
  data: checkpointData,
145
235
  }, null, 2));
146
- this.logSessionEvent(sessionId, 'info', `Checkpoint saved: ${checkpointName}`, null, {
236
+ await this.logSessionEvent(sessionId, 'info', `Checkpoint saved: ${checkpointName}`, null, {
147
237
  checkpointId,
148
238
  });
149
239
  return checkpointId;
@@ -151,34 +241,84 @@ export class HiveMindSessionManager {
151
241
  /**
152
242
  * Get active sessions
153
243
  */
154
- getActiveSessions() {
155
- const stmt = this.db.prepare(`
156
- SELECT s.*,
157
- COUNT(DISTINCT a.id) as agent_count,
158
- COUNT(DISTINCT t.id) as task_count,
159
- SUM(CASE WHEN t.status = 'completed' THEN 1 ELSE 0 END) as completed_tasks
160
- FROM sessions s
161
- LEFT JOIN agents a ON s.swarm_id = a.swarm_id
162
- LEFT JOIN tasks t ON s.swarm_id = t.swarm_id
163
- WHERE s.status = 'active' OR s.status = 'paused'
164
- GROUP BY s.id
165
- ORDER BY s.updated_at DESC
166
- `);
167
- const sessions = stmt.all();
168
- // Parse JSON fields
169
- return sessions.map((session) => ({
170
- ...session,
171
- metadata: session.metadata ? JSON.parse(session.metadata) : {},
172
- checkpoint_data: session.checkpoint_data ? JSON.parse(session.checkpoint_data) : null,
173
- completion_percentage: session.task_count > 0
174
- ? Math.round((session.completed_tasks / session.task_count) * 100)
175
- : 0,
176
- }));
244
+ async getActiveSessions() {
245
+ await this.ensureInitialized();
246
+ if (this.isInMemory) {
247
+ // Use in-memory storage
248
+ const sessions = [];
249
+ for (const [sessionId, session] of this.memoryStore.sessions) {
250
+ if (session.status === 'active' || session.status === 'paused') {
251
+ sessions.push({
252
+ ...session,
253
+ metadata: session.metadata ? JSON.parse(session.metadata) : {},
254
+ checkpoint_data: session.checkpoint_data ? JSON.parse(session.checkpoint_data) : null,
255
+ agent_count: 0, // Not tracked in memory mode
256
+ task_count: 0, // Not tracked in memory mode
257
+ completed_tasks: 0, // Not tracked in memory mode
258
+ completion_percentage: 0
259
+ });
260
+ }
261
+ }
262
+ return sessions.sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at));
263
+ }
264
+ else {
265
+ // Use SQLite
266
+ const stmt = this.db.prepare(`
267
+ SELECT s.*,
268
+ COUNT(DISTINCT a.id) as agent_count,
269
+ COUNT(DISTINCT t.id) as task_count,
270
+ SUM(CASE WHEN t.status = 'completed' THEN 1 ELSE 0 END) as completed_tasks
271
+ FROM sessions s
272
+ LEFT JOIN agents a ON s.swarm_id = a.swarm_id
273
+ LEFT JOIN tasks t ON s.swarm_id = t.swarm_id
274
+ WHERE s.status = 'active' OR s.status = 'paused'
275
+ GROUP BY s.id
276
+ ORDER BY s.updated_at DESC
277
+ `);
278
+ const sessions = stmt.all();
279
+ // Parse JSON fields
280
+ return sessions.map((session) => ({
281
+ ...session,
282
+ metadata: session.metadata ? JSON.parse(session.metadata) : {},
283
+ checkpoint_data: session.checkpoint_data ? JSON.parse(session.checkpoint_data) : null,
284
+ completion_percentage: session.task_count > 0
285
+ ? Math.round((session.completed_tasks / session.task_count) * 100)
286
+ : 0,
287
+ }));
288
+ }
177
289
  }
178
290
  /**
179
291
  * Get session by ID with full details
180
292
  */
181
- getSession(sessionId) {
293
+ async getSession(sessionId) {
294
+ await this.ensureInitialized();
295
+ if (this.isInMemory) {
296
+ // Use in-memory storage
297
+ const session = this.memoryStore.sessions.get(sessionId);
298
+ if (!session) {
299
+ return null;
300
+ }
301
+ // Return simplified session data for in-memory mode
302
+ return {
303
+ ...session,
304
+ metadata: session.metadata ? JSON.parse(session.metadata) : {},
305
+ checkpoint_data: session.checkpoint_data ? JSON.parse(session.checkpoint_data) : null,
306
+ swarm: null, // Not available in memory mode
307
+ agents: [], // Not available in memory mode
308
+ tasks: [], // Not available in memory mode
309
+ checkpoints: this.memoryStore.checkpoints.get(sessionId) || [],
310
+ recentLogs: this.memoryStore.logs.get(sessionId) || [],
311
+ statistics: {
312
+ totalAgents: 0,
313
+ activeAgents: 0,
314
+ totalTasks: 0,
315
+ completedTasks: 0,
316
+ pendingTasks: 0,
317
+ inProgressTasks: 0,
318
+ completionPercentage: session.completion_percentage || 0,
319
+ },
320
+ };
321
+ }
182
322
  const session = this.db
183
323
  .prepare(`
184
324
  SELECT * FROM sessions WHERE id = ?
@@ -250,24 +390,40 @@ export class HiveMindSessionManager {
250
390
  /**
251
391
  * Pause a session
252
392
  */
253
- pauseSession(sessionId) {
254
- const stmt = this.db.prepare(`
255
- UPDATE sessions
256
- SET status = 'paused', paused_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP
257
- WHERE id = ?
258
- `);
259
- const result = stmt.run(sessionId);
260
- if (result.changes > 0) {
261
- this.logSessionEvent(sessionId, 'info', 'Session paused');
262
- // Update swarm status
263
- const session = this.db.prepare('SELECT swarm_id FROM sessions WHERE id = ?').get(sessionId);
393
+ async pauseSession(sessionId) {
394
+ await this.ensureInitialized();
395
+ if (this.isInMemory) {
396
+ // Use in-memory storage
397
+ const session = this.memoryStore.sessions.get(sessionId);
264
398
  if (session) {
265
- this.db
266
- .prepare('UPDATE swarms SET status = ? WHERE id = ?')
267
- .run('paused', session.swarm_id);
399
+ session.status = 'paused';
400
+ session.paused_at = new Date().toISOString();
401
+ session.updated_at = new Date().toISOString();
402
+ await this.logSessionEvent(sessionId, 'info', 'Session paused');
403
+ return true;
268
404
  }
405
+ return false;
406
+ }
407
+ else {
408
+ // Use SQLite
409
+ const stmt = this.db.prepare(`
410
+ UPDATE sessions
411
+ SET status = 'paused', paused_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP
412
+ WHERE id = ?
413
+ `);
414
+ const result = stmt.run(sessionId);
415
+ if (result.changes > 0) {
416
+ await this.logSessionEvent(sessionId, 'info', 'Session paused');
417
+ // Update swarm status
418
+ const session = this.db.prepare('SELECT swarm_id FROM sessions WHERE id = ?').get(sessionId);
419
+ if (session) {
420
+ this.db
421
+ .prepare('UPDATE swarms SET status = ? WHERE id = ?')
422
+ .run('paused', session.swarm_id);
423
+ }
424
+ }
425
+ return result.changes > 0;
269
426
  }
270
- return result.changes > 0;
271
427
  }
272
428
  /**
273
429
  * Resume any previous session (paused, stopped, or inactive)
@@ -360,12 +516,33 @@ export class HiveMindSessionManager {
360
516
  /**
361
517
  * Log session event
362
518
  */
363
- logSessionEvent(sessionId, logLevel, message, agentId = null, data = null) {
364
- const stmt = this.db.prepare(`
365
- INSERT INTO session_logs (session_id, log_level, message, agent_id, data)
366
- VALUES (?, ?, ?, ?, ?)
367
- `);
368
- stmt.run(sessionId, logLevel, message, agentId, data ? JSON.stringify(data) : null);
519
+ async logSessionEvent(sessionId, logLevel, message, agentId = null, data = null) {
520
+ await this.ensureInitialized();
521
+ if (this.isInMemory) {
522
+ // Use in-memory storage for logs
523
+ const logId = `log-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
524
+ const logEntry = {
525
+ id: logId,
526
+ session_id: sessionId,
527
+ timestamp: new Date().toISOString(),
528
+ log_level: logLevel,
529
+ message,
530
+ agent_id: agentId,
531
+ data: data ? JSON.stringify(data) : null
532
+ };
533
+ if (!this.memoryStore.logs.has(sessionId)) {
534
+ this.memoryStore.logs.set(sessionId, []);
535
+ }
536
+ this.memoryStore.logs.get(sessionId).push(logEntry);
537
+ }
538
+ else {
539
+ // Use SQLite
540
+ const stmt = this.db.prepare(`
541
+ INSERT INTO session_logs (session_id, log_level, message, agent_id, data)
542
+ VALUES (?, ?, ?, ?, ?)
543
+ `);
544
+ stmt.run(sessionId, logLevel, message, agentId, data ? JSON.stringify(data) : null);
545
+ }
369
546
  }
370
547
  /**
371
548
  * Get session logs
@@ -386,13 +563,25 @@ export class HiveMindSessionManager {
386
563
  /**
387
564
  * Update session progress
388
565
  */
389
- updateSessionProgress(sessionId, completionPercentage) {
390
- const stmt = this.db.prepare(`
391
- UPDATE sessions
392
- SET completion_percentage = ?, updated_at = CURRENT_TIMESTAMP
393
- WHERE id = ?
394
- `);
395
- stmt.run(completionPercentage, sessionId);
566
+ async updateSessionProgress(sessionId, completionPercentage) {
567
+ await this.ensureInitialized();
568
+ if (this.isInMemory) {
569
+ // Use in-memory storage
570
+ const session = this.memoryStore.sessions.get(sessionId);
571
+ if (session) {
572
+ session.completion_percentage = completionPercentage;
573
+ session.updated_at = new Date().toISOString();
574
+ }
575
+ }
576
+ else {
577
+ // Use SQLite
578
+ const stmt = this.db.prepare(`
579
+ UPDATE sessions
580
+ SET completion_percentage = ?, updated_at = CURRENT_TIMESTAMP
581
+ WHERE id = ?
582
+ `);
583
+ stmt.run(completionPercentage, sessionId);
584
+ }
396
585
  }
397
586
  /**
398
587
  * Generate session summary
@@ -514,46 +703,68 @@ export class HiveMindSessionManager {
514
703
  /**
515
704
  * Get all child PIDs for a session
516
705
  */
517
- getChildPids(sessionId) {
518
- const session = this.db.prepare('SELECT child_pids FROM sessions WHERE id = ?').get(sessionId);
519
- if (!session || !session.child_pids)
520
- return [];
521
- return JSON.parse(session.child_pids);
706
+ async getChildPids(sessionId) {
707
+ await this.ensureInitialized();
708
+ if (this.isInMemory) {
709
+ // Use in-memory storage
710
+ const session = this.memoryStore.sessions.get(sessionId);
711
+ if (!session || !session.child_pids)
712
+ return [];
713
+ return JSON.parse(session.child_pids);
714
+ }
715
+ else {
716
+ // Use SQLite
717
+ const session = this.db.prepare('SELECT child_pids FROM sessions WHERE id = ?').get(sessionId);
718
+ if (!session || !session.child_pids)
719
+ return [];
720
+ return JSON.parse(session.child_pids);
721
+ }
522
722
  }
523
723
  /**
524
724
  * Stop a session and terminate all child processes
525
725
  */
526
726
  async stopSession(sessionId) {
527
- const session = this.getSession(sessionId);
727
+ const session = await this.getSession(sessionId);
528
728
  if (!session) {
529
729
  throw new Error(`Session ${sessionId} not found`);
530
730
  }
531
731
  // Get child PIDs
532
- const childPids = this.getChildPids(sessionId);
732
+ const childPids = await this.getChildPids(sessionId);
533
733
  // Terminate child processes
534
734
  for (const pid of childPids) {
535
735
  try {
536
736
  process.kill(pid, 'SIGTERM');
537
- this.logSessionEvent(sessionId, 'info', 'Child process terminated', null, { pid });
737
+ await this.logSessionEvent(sessionId, 'info', 'Child process terminated', null, { pid });
538
738
  }
539
739
  catch (err) {
540
740
  // Process might already be dead
541
- this.logSessionEvent(sessionId, 'warning', 'Failed to terminate child process', null, {
741
+ await this.logSessionEvent(sessionId, 'warning', 'Failed to terminate child process', null, {
542
742
  pid,
543
743
  error: err.message,
544
744
  });
545
745
  }
546
746
  }
547
747
  // Update session status
548
- const stmt = this.db.prepare(`
549
- UPDATE sessions
550
- SET status = 'stopped', updated_at = CURRENT_TIMESTAMP
551
- WHERE id = ?
552
- `);
553
- stmt.run(sessionId);
554
- // Update swarm status
555
- this.db.prepare('UPDATE swarms SET status = ? WHERE id = ?').run('stopped', session.swarm_id);
556
- this.logSessionEvent(sessionId, 'info', 'Session stopped');
748
+ if (this.isInMemory) {
749
+ // Use in-memory storage
750
+ const sessionData = this.memoryStore.sessions.get(sessionId);
751
+ if (sessionData) {
752
+ sessionData.status = 'stopped';
753
+ sessionData.updated_at = new Date().toISOString();
754
+ }
755
+ }
756
+ else {
757
+ // Use SQLite
758
+ const stmt = this.db.prepare(`
759
+ UPDATE sessions
760
+ SET status = 'stopped', updated_at = CURRENT_TIMESTAMP
761
+ WHERE id = ?
762
+ `);
763
+ stmt.run(sessionId);
764
+ // Update swarm status
765
+ this.db.prepare('UPDATE swarms SET status = ? WHERE id = ?').run('stopped', session.swarm_id);
766
+ }
767
+ await this.logSessionEvent(sessionId, 'info', 'Session stopped');
557
768
  return true;
558
769
  }
559
770
  /**
@@ -612,7 +823,9 @@ export class HiveMindSessionManager {
612
823
  * Clean up and close database connection
613
824
  */
614
825
  close() {
615
- this.db.close();
826
+ if (this.db && !this.isInMemory) {
827
+ this.db.close();
828
+ }
616
829
  }
617
830
  }
618
831
  // Export for use in other modules