claude-flow 2.7.42 → 2.7.44
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.
- package/bin/claude-flow +1 -1
- package/dist/src/cli/help-formatter.js +0 -5
- package/dist/src/cli/simple-commands/config.js +137 -119
- package/dist/src/cli/simple-commands/config.js.map +1 -1
- package/dist/src/cli/simple-commands/hive-mind.js +42 -5
- package/dist/src/cli/simple-commands/hive-mind.js.map +1 -1
- package/dist/src/cli/simple-commands/hooks.js +21 -1
- package/dist/src/cli/simple-commands/hooks.js.map +1 -1
- package/dist/src/cli/validation-helper.js.map +1 -1
- package/dist/src/core/DatabaseManager.js +19 -2
- package/dist/src/core/DatabaseManager.js.map +1 -1
- package/dist/src/memory/in-memory-store.js +1 -0
- package/dist/src/memory/in-memory-store.js.map +1 -1
- package/dist/src/memory/sqlite-wrapper.js +52 -14
- package/dist/src/memory/sqlite-wrapper.js.map +1 -1
- package/dist/src/memory/swarm-memory.js +348 -416
- package/dist/src/memory/swarm-memory.js.map +1 -1
- package/dist/src/utils/error-recovery.js +29 -0
- package/dist/src/utils/error-recovery.js.map +1 -1
- package/dist/src/utils/metrics-reader.js +0 -10
- package/package.json +1 -1
- package/src/cli/simple-commands/hooks.js +31 -1
- package/src/core/DatabaseManager.ts +27 -2
- package/src/memory/in-memory-store.js +2 -0
- package/src/memory/sqlite-wrapper.js +63 -19
- package/src/utils/error-recovery.ts +48 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/DatabaseManager.ts"],"sourcesContent":["/**\n * DatabaseManager - Manages SQLite and JSON fallback storage\n * Provides a unified interface for persistent data storage with automatic fallback\n */\n\nimport * as fs from 'fs-extra';\nimport * as path from 'path';\nimport { IDatabaseProvider } from '../types/interfaces.js';\n\nexport class DatabaseManager implements IDatabaseProvider {\n private provider: IDatabaseProvider;\n private dbType: 'sqlite' | 'json';\n private dbPath: string;\n private initialized: boolean = false;\n private retryCount: number = 0;\n private maxRetries: number = 3;\n\n constructor(dbType: 'sqlite' | 'json' = 'sqlite', dbPath?: string) {\n this.dbType = dbType;\n this.dbPath = dbPath || this.getDefaultPath();\n\n // Try SQLite first, fallback to JSON if needed\n if (this.dbType === 'sqlite') {\n this.provider = this.initializeSQLiteWithRecovery();\n } else {\n this.provider = new JSONProvider(this.dbPath);\n }\n }\n\n /**\n * Initialize SQLite with automatic error recovery\n */\n private initializeSQLiteWithRecovery(): IDatabaseProvider {\n try {\n return new SQLiteProvider(this.dbPath);\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n\n // Check if it's an npm cache error\n if (errorMsg.includes('ENOTEMPTY') || errorMsg.includes('better-sqlite3')) {\n console.warn('⚠️ SQLite initialization failed due to npm cache error');\n console.warn(' Will attempt automatic recovery during initialize()');\n } else {\n console.warn('SQLite not available, falling back to JSON storage:', error);\n }\n\n // Fallback to JSON for now\n this.provider = new JSONProvider(this.dbPath.replace('.sqlite', '.json'));\n this.dbType = 'json';\n return this.provider;\n }\n }\n\n private getDefaultPath(): string {\n const baseDir = path.join(process.cwd(), '.claude-flow');\n return this.dbType === 'sqlite'\n ? path.join(baseDir, 'database.sqlite')\n : path.join(baseDir, 'database.json');\n }\n\n async initialize(): Promise<void> {\n await fs.ensureDir(path.dirname(this.dbPath));\n\n try {\n await this.provider.initialize();\n this.initialized = true;\n } catch (error) {\n // If JSON provider failed, just propagate the error\n if (this.dbType === 'json') {\n throw error;\n }\n\n // For SQLite errors, attempt recovery\n const errorMsg = error instanceof Error ? error.message : String(error);\n if (this.retryCount < this.maxRetries) {\n console.warn(`⚠️ Database initialization failed (attempt ${this.retryCount + 1}/${this.maxRetries})`);\n console.warn(` Error: ${errorMsg}`);\n\n // Attempt to recover by switching to JSON\n console.log('🔄 Switching to JSON storage as fallback...');\n this.provider = new JSONProvider(this.dbPath.replace('.sqlite', '.json'));\n this.dbType = 'json';\n this.retryCount++;\n\n // Retry initialization with JSON provider\n await this.initialize();\n } else {\n throw error;\n }\n }\n }\n\n async store(key: string, value: any, namespace: string = 'default'): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n return this.provider.store(key, value, namespace);\n }\n\n async retrieve(key: string, namespace: string = 'default'): Promise<any> {\n if (!this.initialized) {\n await this.initialize();\n }\n return this.provider.retrieve(key, namespace);\n }\n\n async delete(key: string, namespace: string = 'default'): Promise<boolean> {\n if (!this.initialized) {\n await this.initialize();\n }\n return this.provider.delete(key, namespace);\n }\n\n async list(namespace: string = 'default'): Promise<string[]> {\n if (!this.initialized) {\n await this.initialize();\n }\n return this.provider.list(namespace);\n }\n\n async close(): Promise<void> {\n if (this.provider) {\n await this.provider.close();\n }\n this.initialized = false;\n }\n\n getDatabaseType(): 'sqlite' | 'json' {\n return this.dbType;\n }\n\n getDatabasePath(): string {\n return this.dbPath;\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n // Specialized methods for common operations\n async storeJSON(key: string, data: object, namespace?: string): Promise<void> {\n await this.store(key, JSON.stringify(data), namespace);\n }\n\n async retrieveJSON(key: string, namespace?: string): Promise<object | null> {\n const data = await this.retrieve(key, namespace);\n if (!data) return null;\n try {\n return typeof data === 'string' ? JSON.parse(data) : data;\n } catch {\n return null;\n }\n }\n\n async exists(key: string, namespace?: string): Promise<boolean> {\n const data = await this.retrieve(key, namespace);\n return data !== null && data !== undefined;\n }\n\n async clear(namespace?: string): Promise<void> {\n const keys = await this.list(namespace);\n await Promise.all(keys.map(key => this.delete(key, namespace)));\n }\n}\n\n/**\n * SQLite implementation\n */\nclass SQLiteProvider implements IDatabaseProvider {\n private db: any;\n private dbPath: string;\n\n constructor(dbPath: string) {\n this.dbPath = dbPath;\n // Dynamic import to handle optional dependency\n try {\n const Database = require('better-sqlite3');\n this.db = new Database(dbPath);\n } catch (error) {\n throw new Error('better-sqlite3 not available. Install with: npm install better-sqlite3');\n }\n }\n\n async initialize(): Promise<void> {\n // Create tables\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS storage (\n namespace TEXT NOT NULL,\n key TEXT NOT NULL,\n value TEXT NOT NULL,\n created_at INTEGER DEFAULT (strftime('%s', 'now')),\n updated_at INTEGER DEFAULT (strftime('%s', 'now')),\n PRIMARY KEY (namespace, key)\n )\n `);\n\n this.db.exec(`\n CREATE INDEX IF NOT EXISTS idx_storage_namespace ON storage(namespace);\n CREATE INDEX IF NOT EXISTS idx_storage_created_at ON storage(created_at);\n `);\n }\n\n async store(key: string, value: any, namespace: string = 'default'): Promise<void> {\n const stmt = this.db.prepare(`\n INSERT OR REPLACE INTO storage (namespace, key, value, updated_at)\n VALUES (?, ?, ?, strftime('%s', 'now'))\n `);\n\n const serializedValue = typeof value === 'string' ? value : JSON.stringify(value);\n stmt.run(namespace, key, serializedValue);\n }\n\n async retrieve(key: string, namespace: string = 'default'): Promise<any> {\n const stmt = this.db.prepare('SELECT value FROM storage WHERE namespace = ? AND key = ?');\n const row = stmt.get(namespace, key);\n\n if (!row) return null;\n\n try {\n return JSON.parse(row.value);\n } catch {\n return row.value;\n }\n }\n\n async delete(key: string, namespace: string = 'default'): Promise<boolean> {\n const stmt = this.db.prepare('DELETE FROM storage WHERE namespace = ? AND key = ?');\n const result = stmt.run(namespace, key);\n return result.changes > 0;\n }\n\n async list(namespace: string = 'default'): Promise<string[]> {\n const stmt = this.db.prepare('SELECT key FROM storage WHERE namespace = ? ORDER BY key');\n const rows = stmt.all(namespace);\n return rows.map((row: any) => row.key);\n }\n\n async close(): Promise<void> {\n if (this.db) {\n this.db.close();\n }\n }\n}\n\n/**\n * JSON file-based implementation\n */\nclass JSONProvider implements IDatabaseProvider {\n private data: Record<string, Record<string, any>> = {};\n private dbPath: string;\n\n constructor(dbPath: string) {\n this.dbPath = dbPath;\n }\n\n async initialize(): Promise<void> {\n try {\n if (await fs.pathExists(this.dbPath)) {\n const content = await fs.readJSON(this.dbPath);\n this.data = content || {};\n }\n } catch (error) {\n console.warn('Failed to load JSON database, starting fresh:', error);\n this.data = {};\n }\n }\n\n async store(key: string, value: any, namespace: string = 'default'): Promise<void> {\n if (!this.data[namespace]) {\n this.data[namespace] = {};\n }\n\n this.data[namespace][key] = value;\n await this.persist();\n }\n\n async retrieve(key: string, namespace: string = 'default'): Promise<any> {\n if (!this.data[namespace]) {\n return null;\n }\n return this.data[namespace][key] || null;\n }\n\n async delete(key: string, namespace: string = 'default'): Promise<boolean> {\n if (!this.data[namespace] || !(key in this.data[namespace])) {\n return false;\n }\n\n delete this.data[namespace][key];\n await this.persist();\n return true;\n }\n\n async list(namespace: string = 'default'): Promise<string[]> {\n if (!this.data[namespace]) {\n return [];\n }\n return Object.keys(this.data[namespace]).sort();\n }\n\n async close(): Promise<void> {\n await this.persist();\n }\n\n private async persist(): Promise<void> {\n try {\n await fs.ensureDir(path.dirname(this.dbPath));\n await fs.writeJSON(this.dbPath, this.data, { spaces: 2 });\n } catch (error) {\n console.error('Failed to persist JSON database:', error);\n }\n }\n}"],"names":["fs","path","DatabaseManager","provider","dbType","dbPath","initialized","retryCount","maxRetries","getDefaultPath","initializeSQLiteWithRecovery","JSONProvider","SQLiteProvider","error","errorMsg","Error","message","String","includes","console","warn","replace","baseDir","join","process","cwd","initialize","ensureDir","dirname","log","store","key","value","namespace","retrieve","delete","list","close","getDatabaseType","getDatabasePath","isInitialized","storeJSON","data","JSON","stringify","retrieveJSON","parse","exists","undefined","clear","keys","Promise","all","map","db","Database","require","exec","stmt","prepare","serializedValue","run","row","get","result","changes","rows","pathExists","content","readJSON","persist","Object","sort","writeJSON","spaces"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/DatabaseManager.ts"],"sourcesContent":["/**\n * DatabaseManager - Manages SQLite and JSON fallback storage\n * Provides a unified interface for persistent data storage with automatic fallback\n */\n\nimport * as fs from 'fs-extra';\nimport * as path from 'path';\nimport { IDatabaseProvider } from '../types/interfaces.js';\nimport { isNativeModuleVersionError, getNativeModuleRecoveryMessage } from '../utils/error-recovery.js';\n\n/**\n * Custom error class for native module issues\n */\nexport class NativeModuleError extends Error {\n public readonly originalError: Error;\n public readonly isNativeModuleError = true;\n\n constructor(message: string, originalError: Error) {\n super(message);\n this.name = 'NativeModuleError';\n this.originalError = originalError;\n }\n}\n\nexport class DatabaseManager implements IDatabaseProvider {\n private provider: IDatabaseProvider;\n private dbType: 'sqlite' | 'json';\n private dbPath: string;\n private initialized: boolean = false;\n private retryCount: number = 0;\n private maxRetries: number = 3;\n\n constructor(dbType: 'sqlite' | 'json' = 'sqlite', dbPath?: string) {\n this.dbType = dbType;\n this.dbPath = dbPath || this.getDefaultPath();\n\n // Try SQLite first, fallback to JSON if needed\n if (this.dbType === 'sqlite') {\n this.provider = this.initializeSQLiteWithRecovery();\n } else {\n this.provider = new JSONProvider(this.dbPath);\n }\n }\n\n /**\n * Initialize SQLite with automatic error recovery\n */\n private initializeSQLiteWithRecovery(): IDatabaseProvider {\n try {\n return new SQLiteProvider(this.dbPath);\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n\n // Check for native module version mismatch (NODE_MODULE_VERSION error)\n if (error instanceof NativeModuleError || isNativeModuleVersionError(error)) {\n console.warn('\\n' + (error instanceof NativeModuleError ? error.message : getNativeModuleRecoveryMessage(error)));\n console.warn(' Falling back to JSON storage (no data loss, just slower).\\n');\n }\n // Check if it's an npm cache error\n else if (errorMsg.includes('ENOTEMPTY') || errorMsg.includes('better-sqlite3')) {\n console.warn('⚠️ SQLite initialization failed due to npm cache error');\n console.warn(' Will attempt automatic recovery during initialize()');\n } else {\n console.warn('SQLite not available, falling back to JSON storage:', errorMsg);\n }\n\n // Fallback to JSON for now\n this.provider = new JSONProvider(this.dbPath.replace('.sqlite', '.json'));\n this.dbType = 'json';\n return this.provider;\n }\n }\n\n private getDefaultPath(): string {\n const baseDir = path.join(process.cwd(), '.claude-flow');\n return this.dbType === 'sqlite'\n ? path.join(baseDir, 'database.sqlite')\n : path.join(baseDir, 'database.json');\n }\n\n async initialize(): Promise<void> {\n await fs.ensureDir(path.dirname(this.dbPath));\n\n try {\n await this.provider.initialize();\n this.initialized = true;\n } catch (error) {\n // If JSON provider failed, just propagate the error\n if (this.dbType === 'json') {\n throw error;\n }\n\n // For SQLite errors, attempt recovery\n const errorMsg = error instanceof Error ? error.message : String(error);\n if (this.retryCount < this.maxRetries) {\n console.warn(`⚠️ Database initialization failed (attempt ${this.retryCount + 1}/${this.maxRetries})`);\n console.warn(` Error: ${errorMsg}`);\n\n // Attempt to recover by switching to JSON\n console.log('🔄 Switching to JSON storage as fallback...');\n this.provider = new JSONProvider(this.dbPath.replace('.sqlite', '.json'));\n this.dbType = 'json';\n this.retryCount++;\n\n // Retry initialization with JSON provider\n await this.initialize();\n } else {\n throw error;\n }\n }\n }\n\n async store(key: string, value: any, namespace: string = 'default'): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n return this.provider.store(key, value, namespace);\n }\n\n async retrieve(key: string, namespace: string = 'default'): Promise<any> {\n if (!this.initialized) {\n await this.initialize();\n }\n return this.provider.retrieve(key, namespace);\n }\n\n async delete(key: string, namespace: string = 'default'): Promise<boolean> {\n if (!this.initialized) {\n await this.initialize();\n }\n return this.provider.delete(key, namespace);\n }\n\n async list(namespace: string = 'default'): Promise<string[]> {\n if (!this.initialized) {\n await this.initialize();\n }\n return this.provider.list(namespace);\n }\n\n async close(): Promise<void> {\n if (this.provider) {\n await this.provider.close();\n }\n this.initialized = false;\n }\n\n getDatabaseType(): 'sqlite' | 'json' {\n return this.dbType;\n }\n\n getDatabasePath(): string {\n return this.dbPath;\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n // Specialized methods for common operations\n async storeJSON(key: string, data: object, namespace?: string): Promise<void> {\n await this.store(key, JSON.stringify(data), namespace);\n }\n\n async retrieveJSON(key: string, namespace?: string): Promise<object | null> {\n const data = await this.retrieve(key, namespace);\n if (!data) return null;\n try {\n return typeof data === 'string' ? JSON.parse(data) : data;\n } catch {\n return null;\n }\n }\n\n async exists(key: string, namespace?: string): Promise<boolean> {\n const data = await this.retrieve(key, namespace);\n return data !== null && data !== undefined;\n }\n\n async clear(namespace?: string): Promise<void> {\n const keys = await this.list(namespace);\n await Promise.all(keys.map(key => this.delete(key, namespace)));\n }\n}\n\n/**\n * SQLite implementation\n */\nclass SQLiteProvider implements IDatabaseProvider {\n private db: any;\n private dbPath: string;\n\n constructor(dbPath: string) {\n this.dbPath = dbPath;\n // Dynamic import to handle optional dependency\n try {\n const Database = require('better-sqlite3');\n this.db = new Database(dbPath);\n } catch (error) {\n // Check for native module version mismatch (NODE_MODULE_VERSION error)\n if (isNativeModuleVersionError(error)) {\n const recoveryMsg = getNativeModuleRecoveryMessage(error);\n throw new NativeModuleError(recoveryMsg, error as Error);\n }\n throw new Error('better-sqlite3 not available. Install with: npm install better-sqlite3');\n }\n }\n\n async initialize(): Promise<void> {\n // Create tables\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS storage (\n namespace TEXT NOT NULL,\n key TEXT NOT NULL,\n value TEXT NOT NULL,\n created_at INTEGER DEFAULT (strftime('%s', 'now')),\n updated_at INTEGER DEFAULT (strftime('%s', 'now')),\n PRIMARY KEY (namespace, key)\n )\n `);\n\n this.db.exec(`\n CREATE INDEX IF NOT EXISTS idx_storage_namespace ON storage(namespace);\n CREATE INDEX IF NOT EXISTS idx_storage_created_at ON storage(created_at);\n `);\n }\n\n async store(key: string, value: any, namespace: string = 'default'): Promise<void> {\n const stmt = this.db.prepare(`\n INSERT OR REPLACE INTO storage (namespace, key, value, updated_at)\n VALUES (?, ?, ?, strftime('%s', 'now'))\n `);\n\n const serializedValue = typeof value === 'string' ? value : JSON.stringify(value);\n stmt.run(namespace, key, serializedValue);\n }\n\n async retrieve(key: string, namespace: string = 'default'): Promise<any> {\n const stmt = this.db.prepare('SELECT value FROM storage WHERE namespace = ? AND key = ?');\n const row = stmt.get(namespace, key);\n\n if (!row) return null;\n\n try {\n return JSON.parse(row.value);\n } catch {\n return row.value;\n }\n }\n\n async delete(key: string, namespace: string = 'default'): Promise<boolean> {\n const stmt = this.db.prepare('DELETE FROM storage WHERE namespace = ? AND key = ?');\n const result = stmt.run(namespace, key);\n return result.changes > 0;\n }\n\n async list(namespace: string = 'default'): Promise<string[]> {\n const stmt = this.db.prepare('SELECT key FROM storage WHERE namespace = ? ORDER BY key');\n const rows = stmt.all(namespace);\n return rows.map((row: any) => row.key);\n }\n\n async close(): Promise<void> {\n if (this.db) {\n this.db.close();\n }\n }\n}\n\n/**\n * JSON file-based implementation\n */\nclass JSONProvider implements IDatabaseProvider {\n private data: Record<string, Record<string, any>> = {};\n private dbPath: string;\n\n constructor(dbPath: string) {\n this.dbPath = dbPath;\n }\n\n async initialize(): Promise<void> {\n try {\n if (await fs.pathExists(this.dbPath)) {\n const content = await fs.readJSON(this.dbPath);\n this.data = content || {};\n }\n } catch (error) {\n console.warn('Failed to load JSON database, starting fresh:', error);\n this.data = {};\n }\n }\n\n async store(key: string, value: any, namespace: string = 'default'): Promise<void> {\n if (!this.data[namespace]) {\n this.data[namespace] = {};\n }\n\n this.data[namespace][key] = value;\n await this.persist();\n }\n\n async retrieve(key: string, namespace: string = 'default'): Promise<any> {\n if (!this.data[namespace]) {\n return null;\n }\n return this.data[namespace][key] || null;\n }\n\n async delete(key: string, namespace: string = 'default'): Promise<boolean> {\n if (!this.data[namespace] || !(key in this.data[namespace])) {\n return false;\n }\n\n delete this.data[namespace][key];\n await this.persist();\n return true;\n }\n\n async list(namespace: string = 'default'): Promise<string[]> {\n if (!this.data[namespace]) {\n return [];\n }\n return Object.keys(this.data[namespace]).sort();\n }\n\n async close(): Promise<void> {\n await this.persist();\n }\n\n private async persist(): Promise<void> {\n try {\n await fs.ensureDir(path.dirname(this.dbPath));\n await fs.writeJSON(this.dbPath, this.data, { spaces: 2 });\n } catch (error) {\n console.error('Failed to persist JSON database:', error);\n }\n }\n}"],"names":["fs","path","isNativeModuleVersionError","getNativeModuleRecoveryMessage","NativeModuleError","Error","originalError","isNativeModuleError","message","name","DatabaseManager","provider","dbType","dbPath","initialized","retryCount","maxRetries","getDefaultPath","initializeSQLiteWithRecovery","JSONProvider","SQLiteProvider","error","errorMsg","String","console","warn","includes","replace","baseDir","join","process","cwd","initialize","ensureDir","dirname","log","store","key","value","namespace","retrieve","delete","list","close","getDatabaseType","getDatabasePath","isInitialized","storeJSON","data","JSON","stringify","retrieveJSON","parse","exists","undefined","clear","keys","Promise","all","map","db","Database","require","recoveryMsg","exec","stmt","prepare","serializedValue","run","row","get","result","changes","rows","pathExists","content","readJSON","persist","Object","sort","writeJSON","spaces"],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ let InMemoryStore = class InMemoryStore {
|
|
|
12
12
|
this.cleanupInterval = setInterval(()=>{
|
|
13
13
|
this.cleanup().catch((err)=>console.error(`[${new Date().toISOString()}] ERROR [in-memory-store] Cleanup failed:`, err));
|
|
14
14
|
}, 60000);
|
|
15
|
+
this.cleanupInterval.unref();
|
|
15
16
|
this.isInitialized = true;
|
|
16
17
|
console.error(`[${new Date().toISOString()}] INFO [in-memory-store] Initialized in-memory store`);
|
|
17
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/memory/in-memory-store.js"],"sourcesContent":["/**\n * In-memory store for environments where SQLite is not available\n * Provides the same API as SQLite store but data is not persistent\n */\n\nimport { sessionSerializer } from './enhanced-session-serializer.js';\n\nclass InMemoryStore {\n constructor(options = {}) {\n this.options = options;\n this.data = new Map(); // namespace -> Map(key -> entry)\n this.isInitialized = false;\n this.cleanupInterval = null;\n }\n\n async initialize() {\n if (this.isInitialized) return;\n\n // Initialize default namespace\n this.data.set('default', new Map());\n\n // Start cleanup interval for expired entries\n this.cleanupInterval = setInterval(() => {\n this.cleanup().catch((err) =>\n console.error(`[${new Date().toISOString()}] ERROR [in-memory-store] Cleanup failed:`, err),\n );\n }, 60000); // Run cleanup every minute\n\n this.isInitialized = true;\n console.error(\n `[${new Date().toISOString()}] INFO [in-memory-store] Initialized in-memory store`,\n );\n }\n\n _getNamespaceMap(namespace) {\n if (!this.data.has(namespace)) {\n this.data.set(namespace, new Map());\n }\n return this.data.get(namespace);\n }\n\n async store(key, value, options = {}) {\n await this.initialize();\n\n const namespace = options.namespace || 'default';\n const namespaceMap = this._getNamespaceMap(namespace);\n\n const now = Date.now();\n const ttl = options.ttl || null;\n const expiresAt = ttl ? now + ttl * 1000 : null;\n const valueStr = typeof value === 'string' ? value : sessionSerializer.serializer.serialize(value);\n\n const entry = {\n key,\n value: valueStr,\n namespace,\n metadata: options.metadata || null,\n createdAt: namespaceMap.has(key) ? namespaceMap.get(key).createdAt : now,\n updatedAt: now,\n accessedAt: now,\n accessCount: namespaceMap.has(key) ? namespaceMap.get(key).accessCount + 1 : 1,\n ttl,\n expiresAt,\n };\n\n namespaceMap.set(key, entry);\n\n return {\n success: true,\n id: `${namespace}:${key}`,\n size: valueStr.length,\n };\n }\n\n async retrieve(key, options = {}) {\n await this.initialize();\n\n const namespace = options.namespace || 'default';\n const namespaceMap = this._getNamespaceMap(namespace);\n\n const entry = namespaceMap.get(key);\n\n if (!entry) {\n return null;\n }\n\n // Check if expired\n if (entry.expiresAt && entry.expiresAt < Date.now()) {\n namespaceMap.delete(key);\n return null;\n }\n\n // Update access stats\n entry.accessedAt = Date.now();\n entry.accessCount++;\n\n // Try to deserialize, fall back to raw string\n try {\n return sessionSerializer.serializer.deserialize(entry.value);\n } catch {\n return entry.value;\n }\n }\n\n async list(options = {}) {\n await this.initialize();\n\n const namespace = options.namespace || 'default';\n const limit = options.limit || 100;\n const namespaceMap = this._getNamespaceMap(namespace);\n\n const entries = Array.from(namespaceMap.values())\n .filter((entry) => !entry.expiresAt || entry.expiresAt > Date.now())\n .sort((a, b) => b.updatedAt - a.updatedAt)\n .slice(0, limit);\n\n return entries.map((entry) => ({\n key: entry.key,\n value: this._tryParseJson(entry.value),\n namespace: entry.namespace,\n metadata: entry.metadata,\n createdAt: new Date(entry.createdAt),\n updatedAt: new Date(entry.updatedAt),\n accessCount: entry.accessCount,\n }));\n }\n\n async delete(key, options = {}) {\n await this.initialize();\n\n const namespace = options.namespace || 'default';\n const namespaceMap = this._getNamespaceMap(namespace);\n\n return namespaceMap.delete(key);\n }\n\n async search(pattern, options = {}) {\n await this.initialize();\n\n const namespace = options.namespace || 'default';\n const limit = options.limit || 50;\n const namespaceMap = this._getNamespaceMap(namespace);\n\n const searchLower = pattern.toLowerCase();\n const results = [];\n\n for (const [key, entry] of namespaceMap.entries()) {\n // Skip expired entries\n if (entry.expiresAt && entry.expiresAt < Date.now()) {\n continue;\n }\n\n // Search in key and value\n if (\n key.toLowerCase().includes(searchLower) ||\n entry.value.toLowerCase().includes(searchLower)\n ) {\n results.push({\n key: entry.key,\n value: this._tryParseJson(entry.value),\n namespace: entry.namespace,\n score: entry.accessCount,\n updatedAt: new Date(entry.updatedAt),\n });\n }\n\n if (results.length >= limit) {\n break;\n }\n }\n\n // Sort by score (access count) and updated time\n return results.sort((a, b) => {\n if (a.score !== b.score) return b.score - a.score;\n return b.updatedAt - a.updatedAt;\n });\n }\n\n async cleanup() {\n await this.initialize();\n\n let cleaned = 0;\n const now = Date.now();\n\n for (const [namespace, namespaceMap] of this.data.entries()) {\n for (const [key, entry] of namespaceMap.entries()) {\n if (entry.expiresAt && entry.expiresAt <= now) {\n namespaceMap.delete(key);\n cleaned++;\n }\n }\n }\n\n return cleaned;\n }\n\n _tryParseJson(value) {\n try {\n return sessionSerializer.serializer.deserialize(value);\n } catch {\n return value;\n }\n }\n\n close() {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = null;\n }\n this.data.clear();\n this.isInitialized = false;\n }\n}\n\nexport { InMemoryStore };\nexport default InMemoryStore;\n"],"names":["sessionSerializer","InMemoryStore","options","data","Map","isInitialized","cleanupInterval","initialize","set","setInterval","cleanup","catch","err","console","error","Date","toISOString","_getNamespaceMap","namespace","has","get","store","key","value","namespaceMap","now","ttl","expiresAt","valueStr","serializer","serialize","entry","metadata","createdAt","updatedAt","accessedAt","accessCount","success","id","size","length","retrieve","delete","deserialize","list","limit","entries","Array","from","values","filter","sort","a","b","slice","map","_tryParseJson","search","pattern","searchLower","toLowerCase","results","includes","push","score","cleaned","close","clearInterval","clear"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/memory/in-memory-store.js"],"sourcesContent":["/**\n * In-memory store for environments where SQLite is not available\n * Provides the same API as SQLite store but data is not persistent\n */\n\nimport { sessionSerializer } from './enhanced-session-serializer.js';\n\nclass InMemoryStore {\n constructor(options = {}) {\n this.options = options;\n this.data = new Map(); // namespace -> Map(key -> entry)\n this.isInitialized = false;\n this.cleanupInterval = null;\n }\n\n async initialize() {\n if (this.isInitialized) return;\n\n // Initialize default namespace\n this.data.set('default', new Map());\n\n // Start cleanup interval for expired entries\n // Use unref() so the interval doesn't prevent process exit\n this.cleanupInterval = setInterval(() => {\n this.cleanup().catch((err) =>\n console.error(`[${new Date().toISOString()}] ERROR [in-memory-store] Cleanup failed:`, err),\n );\n }, 60000); // Run cleanup every minute\n this.cleanupInterval.unref(); // Don't keep process alive just for cleanup\n\n this.isInitialized = true;\n console.error(\n `[${new Date().toISOString()}] INFO [in-memory-store] Initialized in-memory store`,\n );\n }\n\n _getNamespaceMap(namespace) {\n if (!this.data.has(namespace)) {\n this.data.set(namespace, new Map());\n }\n return this.data.get(namespace);\n }\n\n async store(key, value, options = {}) {\n await this.initialize();\n\n const namespace = options.namespace || 'default';\n const namespaceMap = this._getNamespaceMap(namespace);\n\n const now = Date.now();\n const ttl = options.ttl || null;\n const expiresAt = ttl ? now + ttl * 1000 : null;\n const valueStr = typeof value === 'string' ? value : sessionSerializer.serializer.serialize(value);\n\n const entry = {\n key,\n value: valueStr,\n namespace,\n metadata: options.metadata || null,\n createdAt: namespaceMap.has(key) ? namespaceMap.get(key).createdAt : now,\n updatedAt: now,\n accessedAt: now,\n accessCount: namespaceMap.has(key) ? namespaceMap.get(key).accessCount + 1 : 1,\n ttl,\n expiresAt,\n };\n\n namespaceMap.set(key, entry);\n\n return {\n success: true,\n id: `${namespace}:${key}`,\n size: valueStr.length,\n };\n }\n\n async retrieve(key, options = {}) {\n await this.initialize();\n\n const namespace = options.namespace || 'default';\n const namespaceMap = this._getNamespaceMap(namespace);\n\n const entry = namespaceMap.get(key);\n\n if (!entry) {\n return null;\n }\n\n // Check if expired\n if (entry.expiresAt && entry.expiresAt < Date.now()) {\n namespaceMap.delete(key);\n return null;\n }\n\n // Update access stats\n entry.accessedAt = Date.now();\n entry.accessCount++;\n\n // Try to deserialize, fall back to raw string\n try {\n return sessionSerializer.serializer.deserialize(entry.value);\n } catch {\n return entry.value;\n }\n }\n\n async list(options = {}) {\n await this.initialize();\n\n const namespace = options.namespace || 'default';\n const limit = options.limit || 100;\n const namespaceMap = this._getNamespaceMap(namespace);\n\n const entries = Array.from(namespaceMap.values())\n .filter((entry) => !entry.expiresAt || entry.expiresAt > Date.now())\n .sort((a, b) => b.updatedAt - a.updatedAt)\n .slice(0, limit);\n\n return entries.map((entry) => ({\n key: entry.key,\n value: this._tryParseJson(entry.value),\n namespace: entry.namespace,\n metadata: entry.metadata,\n createdAt: new Date(entry.createdAt),\n updatedAt: new Date(entry.updatedAt),\n accessCount: entry.accessCount,\n }));\n }\n\n async delete(key, options = {}) {\n await this.initialize();\n\n const namespace = options.namespace || 'default';\n const namespaceMap = this._getNamespaceMap(namespace);\n\n return namespaceMap.delete(key);\n }\n\n async search(pattern, options = {}) {\n await this.initialize();\n\n const namespace = options.namespace || 'default';\n const limit = options.limit || 50;\n const namespaceMap = this._getNamespaceMap(namespace);\n\n const searchLower = pattern.toLowerCase();\n const results = [];\n\n for (const [key, entry] of namespaceMap.entries()) {\n // Skip expired entries\n if (entry.expiresAt && entry.expiresAt < Date.now()) {\n continue;\n }\n\n // Search in key and value\n if (\n key.toLowerCase().includes(searchLower) ||\n entry.value.toLowerCase().includes(searchLower)\n ) {\n results.push({\n key: entry.key,\n value: this._tryParseJson(entry.value),\n namespace: entry.namespace,\n score: entry.accessCount,\n updatedAt: new Date(entry.updatedAt),\n });\n }\n\n if (results.length >= limit) {\n break;\n }\n }\n\n // Sort by score (access count) and updated time\n return results.sort((a, b) => {\n if (a.score !== b.score) return b.score - a.score;\n return b.updatedAt - a.updatedAt;\n });\n }\n\n async cleanup() {\n await this.initialize();\n\n let cleaned = 0;\n const now = Date.now();\n\n for (const [namespace, namespaceMap] of this.data.entries()) {\n for (const [key, entry] of namespaceMap.entries()) {\n if (entry.expiresAt && entry.expiresAt <= now) {\n namespaceMap.delete(key);\n cleaned++;\n }\n }\n }\n\n return cleaned;\n }\n\n _tryParseJson(value) {\n try {\n return sessionSerializer.serializer.deserialize(value);\n } catch {\n return value;\n }\n }\n\n close() {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = null;\n }\n this.data.clear();\n this.isInitialized = false;\n }\n}\n\nexport { InMemoryStore };\nexport default InMemoryStore;\n"],"names":["sessionSerializer","InMemoryStore","options","data","Map","isInitialized","cleanupInterval","initialize","set","setInterval","cleanup","catch","err","console","error","Date","toISOString","unref","_getNamespaceMap","namespace","has","get","store","key","value","namespaceMap","now","ttl","expiresAt","valueStr","serializer","serialize","entry","metadata","createdAt","updatedAt","accessedAt","accessCount","success","id","size","length","retrieve","delete","deserialize","list","limit","entries","Array","from","values","filter","sort","a","b","slice","map","_tryParseJson","search","pattern","searchLower","toLowerCase","results","includes","push","score","cleaned","close","clearInterval","clear"],"mappings":"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"}
|
|
@@ -20,29 +20,67 @@ async function tryLoadSQLite() {
|
|
|
20
20
|
return true;
|
|
21
21
|
} catch (importErr) {
|
|
22
22
|
loadError = importErr;
|
|
23
|
-
|
|
23
|
+
const isVersionMismatch = requireErr.message?.includes('NODE_MODULE_VERSION') || importErr.message?.includes('NODE_MODULE_VERSION') || requireErr.message?.includes('was compiled against a different Node.js version') || importErr.message?.includes('was compiled against a different Node.js version');
|
|
24
|
+
if (isVersionMismatch) {
|
|
25
|
+
const errorMsg = requireErr.message || importErr.message || '';
|
|
26
|
+
const compiledMatch = errorMsg.match(/NODE_MODULE_VERSION (\d+)/);
|
|
27
|
+
const requiredMatch = errorMsg.match(/requires\s+NODE_MODULE_VERSION (\d+)/);
|
|
28
|
+
const nodeVersionMap = {
|
|
29
|
+
'108': '18.x',
|
|
30
|
+
'115': '20.x',
|
|
31
|
+
'120': '21.x',
|
|
32
|
+
'127': '22.x',
|
|
33
|
+
'131': '23.x'
|
|
34
|
+
};
|
|
35
|
+
let versionInfo = '';
|
|
36
|
+
if (compiledMatch && requiredMatch) {
|
|
37
|
+
const compiled = nodeVersionMap[compiledMatch[1]] || `ABI ${compiledMatch[1]}`;
|
|
38
|
+
const required = nodeVersionMap[requiredMatch[1]] || `ABI ${requiredMatch[1]}`;
|
|
39
|
+
versionInfo = `\n║ Module compiled for Node.js ${compiled}, running Node.js ${required}`.padEnd(79) + '║';
|
|
40
|
+
}
|
|
24
41
|
console.warn(`
|
|
25
42
|
╔══════════════════════════════════════════════════════════════════════════════╗
|
|
26
|
-
║
|
|
43
|
+
║ Native Module Version Mismatch (NODE_MODULE_VERSION) ║
|
|
27
44
|
╠══════════════════════════════════════════════════════════════════════════════╣
|
|
28
45
|
║ ║
|
|
29
|
-
║ The
|
|
30
|
-
║
|
|
46
|
+
║ The better-sqlite3 module was compiled for a different Node.js version. ║${versionInfo}
|
|
47
|
+
║ ║
|
|
48
|
+
║ Claude Flow will continue with JSON fallback storage (still works fine). ║
|
|
49
|
+
║ ║
|
|
50
|
+
║ To fix this and use SQLite: ║
|
|
51
|
+
║ ║
|
|
52
|
+
║ Option 1 - Rebuild the module: ║
|
|
53
|
+
║ > npm rebuild better-sqlite3 ║
|
|
54
|
+
║ ║
|
|
55
|
+
║ Option 2 - Clear npx cache (if using npx): ║
|
|
56
|
+
║ > rm -rf ~/.npm/_npx/ && npx claude-flow@alpha ... ║
|
|
57
|
+
║ ║
|
|
58
|
+
║ Option 3 - Reinstall dependencies: ║
|
|
59
|
+
║ > rm -rf node_modules && npm install ║
|
|
60
|
+
║ ║
|
|
61
|
+
╚══════════════════════════════════════════════════════════════════════════════╝
|
|
62
|
+
`);
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
if (requireErr.message?.includes('Could not locate the bindings file') || requireErr.message?.includes('The specified module could not be found') || requireErr.code === 'MODULE_NOT_FOUND') {
|
|
66
|
+
console.warn(`
|
|
67
|
+
╔══════════════════════════════════════════════════════════════════════════════╗
|
|
68
|
+
║ SQLite Native Module Installation Issue ║
|
|
69
|
+
╠══════════════════════════════════════════════════════════════════════════════╣
|
|
31
70
|
║ ║
|
|
32
|
-
║
|
|
71
|
+
║ The native SQLite module failed to load. This is common on Windows when ║
|
|
72
|
+
║ using 'npx' or when node-gyp build tools are not available. ║
|
|
33
73
|
║ ║
|
|
34
|
-
║
|
|
74
|
+
║ Claude Flow will continue with JSON fallback storage (still works fine). ║
|
|
35
75
|
║ ║
|
|
36
|
-
║
|
|
37
|
-
║ > npm install --global windows-build-tools ║
|
|
38
|
-
║ > npm install claude-flow@alpha ║
|
|
76
|
+
║ To enable SQLite storage: ║
|
|
39
77
|
║ ║
|
|
40
|
-
║ Option
|
|
41
|
-
║ > npm
|
|
42
|
-
║ > npm install claude-flow@alpha
|
|
78
|
+
║ Option 1 - Install Build Tools (Windows): ║
|
|
79
|
+
║ > npm install --global windows-build-tools ║
|
|
80
|
+
║ > npm install claude-flow@alpha ║
|
|
43
81
|
║ ║
|
|
44
|
-
║ Option
|
|
45
|
-
║ Install WSL and run Claude Flow inside a Linux environment
|
|
82
|
+
║ Option 2 - Use WSL (Windows Subsystem for Linux): ║
|
|
83
|
+
║ Install WSL and run Claude Flow inside a Linux environment ║
|
|
46
84
|
║ ║
|
|
47
85
|
╚══════════════════════════════════════════════════════════════════════════════╝
|
|
48
86
|
`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/memory/sqlite-wrapper.js"],"sourcesContent":["/**\n * SQLite Wrapper with Windows Fallback Support\n * Provides graceful fallback when better-sqlite3 fails to load\n */\n\nimport { createRequire } from 'module';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nlet Database = null;\nlet sqliteAvailable = false;\nlet loadError = null;\n\n/**\n * Try to load better-sqlite3 with comprehensive error handling\n */\nasync function tryLoadSQLite() {\n try {\n // Try CommonJS require first (more reliable in Node.js)\n const require = createRequire(import.meta.url);\n Database = require('better-sqlite3');\n sqliteAvailable = true;\n return true;\n } catch (requireErr) {\n // Fallback to ES module import\n try {\n const module = await import('better-sqlite3');\n Database = module.default;\n sqliteAvailable = true;\n return true;\n } catch (importErr) {\n loadError = importErr;\n \n // Check for specific Windows errors\n if (requireErr.message.includes('was compiled against a different Node.js version') ||\n requireErr.message.includes('Could not locate the bindings file') ||\n requireErr.message.includes('The specified module could not be found') ||\n requireErr.code === 'MODULE_NOT_FOUND') {\n \n console.warn(`\n╔══════════════════════════════════════════════════════════════════════════════╗\n║ Windows SQLite Installation Issue ║\n╠══════════════════════════════════════════════════════════════════════════════╣\n║ ║\n║ The native SQLite module failed to load. This is common on Windows when ║\n║ using 'npx' or when node-gyp build tools are not available. ║\n║ ║\n║ Claude Flow will continue with in-memory storage (non-persistent). ║\n║ ║\n║ To enable persistent storage on Windows: ║\n║ ║\n║ Option 1 - Install Windows Build Tools: ║\n║ > npm install --global windows-build-tools ║\n║ > npm install claude-flow@alpha ║\n║ ║\n║ Option 2 - Use Pre-built Binaries: ║\n║ > npm config set python python3 ║\n║ > npm install claude-flow@alpha --build-from-source=false ║\n║ ║\n║ Option 3 - Use WSL (Windows Subsystem for Linux): ║\n║ Install WSL and run Claude Flow inside a Linux environment ║\n║ ║\n╚══════════════════════════════════════════════════════════════════════════════╝\n`);\n }\n \n return false;\n }\n }\n}\n\n/**\n * Check if SQLite is available\n */\nexport async function isSQLiteAvailable() {\n if (sqliteAvailable !== null) {\n return sqliteAvailable;\n }\n \n await tryLoadSQLite();\n return sqliteAvailable;\n}\n\n/**\n * Get SQLite Database constructor or null\n */\nexport async function getSQLiteDatabase() {\n if (!sqliteAvailable && loadError === null) {\n await tryLoadSQLite();\n }\n \n return Database;\n}\n\n/**\n * Get the load error if any\n */\nexport function getLoadError() {\n return loadError;\n}\n\n/**\n * Create a SQLite database instance with fallback\n */\nexport async function createDatabase(dbPath) {\n const DB = await getSQLiteDatabase();\n \n if (!DB) {\n throw new Error('SQLite is not available. Use fallback storage instead.');\n }\n \n try {\n return new DB(dbPath);\n } catch (err) {\n // Additional Windows-specific error handling\n if (err.message.includes('EPERM') || err.message.includes('access denied')) {\n throw new Error(`Cannot create database at ${dbPath}. Permission denied. Try using a different directory or running with administrator privileges.`);\n }\n throw err;\n }\n}\n\n/**\n * Check if running on Windows\n */\nexport function isWindows() {\n return process.platform === 'win32';\n}\n\n/**\n * Get platform-specific storage recommendations\n */\nexport function getStorageRecommendations() {\n if (isWindows()) {\n return {\n recommended: 'in-memory',\n reason: 'Windows native module compatibility',\n alternatives: [\n 'Install Windows build tools for SQLite support',\n 'Use WSL (Windows Subsystem for Linux)',\n 'Use Docker container with Linux'\n ]\n };\n }\n \n return {\n recommended: 'sqlite',\n reason: 'Best performance and persistence',\n alternatives: ['in-memory for testing']\n };\n}\n\n// Pre-load SQLite on module import\ntryLoadSQLite().catch(() => {\n // Silently handle initial load failure\n});\n\nexport default {\n isSQLiteAvailable,\n getSQLiteDatabase,\n getLoadError,\n createDatabase,\n isWindows,\n getStorageRecommendations\n};"],"names":["createRequire","path","fileURLToPath","__filename","url","__dirname","dirname","Database","sqliteAvailable","loadError","tryLoadSQLite","require","requireErr","module","default","importErr","message","includes","code","console","warn","isSQLiteAvailable","getSQLiteDatabase","getLoadError","createDatabase","dbPath","DB","Error","err","isWindows","process","platform","getStorageRecommendations","recommended","reason","alternatives","catch"],"mappings":"AAKA,SAASA,aAAa,QAAQ,SAAS;AACvC,OAAOC,UAAU,OAAO;AACxB,SAASC,aAAa,QAAQ,MAAM;AAEpC,MAAMC,aAAaD,cAAc,YAAYE,GAAG;AAChD,MAAMC,YAAYJ,KAAKK,OAAO,CAACH;AAE/B,IAAII,WAAW;AACf,IAAIC,kBAAkB;AACtB,IAAIC,YAAY;AAKhB,eAAeC;IACb,IAAI;QAEF,MAAMC,UAAUX,cAAc,YAAYI,GAAG;QAC7CG,WAAWI,QAAQ;QACnBH,kBAAkB;QAClB,OAAO;IACT,EAAE,OAAOI,YAAY;QAEnB,IAAI;YACF,MAAMC,SAAS,MAAM,MAAM,CAAC;YAC5BN,WAAWM,OAAOC,OAAO;YACzBN,kBAAkB;YAClB,OAAO;QACT,EAAE,OAAOO,WAAW;YAClBN,YAAYM;YAGZ,IAAIH,WAAWI,OAAO,CAACC,QAAQ,CAAC,uDAC5BL,WAAWI,OAAO,CAACC,QAAQ,CAAC,yCAC5BL,WAAWI,OAAO,CAACC,QAAQ,CAAC,8CAC5BL,WAAWM,IAAI,KAAK,oBAAoB;gBAE1CC,QAAQC,IAAI,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;AAwBtB,CAAC;YACK;YAEA,OAAO;QACT;IACF;AACF;AAKA,OAAO,eAAeC;IACpB,IAAIb,oBAAoB,MAAM;QAC5B,OAAOA;IACT;IAEA,MAAME;IACN,OAAOF;AACT;AAKA,OAAO,eAAec;IACpB,IAAI,CAACd,mBAAmBC,cAAc,MAAM;QAC1C,MAAMC;IACR;IAEA,OAAOH;AACT;AAKA,OAAO,SAASgB;IACd,OAAOd;AACT;AAKA,OAAO,eAAee,eAAeC,MAAM;IACzC,MAAMC,KAAK,MAAMJ;IAEjB,IAAI,CAACI,IAAI;QACP,MAAM,IAAIC,MAAM;IAClB;IAEA,IAAI;QACF,OAAO,IAAID,GAAGD;IAChB,EAAE,OAAOG,KAAK;QAEZ,IAAIA,IAAIZ,OAAO,CAACC,QAAQ,CAAC,YAAYW,IAAIZ,OAAO,CAACC,QAAQ,CAAC,kBAAkB;YAC1E,MAAM,IAAIU,MAAM,CAAC,0BAA0B,EAAEF,OAAO,8FAA8F,CAAC;QACrJ;QACA,MAAMG;IACR;AACF;AAKA,OAAO,SAASC;IACd,OAAOC,QAAQC,QAAQ,KAAK;AAC9B;AAKA,OAAO,SAASC;IACd,IAAIH,aAAa;QACf,OAAO;YACLI,aAAa;YACbC,QAAQ;YACRC,cAAc;gBACZ;gBACA;gBACA;aACD;QACH;IACF;IAEA,OAAO;QACLF,aAAa;QACbC,QAAQ;QACRC,cAAc;YAAC;SAAwB;IACzC;AACF;AAGAzB,gBAAgB0B,KAAK,CAAC,KAEtB;AAEA,eAAe;IACbf;IACAC;IACAC;IACAC;IACAK;IACAG;AACF,EAAE"}
|
|
1
|
+
{"version":3,"sources":["../../../src/memory/sqlite-wrapper.js"],"sourcesContent":["/**\n * SQLite Wrapper with Windows Fallback Support\n * Provides graceful fallback when better-sqlite3 fails to load\n */\n\nimport { createRequire } from 'module';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nlet Database = null;\nlet sqliteAvailable = false;\nlet loadError = null;\n\n/**\n * Try to load better-sqlite3 with comprehensive error handling\n */\nasync function tryLoadSQLite() {\n try {\n // Try CommonJS require first (more reliable in Node.js)\n const require = createRequire(import.meta.url);\n Database = require('better-sqlite3');\n sqliteAvailable = true;\n return true;\n } catch (requireErr) {\n // Fallback to ES module import\n try {\n const module = await import('better-sqlite3');\n Database = module.default;\n sqliteAvailable = true;\n return true;\n } catch (importErr) {\n loadError = importErr;\n\n // Check for NODE_MODULE_VERSION mismatch (different Node.js ABI)\n const isVersionMismatch =\n requireErr.message?.includes('NODE_MODULE_VERSION') ||\n importErr.message?.includes('NODE_MODULE_VERSION') ||\n requireErr.message?.includes('was compiled against a different Node.js version') ||\n importErr.message?.includes('was compiled against a different Node.js version');\n\n if (isVersionMismatch) {\n // Extract version info for helpful message\n const errorMsg = requireErr.message || importErr.message || '';\n const compiledMatch = errorMsg.match(/NODE_MODULE_VERSION (\\d+)/);\n const requiredMatch = errorMsg.match(/requires\\s+NODE_MODULE_VERSION (\\d+)/);\n\n const nodeVersionMap = {\n '108': '18.x', '115': '20.x', '120': '21.x', '127': '22.x', '131': '23.x'\n };\n\n let versionInfo = '';\n if (compiledMatch && requiredMatch) {\n const compiled = nodeVersionMap[compiledMatch[1]] || `ABI ${compiledMatch[1]}`;\n const required = nodeVersionMap[requiredMatch[1]] || `ABI ${requiredMatch[1]}`;\n versionInfo = `\\n║ Module compiled for Node.js ${compiled}, running Node.js ${required}`.padEnd(79) + '║';\n }\n\n console.warn(`\n╔══════════════════════════════════════════════════════════════════════════════╗\n║ Native Module Version Mismatch (NODE_MODULE_VERSION) ║\n╠══════════════════════════════════════════════════════════════════════════════╣\n║ ║\n║ The better-sqlite3 module was compiled for a different Node.js version. ║${versionInfo}\n║ ║\n║ Claude Flow will continue with JSON fallback storage (still works fine). ║\n║ ║\n║ To fix this and use SQLite: ║\n║ ║\n║ Option 1 - Rebuild the module: ║\n║ > npm rebuild better-sqlite3 ║\n║ ║\n║ Option 2 - Clear npx cache (if using npx): ║\n║ > rm -rf ~/.npm/_npx/ && npx claude-flow@alpha ... ║\n║ ║\n║ Option 3 - Reinstall dependencies: ║\n║ > rm -rf node_modules && npm install ║\n║ ║\n╚══════════════════════════════════════════════════════════════════════════════╝\n`);\n return false;\n }\n\n // Check for other Windows/installation errors\n if (requireErr.message?.includes('Could not locate the bindings file') ||\n requireErr.message?.includes('The specified module could not be found') ||\n requireErr.code === 'MODULE_NOT_FOUND') {\n\n console.warn(`\n╔══════════════════════════════════════════════════════════════════════════════╗\n║ SQLite Native Module Installation Issue ║\n╠══════════════════════════════════════════════════════════════════════════════╣\n║ ║\n║ The native SQLite module failed to load. This is common on Windows when ║\n║ using 'npx' or when node-gyp build tools are not available. ║\n║ ║\n║ Claude Flow will continue with JSON fallback storage (still works fine). ║\n║ ║\n║ To enable SQLite storage: ║\n║ ║\n║ Option 1 - Install Build Tools (Windows): ║\n║ > npm install --global windows-build-tools ║\n║ > npm install claude-flow@alpha ║\n║ ║\n║ Option 2 - Use WSL (Windows Subsystem for Linux): ║\n║ Install WSL and run Claude Flow inside a Linux environment ║\n║ ║\n╚══════════════════════════════════════════════════════════════════════════════╝\n`);\n }\n \n return false;\n }\n }\n}\n\n/**\n * Check if SQLite is available\n */\nexport async function isSQLiteAvailable() {\n if (sqliteAvailable !== null) {\n return sqliteAvailable;\n }\n \n await tryLoadSQLite();\n return sqliteAvailable;\n}\n\n/**\n * Get SQLite Database constructor or null\n */\nexport async function getSQLiteDatabase() {\n if (!sqliteAvailable && loadError === null) {\n await tryLoadSQLite();\n }\n \n return Database;\n}\n\n/**\n * Get the load error if any\n */\nexport function getLoadError() {\n return loadError;\n}\n\n/**\n * Create a SQLite database instance with fallback\n */\nexport async function createDatabase(dbPath) {\n const DB = await getSQLiteDatabase();\n \n if (!DB) {\n throw new Error('SQLite is not available. Use fallback storage instead.');\n }\n \n try {\n return new DB(dbPath);\n } catch (err) {\n // Additional Windows-specific error handling\n if (err.message.includes('EPERM') || err.message.includes('access denied')) {\n throw new Error(`Cannot create database at ${dbPath}. Permission denied. Try using a different directory or running with administrator privileges.`);\n }\n throw err;\n }\n}\n\n/**\n * Check if running on Windows\n */\nexport function isWindows() {\n return process.platform === 'win32';\n}\n\n/**\n * Get platform-specific storage recommendations\n */\nexport function getStorageRecommendations() {\n if (isWindows()) {\n return {\n recommended: 'in-memory',\n reason: 'Windows native module compatibility',\n alternatives: [\n 'Install Windows build tools for SQLite support',\n 'Use WSL (Windows Subsystem for Linux)',\n 'Use Docker container with Linux'\n ]\n };\n }\n \n return {\n recommended: 'sqlite',\n reason: 'Best performance and persistence',\n alternatives: ['in-memory for testing']\n };\n}\n\n// Pre-load SQLite on module import\ntryLoadSQLite().catch(() => {\n // Silently handle initial load failure\n});\n\nexport default {\n isSQLiteAvailable,\n getSQLiteDatabase,\n getLoadError,\n createDatabase,\n isWindows,\n getStorageRecommendations\n};"],"names":["createRequire","path","fileURLToPath","__filename","url","__dirname","dirname","Database","sqliteAvailable","loadError","tryLoadSQLite","require","requireErr","module","default","importErr","isVersionMismatch","message","includes","errorMsg","compiledMatch","match","requiredMatch","nodeVersionMap","versionInfo","compiled","required","padEnd","console","warn","code","isSQLiteAvailable","getSQLiteDatabase","getLoadError","createDatabase","dbPath","DB","Error","err","isWindows","process","platform","getStorageRecommendations","recommended","reason","alternatives","catch"],"mappings":"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"}
|