claude-flow 2.7.41 → 2.7.43

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.
@@ -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,7 +12,7 @@ try {
12
12
  BUILD_DATE = new Date().toISOString().split('T')[0];
13
13
  } catch (error) {
14
14
  console.warn('Warning: Could not read version from package.json, using fallback');
15
- VERSION = '2.0.0-alpha.91';
15
+ VERSION = '2.0.0-alpha.101';
16
16
  BUILD_DATE = new Date().toISOString().split('T')[0];
17
17
  }
18
18
  export { VERSION, BUILD_DATE };
@@ -23,4 +23,4 @@ export function displayVersion() {
23
23
  console.log(getVersionString());
24
24
  }
25
25
 
26
- //# sourceMappingURL=version.js.mapp
26
+ //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/version.ts"],"sourcesContent":["/**\n * Centralized version management\n * Reads version from package.json to ensure consistency\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\n// Get the directory of this module\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Read version from package.json\nlet VERSION: string;\nlet BUILD_DATE: string;\n\ntry {\n // Navigate to project root and read package.json\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n VERSION = packageJson.version;\n BUILD_DATE = new Date().toISOString().split('T')[0];\n} catch (error) {\n // Fallback version if package.json can't be read\n console.warn('Warning: Could not read version from package.json, using fallback');\n VERSION = '2.0.0-alpha.91';\n BUILD_DATE = new Date().toISOString().split('T')[0];\n}\n\nexport { VERSION, BUILD_DATE };\n\n// Helper function to get formatted version string\nexport function getVersionString(includeV = true): string {\n return includeV ? `v${VERSION}` : VERSION;\n}\n\n// Helper function for version display in CLI\nexport function displayVersion(): void {\n console.log(getVersionString());\n}"],"names":["readFileSync","join","dirname","fileURLToPath","__filename","url","__dirname","VERSION","BUILD_DATE","packageJsonPath","packageJson","JSON","parse","version","Date","toISOString","split","error","console","warn","getVersionString","includeV","displayVersion","log"],"mappings":"AAKA,SAASA,YAAY,QAAQ,KAAK;AAClC,SAASC,IAAI,EAAEC,OAAO,QAAQ,OAAO;AACrC,SAASC,aAAa,QAAQ,MAAM;AAGpC,MAAMC,aAAaD,cAAc,YAAYE,GAAG;AAChD,MAAMC,YAAYJ,QAAQE;AAG1B,IAAIG;AACJ,IAAIC;AAEJ,IAAI;IAEF,MAAMC,kBAAkBR,KAAKK,WAAW;IACxC,MAAMI,cAAcC,KAAKC,KAAK,CAACZ,aAAaS,iBAAiB;IAC7DF,UAAUG,YAAYG,OAAO;IAC7BL,aAAa,IAAIM,OAAOC,WAAW,GAAGC,KAAK,CAAC,IAAI,CAAC,EAAE;AACrD,EAAE,OAAOC,OAAO;IAEdC,QAAQC,IAAI,CAAC;IACbZ,UAAU;IACVC,aAAa,IAAIM,OAAOC,WAAW,GAAGC,KAAK,CAAC,IAAI,CAAC,EAAE;AACrD;AAEA,SAAST,OAAO,EAAEC,UAAU,GAAG;AAG/B,OAAO,SAASY,iBAAiBC,WAAW,IAAI;IAC9C,OAAOA,WAAW,CAAC,CAAC,EAAEd,SAAS,GAAGA;AACpC;AAGA,OAAO,SAASe;IACdJ,QAAQK,GAAG,CAACH;AACd"}
1
+ {"version":3,"sources":["../../../src/core/version.js"],"sourcesContent":["/**\n * Centralized version management (JavaScript version)\n * Reads version from package.json to ensure consistency\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\n// Get the directory of this module\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Read version from package.json\nlet VERSION;\nlet BUILD_DATE;\n\ntry {\n // Navigate to project root and read package.json\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n VERSION = packageJson.version;\n BUILD_DATE = new Date().toISOString().split('T')[0];\n} catch (error) {\n // Fallback version if package.json can't be read\n console.warn('Warning: Could not read version from package.json, using fallback');\n VERSION = '2.0.0-alpha.101';\n BUILD_DATE = new Date().toISOString().split('T')[0];\n}\n\nexport { VERSION, BUILD_DATE };\n\n// Helper function to get formatted version string\nexport function getVersionString(includeV = true) {\n return includeV ? `v${VERSION}` : VERSION;\n}\n\n// Helper function for version display in CLI\nexport function displayVersion() {\n console.log(getVersionString());\n}"],"names":["readFileSync","join","dirname","fileURLToPath","__filename","url","__dirname","VERSION","BUILD_DATE","packageJsonPath","packageJson","JSON","parse","version","Date","toISOString","split","error","console","warn","getVersionString","includeV","displayVersion","log"],"mappings":"AAKA,SAASA,YAAY,QAAQ,KAAK;AAClC,SAASC,IAAI,EAAEC,OAAO,QAAQ,OAAO;AACrC,SAASC,aAAa,QAAQ,MAAM;AAGpC,MAAMC,aAAaD,cAAc,YAAYE,GAAG;AAChD,MAAMC,YAAYJ,QAAQE;AAG1B,IAAIG;AACJ,IAAIC;AAEJ,IAAI;IAEF,MAAMC,kBAAkBR,KAAKK,WAAW;IACxC,MAAMI,cAAcC,KAAKC,KAAK,CAACZ,aAAaS,iBAAiB;IAC7DF,UAAUG,YAAYG,OAAO;IAC7BL,aAAa,IAAIM,OAAOC,WAAW,GAAGC,KAAK,CAAC,IAAI,CAAC,EAAE;AACrD,EAAE,OAAOC,OAAO;IAEdC,QAAQC,IAAI,CAAC;IACbZ,UAAU;IACVC,aAAa,IAAIM,OAAOC,WAAW,GAAGC,KAAK,CAAC,IAAI,CAAC,EAAE;AACrD;AAEA,SAAST,OAAO,EAAEC,UAAU,GAAG;AAG/B,OAAO,SAASY,iBAAiBC,WAAW,IAAI;IAC9C,OAAOA,WAAW,CAAC,CAAC,EAAEd,SAAS,GAAGA;AACpC;AAGA,OAAO,SAASe;IACdJ,QAAQK,GAAG,CAACH;AACd"}H;AACd"}
@@ -20,29 +20,67 @@ async function tryLoadSQLite() {
20
20
  return true;
21
21
  } catch (importErr) {
22
22
  loadError = importErr;
23
- if (requireErr.message.includes('was compiled against a different Node.js version') || requireErr.message.includes('Could not locate the bindings file') || requireErr.message.includes('The specified module could not be found') || requireErr.code === 'MODULE_NOT_FOUND') {
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
- Windows SQLite Installation Issue
43
+ Native Module Version Mismatch (NODE_MODULE_VERSION)
27
44
  ╠══════════════════════════════════════════════════════════════════════════════╣
28
45
  ║ ║
29
- ║ The native SQLite module failed to load. This is common on Windows when
30
- using 'npx' or when node-gyp build tools are not available.
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
- Claude Flow will continue with in-memory storage (non-persistent).
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
- To enable persistent storage on Windows:
74
+ Claude Flow will continue with JSON fallback storage (still works fine).
35
75
  ║ ║
36
- Option 1 - Install Windows Build Tools:
37
- ║ > npm install --global windows-build-tools ║
38
- ║ > npm install claude-flow@alpha ║
76
+ To enable SQLite storage:
39
77
  ║ ║
40
- ║ Option 2 - Use Pre-built Binaries:
41
- ║ > npm config set python python3
42
- ║ > npm install claude-flow@alpha --build-from-source=false
78
+ ║ Option 1 - Install Build Tools (Windows):
79
+ ║ > npm install --global windows-build-tools
80
+ ║ > npm install claude-flow@alpha
43
81
  ║ ║
44
- ║ Option 3 - Use WSL (Windows Subsystem for Linux):
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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"}
@@ -6,6 +6,33 @@ export function isNpmCacheError(error) {
6
6
  const errorStr = error?.message || String(error);
7
7
  return errorStr.includes('ENOTEMPTY') && (errorStr.includes('npm') || errorStr.includes('npx') || errorStr.includes('_npx')) || errorStr.includes('better-sqlite3');
8
8
  }
9
+ export function isNativeModuleVersionError(error) {
10
+ const errorStr = error?.message || String(error);
11
+ return errorStr.includes('NODE_MODULE_VERSION') || errorStr.includes('was compiled against a different Node.js version') || errorStr.includes('re-compiling or re-installing the module');
12
+ }
13
+ export function getNativeModuleRecoveryMessage(error) {
14
+ const errorStr = error?.message || String(error);
15
+ const compiledMatch = errorStr.match(/NODE_MODULE_VERSION (\d+)/);
16
+ const requiredMatch = errorStr.match(/requires\s+NODE_MODULE_VERSION (\d+)/);
17
+ let message = '⚠️ Native module version mismatch detected.\n';
18
+ if (compiledMatch && requiredMatch) {
19
+ const nodeVersionMap = {
20
+ '108': '18.x',
21
+ '115': '20.x',
22
+ '120': '21.x',
23
+ '127': '22.x',
24
+ '131': '23.x'
25
+ };
26
+ const compiled = nodeVersionMap[compiledMatch[1]] || `ABI ${compiledMatch[1]}`;
27
+ const required = nodeVersionMap[requiredMatch[1]] || `ABI ${requiredMatch[1]}`;
28
+ message += ` Module was compiled for Node.js ${compiled}, but running Node.js ${required}.\n`;
29
+ }
30
+ message += '\n To fix this, try one of:\n';
31
+ message += ' 1. npm rebuild better-sqlite3\n';
32
+ message += ' 2. rm -rf node_modules && npm install\n';
33
+ message += ' 3. npx cache: rm -rf ~/.npm/_npx/ && run command again\n';
34
+ return message;
35
+ }
9
36
  export function isWSL() {
10
37
  if (process.platform !== 'linux') {
11
38
  return false;
@@ -203,6 +230,8 @@ export async function recoverInitErrors(error) {
203
230
  }
204
231
  export const errorRecovery = {
205
232
  isNpmCacheError,
233
+ isNativeModuleVersionError,
234
+ getNativeModuleRecoveryMessage,
206
235
  isWSL,
207
236
  cleanNpmCache,
208
237
  retryWithRecovery,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/error-recovery.ts"],"sourcesContent":["/**\n * Error Recovery Utilities\n * Automatic error detection and recovery for common installation issues\n */\n\nimport { execSync } from 'child_process';\nimport * as fs from 'fs-extra';\nimport * as path from 'path';\nimport * as os from 'os';\n\nexport interface RecoveryResult {\n success: boolean;\n action: string;\n message: string;\n recovered: boolean;\n}\n\nexport interface RetryOptions {\n maxRetries?: number;\n delay?: number;\n onRetry?: (attempt: number, error: Error) => void;\n cleanupFn?: () => Promise<void>;\n}\n\n/**\n * Detect if an error is the ENOTEMPTY npm cache error\n */\nexport function isNpmCacheError(error: any): boolean {\n const errorStr = error?.message || String(error);\n return (\n errorStr.includes('ENOTEMPTY') &&\n (errorStr.includes('npm') || errorStr.includes('npx') || errorStr.includes('_npx'))\n ) || errorStr.includes('better-sqlite3');\n}\n\n/**\n * Detect if running on WSL (Windows Subsystem for Linux)\n */\nexport function isWSL(): boolean {\n if (process.platform !== 'linux') {\n return false;\n }\n\n try {\n const release = fs.readFileSync('/proc/version', 'utf8').toLowerCase();\n return release.includes('microsoft') || release.includes('wsl');\n } catch {\n return false;\n }\n}\n\n/**\n * Clean npm and npx cache directories\n */\nexport async function cleanNpmCache(): Promise<RecoveryResult> {\n const homeDir = os.homedir();\n const npxCacheDir = path.join(homeDir, '.npm', '_npx');\n\n try {\n console.log('🧹 Cleaning npm cache...');\n\n // Clean npm cache\n try {\n execSync('npm cache clean --force', { stdio: 'pipe' });\n console.log('✅ npm cache cleaned');\n } catch (error) {\n console.warn('⚠️ npm cache clean failed, continuing...');\n }\n\n // Remove npx cache directory\n if (await fs.pathExists(npxCacheDir)) {\n console.log(`🗑️ Removing npx cache: ${npxCacheDir}`);\n await fs.remove(npxCacheDir);\n console.log('✅ npx cache removed');\n }\n\n // Fix permissions on WSL\n if (isWSL()) {\n const npmDir = path.join(homeDir, '.npm');\n if (await fs.pathExists(npmDir)) {\n try {\n execSync(`chmod -R 755 \"${npmDir}\"`, { stdio: 'pipe' });\n console.log('✅ npm directory permissions fixed');\n } catch (error) {\n console.warn('⚠️ Permission fix failed, continuing...');\n }\n }\n }\n\n return {\n success: true,\n action: 'cache-cleanup',\n message: 'npm/npx cache cleaned successfully',\n recovered: true\n };\n } catch (error) {\n return {\n success: false,\n action: 'cache-cleanup',\n message: `Failed to clean cache: ${error instanceof Error ? error.message : String(error)}`,\n recovered: false\n };\n }\n}\n\n/**\n * Automatic retry with exponential backoff and error recovery\n */\nexport async function retryWithRecovery<T>(\n fn: () => Promise<T>,\n options: RetryOptions = {}\n): Promise<T> {\n const {\n maxRetries = 3,\n delay = 1000,\n onRetry,\n cleanupFn\n } = options;\n\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error as Error;\n\n // Check if it's a recoverable error\n if (isNpmCacheError(error)) {\n console.log(`\\n⚠️ Detected npm cache error (attempt ${attempt}/${maxRetries})`);\n\n // Attempt automatic recovery\n const recovery = await cleanNpmCache();\n if (recovery.success) {\n console.log('✅ Cache cleaned, retrying...\\n');\n\n // Run custom cleanup if provided\n if (cleanupFn) {\n await cleanupFn();\n }\n\n // Exponential backoff\n const backoffDelay = delay * Math.pow(2, attempt - 1);\n await new Promise(resolve => setTimeout(resolve, backoffDelay));\n\n continue; // Retry\n } else {\n console.error('❌ Cache cleanup failed:', recovery.message);\n }\n }\n\n // Call retry callback\n if (onRetry && attempt < maxRetries) {\n onRetry(attempt, lastError);\n await new Promise(resolve => setTimeout(resolve, delay));\n continue;\n }\n\n // Last attempt failed\n if (attempt === maxRetries) {\n break;\n }\n }\n }\n\n // All retries exhausted\n throw new Error(\n `Operation failed after ${maxRetries} attempts. ` +\n `Last error: ${lastError?.message || 'Unknown error'}`\n );\n}\n\n/**\n * WSL-specific error recovery\n */\nexport async function recoverWSLErrors(): Promise<RecoveryResult> {\n if (!isWSL()) {\n return {\n success: true,\n action: 'wsl-check',\n message: 'Not running on WSL, no recovery needed',\n recovered: false\n };\n }\n\n console.log('🔍 Detected WSL environment, applying fixes...');\n\n try {\n const homeDir = os.homedir();\n\n // Check if running from Windows mount\n const cwd = process.cwd();\n if (cwd.startsWith('/mnt/')) {\n console.warn('⚠️ WARNING: Running from Windows filesystem (/mnt/)');\n console.warn(' For best results, run from WSL filesystem (e.g., ~/projects/)');\n }\n\n // Ensure build tools are available\n try {\n execSync('which gcc', { stdio: 'pipe' });\n } catch {\n console.warn('⚠️ build-essential not found. Install with:');\n console.warn(' sudo apt-get update && sudo apt-get install -y build-essential python3');\n }\n\n // Clean cache with WSL-specific handling\n return await cleanNpmCache();\n } catch (error) {\n return {\n success: false,\n action: 'wsl-recovery',\n message: `WSL recovery failed: ${error instanceof Error ? error.message : String(error)}`,\n recovered: false\n };\n }\n}\n\n/**\n * Verify better-sqlite3 installation\n */\nexport async function verifyBetterSqlite3(): Promise<boolean> {\n try {\n require.resolve('better-sqlite3');\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Install better-sqlite3 with retry and error recovery\n */\nexport async function installBetterSqlite3WithRecovery(): Promise<RecoveryResult> {\n console.log('📦 Installing better-sqlite3...');\n\n return retryWithRecovery(\n async () => {\n execSync('npm install better-sqlite3 --no-save', {\n stdio: 'inherit',\n cwd: process.cwd()\n });\n\n // Verify installation\n if (await verifyBetterSqlite3()) {\n return {\n success: true,\n action: 'install-sqlite',\n message: 'better-sqlite3 installed successfully',\n recovered: true\n };\n } else {\n throw new Error('Installation completed but module not found');\n }\n },\n {\n maxRetries: 3,\n delay: 2000,\n onRetry: (attempt, error) => {\n console.log(`⚠️ Install attempt ${attempt} failed: ${error.message}`);\n console.log('🔄 Cleaning cache and retrying...');\n }\n }\n );\n}\n\n/**\n * Comprehensive error recovery for initialization\n */\nexport async function recoverInitErrors(error: any): Promise<RecoveryResult> {\n console.log('\\n🚨 Error detected during initialization');\n console.log(` Error: ${error?.message || String(error)}\\n`);\n\n // WSL-specific recovery\n if (isWSL()) {\n console.log('🔧 Applying WSL-specific fixes...');\n const wslRecovery = await recoverWSLErrors();\n if (!wslRecovery.success) {\n return wslRecovery;\n }\n }\n\n // npm cache error recovery\n if (isNpmCacheError(error)) {\n console.log('🔧 Detected npm cache error, attempting recovery...');\n const cacheRecovery = await cleanNpmCache();\n if (!cacheRecovery.success) {\n return cacheRecovery;\n }\n\n // Try to reinstall better-sqlite3\n if (!await verifyBetterSqlite3()) {\n console.log('🔧 better-sqlite3 missing, attempting reinstall...');\n return await installBetterSqlite3WithRecovery();\n }\n\n return {\n success: true,\n action: 'error-recovery',\n message: 'Cache cleaned and dependencies verified',\n recovered: true\n };\n }\n\n // Generic error handling\n return {\n success: false,\n action: 'error-recovery',\n message: `Unable to automatically recover from error: ${error?.message || String(error)}`,\n recovered: false\n };\n}\n\n/**\n * Export utility functions\n */\nexport const errorRecovery = {\n isNpmCacheError,\n isWSL,\n cleanNpmCache,\n retryWithRecovery,\n recoverWSLErrors,\n verifyBetterSqlite3,\n installBetterSqlite3WithRecovery,\n recoverInitErrors\n};\n"],"names":["execSync","fs","path","os","isNpmCacheError","error","errorStr","message","String","includes","isWSL","process","platform","release","readFileSync","toLowerCase","cleanNpmCache","homeDir","homedir","npxCacheDir","join","console","log","stdio","warn","pathExists","remove","npmDir","success","action","recovered","Error","retryWithRecovery","fn","options","maxRetries","delay","onRetry","cleanupFn","lastError","attempt","recovery","backoffDelay","Math","pow","Promise","resolve","setTimeout","recoverWSLErrors","cwd","startsWith","verifyBetterSqlite3","require","installBetterSqlite3WithRecovery","recoverInitErrors","wslRecovery","cacheRecovery","errorRecovery"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/utils/error-recovery.ts"],"sourcesContent":["/**\n * Error Recovery Utilities\n * Automatic error detection and recovery for common installation issues\n */\n\nimport { execSync } from 'child_process';\nimport * as fs from 'fs-extra';\nimport * as path from 'path';\nimport * as os from 'os';\n\nexport interface RecoveryResult {\n success: boolean;\n action: string;\n message: string;\n recovered: boolean;\n}\n\nexport interface RetryOptions {\n maxRetries?: number;\n delay?: number;\n onRetry?: (attempt: number, error: Error) => void;\n cleanupFn?: () => Promise<void>;\n}\n\n/**\n * Detect if an error is the ENOTEMPTY npm cache error\n */\nexport function isNpmCacheError(error: any): boolean {\n const errorStr = error?.message || String(error);\n return (\n errorStr.includes('ENOTEMPTY') &&\n (errorStr.includes('npm') || errorStr.includes('npx') || errorStr.includes('_npx'))\n ) || errorStr.includes('better-sqlite3');\n}\n\n/**\n * Detect if an error is a native module version mismatch (NODE_MODULE_VERSION)\n * This happens when native modules are compiled for a different Node.js version\n */\nexport function isNativeModuleVersionError(error: any): boolean {\n const errorStr = error?.message || String(error);\n return (\n errorStr.includes('NODE_MODULE_VERSION') ||\n errorStr.includes('was compiled against a different Node.js version') ||\n errorStr.includes('re-compiling or re-installing the module')\n );\n}\n\n/**\n * Get helpful message for native module version mismatch\n */\nexport function getNativeModuleRecoveryMessage(error: any): string {\n const errorStr = error?.message || String(error);\n\n // Extract version numbers if available\n const compiledMatch = errorStr.match(/NODE_MODULE_VERSION (\\d+)/);\n const requiredMatch = errorStr.match(/requires\\s+NODE_MODULE_VERSION (\\d+)/);\n\n let message = '⚠️ Native module version mismatch detected.\\n';\n\n if (compiledMatch && requiredMatch) {\n const nodeVersionMap: Record<string, string> = {\n '108': '18.x',\n '115': '20.x',\n '120': '21.x',\n '127': '22.x',\n '131': '23.x'\n };\n const compiled = nodeVersionMap[compiledMatch[1]] || `ABI ${compiledMatch[1]}`;\n const required = nodeVersionMap[requiredMatch[1]] || `ABI ${requiredMatch[1]}`;\n message += ` Module was compiled for Node.js ${compiled}, but running Node.js ${required}.\\n`;\n }\n\n message += '\\n To fix this, try one of:\\n';\n message += ' 1. npm rebuild better-sqlite3\\n';\n message += ' 2. rm -rf node_modules && npm install\\n';\n message += ' 3. npx cache: rm -rf ~/.npm/_npx/ && run command again\\n';\n\n return message;\n}\n\n/**\n * Detect if running on WSL (Windows Subsystem for Linux)\n */\nexport function isWSL(): boolean {\n if (process.platform !== 'linux') {\n return false;\n }\n\n try {\n const release = fs.readFileSync('/proc/version', 'utf8').toLowerCase();\n return release.includes('microsoft') || release.includes('wsl');\n } catch {\n return false;\n }\n}\n\n/**\n * Clean npm and npx cache directories\n */\nexport async function cleanNpmCache(): Promise<RecoveryResult> {\n const homeDir = os.homedir();\n const npxCacheDir = path.join(homeDir, '.npm', '_npx');\n\n try {\n console.log('🧹 Cleaning npm cache...');\n\n // Clean npm cache\n try {\n execSync('npm cache clean --force', { stdio: 'pipe' });\n console.log('✅ npm cache cleaned');\n } catch (error) {\n console.warn('⚠️ npm cache clean failed, continuing...');\n }\n\n // Remove npx cache directory\n if (await fs.pathExists(npxCacheDir)) {\n console.log(`🗑️ Removing npx cache: ${npxCacheDir}`);\n await fs.remove(npxCacheDir);\n console.log('✅ npx cache removed');\n }\n\n // Fix permissions on WSL\n if (isWSL()) {\n const npmDir = path.join(homeDir, '.npm');\n if (await fs.pathExists(npmDir)) {\n try {\n execSync(`chmod -R 755 \"${npmDir}\"`, { stdio: 'pipe' });\n console.log('✅ npm directory permissions fixed');\n } catch (error) {\n console.warn('⚠️ Permission fix failed, continuing...');\n }\n }\n }\n\n return {\n success: true,\n action: 'cache-cleanup',\n message: 'npm/npx cache cleaned successfully',\n recovered: true\n };\n } catch (error) {\n return {\n success: false,\n action: 'cache-cleanup',\n message: `Failed to clean cache: ${error instanceof Error ? error.message : String(error)}`,\n recovered: false\n };\n }\n}\n\n/**\n * Automatic retry with exponential backoff and error recovery\n */\nexport async function retryWithRecovery<T>(\n fn: () => Promise<T>,\n options: RetryOptions = {}\n): Promise<T> {\n const {\n maxRetries = 3,\n delay = 1000,\n onRetry,\n cleanupFn\n } = options;\n\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error as Error;\n\n // Check if it's a recoverable error\n if (isNpmCacheError(error)) {\n console.log(`\\n⚠️ Detected npm cache error (attempt ${attempt}/${maxRetries})`);\n\n // Attempt automatic recovery\n const recovery = await cleanNpmCache();\n if (recovery.success) {\n console.log('✅ Cache cleaned, retrying...\\n');\n\n // Run custom cleanup if provided\n if (cleanupFn) {\n await cleanupFn();\n }\n\n // Exponential backoff\n const backoffDelay = delay * Math.pow(2, attempt - 1);\n await new Promise(resolve => setTimeout(resolve, backoffDelay));\n\n continue; // Retry\n } else {\n console.error('❌ Cache cleanup failed:', recovery.message);\n }\n }\n\n // Call retry callback\n if (onRetry && attempt < maxRetries) {\n onRetry(attempt, lastError);\n await new Promise(resolve => setTimeout(resolve, delay));\n continue;\n }\n\n // Last attempt failed\n if (attempt === maxRetries) {\n break;\n }\n }\n }\n\n // All retries exhausted\n throw new Error(\n `Operation failed after ${maxRetries} attempts. ` +\n `Last error: ${lastError?.message || 'Unknown error'}`\n );\n}\n\n/**\n * WSL-specific error recovery\n */\nexport async function recoverWSLErrors(): Promise<RecoveryResult> {\n if (!isWSL()) {\n return {\n success: true,\n action: 'wsl-check',\n message: 'Not running on WSL, no recovery needed',\n recovered: false\n };\n }\n\n console.log('🔍 Detected WSL environment, applying fixes...');\n\n try {\n const homeDir = os.homedir();\n\n // Check if running from Windows mount\n const cwd = process.cwd();\n if (cwd.startsWith('/mnt/')) {\n console.warn('⚠️ WARNING: Running from Windows filesystem (/mnt/)');\n console.warn(' For best results, run from WSL filesystem (e.g., ~/projects/)');\n }\n\n // Ensure build tools are available\n try {\n execSync('which gcc', { stdio: 'pipe' });\n } catch {\n console.warn('⚠️ build-essential not found. Install with:');\n console.warn(' sudo apt-get update && sudo apt-get install -y build-essential python3');\n }\n\n // Clean cache with WSL-specific handling\n return await cleanNpmCache();\n } catch (error) {\n return {\n success: false,\n action: 'wsl-recovery',\n message: `WSL recovery failed: ${error instanceof Error ? error.message : String(error)}`,\n recovered: false\n };\n }\n}\n\n/**\n * Verify better-sqlite3 installation\n */\nexport async function verifyBetterSqlite3(): Promise<boolean> {\n try {\n require.resolve('better-sqlite3');\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Install better-sqlite3 with retry and error recovery\n */\nexport async function installBetterSqlite3WithRecovery(): Promise<RecoveryResult> {\n console.log('📦 Installing better-sqlite3...');\n\n return retryWithRecovery(\n async () => {\n execSync('npm install better-sqlite3 --no-save', {\n stdio: 'inherit',\n cwd: process.cwd()\n });\n\n // Verify installation\n if (await verifyBetterSqlite3()) {\n return {\n success: true,\n action: 'install-sqlite',\n message: 'better-sqlite3 installed successfully',\n recovered: true\n };\n } else {\n throw new Error('Installation completed but module not found');\n }\n },\n {\n maxRetries: 3,\n delay: 2000,\n onRetry: (attempt, error) => {\n console.log(`⚠️ Install attempt ${attempt} failed: ${error.message}`);\n console.log('🔄 Cleaning cache and retrying...');\n }\n }\n );\n}\n\n/**\n * Comprehensive error recovery for initialization\n */\nexport async function recoverInitErrors(error: any): Promise<RecoveryResult> {\n console.log('\\n🚨 Error detected during initialization');\n console.log(` Error: ${error?.message || String(error)}\\n`);\n\n // WSL-specific recovery\n if (isWSL()) {\n console.log('🔧 Applying WSL-specific fixes...');\n const wslRecovery = await recoverWSLErrors();\n if (!wslRecovery.success) {\n return wslRecovery;\n }\n }\n\n // npm cache error recovery\n if (isNpmCacheError(error)) {\n console.log('🔧 Detected npm cache error, attempting recovery...');\n const cacheRecovery = await cleanNpmCache();\n if (!cacheRecovery.success) {\n return cacheRecovery;\n }\n\n // Try to reinstall better-sqlite3\n if (!await verifyBetterSqlite3()) {\n console.log('🔧 better-sqlite3 missing, attempting reinstall...');\n return await installBetterSqlite3WithRecovery();\n }\n\n return {\n success: true,\n action: 'error-recovery',\n message: 'Cache cleaned and dependencies verified',\n recovered: true\n };\n }\n\n // Generic error handling\n return {\n success: false,\n action: 'error-recovery',\n message: `Unable to automatically recover from error: ${error?.message || String(error)}`,\n recovered: false\n };\n}\n\n/**\n * Export utility functions\n */\nexport const errorRecovery = {\n isNpmCacheError,\n isNativeModuleVersionError,\n getNativeModuleRecoveryMessage,\n isWSL,\n cleanNpmCache,\n retryWithRecovery,\n recoverWSLErrors,\n verifyBetterSqlite3,\n installBetterSqlite3WithRecovery,\n recoverInitErrors\n};\n"],"names":["execSync","fs","path","os","isNpmCacheError","error","errorStr","message","String","includes","isNativeModuleVersionError","getNativeModuleRecoveryMessage","compiledMatch","match","requiredMatch","nodeVersionMap","compiled","required","isWSL","process","platform","release","readFileSync","toLowerCase","cleanNpmCache","homeDir","homedir","npxCacheDir","join","console","log","stdio","warn","pathExists","remove","npmDir","success","action","recovered","Error","retryWithRecovery","fn","options","maxRetries","delay","onRetry","cleanupFn","lastError","attempt","recovery","backoffDelay","Math","pow","Promise","resolve","setTimeout","recoverWSLErrors","cwd","startsWith","verifyBetterSqlite3","require","installBetterSqlite3WithRecovery","recoverInitErrors","wslRecovery","cacheRecovery","errorRecovery"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-flow",
3
- "version": "2.7.41",
3
+ "version": "2.7.43",
4
4
  "description": "Enterprise-grade AI agent orchestration with WASM-powered ReasoningBank memory and AgentDB vector database (always uses latest agentic-flow)",
5
5
  "mcpName": "io.github.ruvnet/claude-flow",
6
6
  "main": "cli.mjs",
@@ -32,15 +32,26 @@ let sqliteAvailable = false;
32
32
  async function loadSqlite() {
33
33
  if (Database !== null) return sqliteAvailable;
34
34
  try {
35
- const sqlite = await import('better-sqlite3');
36
- Database = sqlite.default;
35
+ // Try createRequire first for CommonJS modules (better-sqlite3 is CommonJS)
36
+ const { createRequire } = await import('module');
37
+ const require = createRequire(import.meta.url);
38
+ Database = require('better-sqlite3');
37
39
  // Test if bindings work by creating a temp in-memory database
38
40
  const testDb = new Database(':memory:');
39
41
  testDb.close();
40
42
  sqliteAvailable = true;
41
- } catch (err) {
42
- sqliteAvailable = false;
43
- Database = null;
43
+ } catch (requireErr) {
44
+ // Fallback to dynamic import if createRequire fails
45
+ try {
46
+ const sqlite = await import('better-sqlite3');
47
+ Database = sqlite.default || sqlite;
48
+ const testDb = new Database(':memory:');
49
+ testDb.close();
50
+ sqliteAvailable = true;
51
+ } catch (err) {
52
+ sqliteAvailable = false;
53
+ Database = null;
54
+ }
44
55
  }
45
56
  return sqliteAvailable;
46
57
  }
@@ -516,6 +527,16 @@ async function spawnSwarmWizard() {
516
527
  * Spawn a hive mind swarm
517
528
  */
518
529
  async function spawnSwarm(args, flags) {
530
+ // Load SQLite before using Database constructor
531
+ const hasSqlite = await loadSqlite();
532
+ if (!hasSqlite) {
533
+ console.error(chalk.red('Error: SQLite is required for hive-mind spawn'));
534
+ console.log(chalk.yellow('Please ensure better-sqlite3 is properly installed:'));
535
+ console.log(chalk.gray(' npm install better-sqlite3'));
536
+ console.log(chalk.gray(' # or for ARM64/M1: npm rebuild better-sqlite3'));
537
+ return;
538
+ }
539
+
519
540
  const objective = args.join(' ').trim();
520
541
 
521
542
  // Check for non-interactive mode FIRST
@@ -1167,6 +1188,12 @@ async function showStatus(flags) {
1167
1188
  * Show consensus decisions
1168
1189
  */
1169
1190
  async function showConsensus(flags) {
1191
+ // Load SQLite before using Database constructor
1192
+ const hasSqlite = await loadSqlite();
1193
+ if (!hasSqlite) {
1194
+ console.error(chalk.red('Error: SQLite is required for this command'));
1195
+ return;
1196
+ }
1170
1197
  try {
1171
1198
  const dbPath = path.join(cwd(), '.hive-mind', 'hive.db');
1172
1199
  const db = new Database(dbPath);
@@ -1261,6 +1288,12 @@ async function showConsensus(flags) {
1261
1288
  * Show performance metrics
1262
1289
  */
1263
1290
  async function showMetrics(flags) {
1291
+ // Load SQLite before using Database constructor
1292
+ const hasSqlite = await loadSqlite();
1293
+ if (!hasSqlite) {
1294
+ console.error(chalk.red('Error: SQLite is required for this command'));
1295
+ return;
1296
+ }
1264
1297
  try {
1265
1298
  const dbPath = path.join(cwd(), '.hive-mind', 'hive.db');
1266
1299
  const db = new Database(dbPath);
@@ -1722,6 +1755,12 @@ export async function hiveMindCommand(args, flags) {
1722
1755
  * List all memories in the collective memory store
1723
1756
  */
1724
1757
  async function listMemories() {
1758
+ // Load SQLite before using Database constructor
1759
+ const hasSqlite = await loadSqlite();
1760
+ if (!hasSqlite) {
1761
+ console.error(chalk.red('Error: SQLite is required for this command'));
1762
+ return;
1763
+ }
1725
1764
  try {
1726
1765
  console.log(chalk.blue('\n📋 Collective Memory Store\n'));
1727
1766
 
@@ -1791,6 +1830,12 @@ async function listMemories() {
1791
1830
  * Search memories by keyword
1792
1831
  */
1793
1832
  async function searchMemories() {
1833
+ // Load SQLite before using Database constructor
1834
+ const hasSqlite = await loadSqlite();
1835
+ if (!hasSqlite) {
1836
+ console.error(chalk.red('Error: SQLite is required for this command'));
1837
+ return;
1838
+ }
1794
1839
  try {
1795
1840
  const { searchTerm } = await inquirer.prompt([
1796
1841
  {
@@ -6,15 +6,45 @@ import {
6
6
  checkRuvSwarmAvailable,
7
7
  } from '../utils.js';
8
8
  import { SqliteMemoryStore } from '../../memory/sqlite-store.js';
9
+ import { InMemoryStore } from '../../memory/in-memory-store.js';
9
10
 
10
11
  // Initialize memory store
11
12
  let memoryStore = null;
13
+ let storeInitFailed = false;
12
14
 
13
15
  async function getMemoryStore() {
14
- if (!memoryStore) {
16
+ if (memoryStore) return memoryStore;
17
+
18
+ // If we already failed, return a working in-memory store
19
+ if (storeInitFailed) {
20
+ if (!memoryStore) {
21
+ memoryStore = new InMemoryStore();
22
+ await memoryStore.initialize();
23
+ }
24
+ return memoryStore;
25
+ }
26
+
27
+ try {
15
28
  memoryStore = new SqliteMemoryStore();
16
29
  await memoryStore.initialize();
30
+ } catch (err) {
31
+ // Check if it's a native module error (NODE_MODULE_VERSION mismatch)
32
+ const isNativeModuleError =
33
+ err.message?.includes('NODE_MODULE_VERSION') ||
34
+ err.message?.includes('was compiled against a different Node.js version') ||
35
+ err.message?.includes('better-sqlite3') ||
36
+ err.message?.includes('SQLite is not available');
37
+
38
+ if (isNativeModuleError) {
39
+ printWarning(`SQLite unavailable, using in-memory storage for hooks (data won't persist)`);
40
+ storeInitFailed = true;
41
+ memoryStore = new InMemoryStore();
42
+ await memoryStore.initialize();
43
+ } else {
44
+ throw err;
45
+ }
17
46
  }
47
+
18
48
  return memoryStore;
19
49
  }
20
50
 
@@ -6,6 +6,21 @@
6
6
  import * as fs from 'fs-extra';
7
7
  import * as path from 'path';
8
8
  import { IDatabaseProvider } from '../types/interfaces.js';
9
+ import { isNativeModuleVersionError, getNativeModuleRecoveryMessage } from '../utils/error-recovery.js';
10
+
11
+ /**
12
+ * Custom error class for native module issues
13
+ */
14
+ export class NativeModuleError extends Error {
15
+ public readonly originalError: Error;
16
+ public readonly isNativeModuleError = true;
17
+
18
+ constructor(message: string, originalError: Error) {
19
+ super(message);
20
+ this.name = 'NativeModuleError';
21
+ this.originalError = originalError;
22
+ }
23
+ }
9
24
 
10
25
  export class DatabaseManager implements IDatabaseProvider {
11
26
  private provider: IDatabaseProvider;
@@ -36,12 +51,17 @@ export class DatabaseManager implements IDatabaseProvider {
36
51
  } catch (error) {
37
52
  const errorMsg = error instanceof Error ? error.message : String(error);
38
53
 
54
+ // Check for native module version mismatch (NODE_MODULE_VERSION error)
55
+ if (error instanceof NativeModuleError || isNativeModuleVersionError(error)) {
56
+ console.warn('\n' + (error instanceof NativeModuleError ? error.message : getNativeModuleRecoveryMessage(error)));
57
+ console.warn(' Falling back to JSON storage (no data loss, just slower).\n');
58
+ }
39
59
  // Check if it's an npm cache error
40
- if (errorMsg.includes('ENOTEMPTY') || errorMsg.includes('better-sqlite3')) {
60
+ else if (errorMsg.includes('ENOTEMPTY') || errorMsg.includes('better-sqlite3')) {
41
61
  console.warn('⚠️ SQLite initialization failed due to npm cache error');
42
62
  console.warn(' Will attempt automatic recovery during initialize()');
43
63
  } else {
44
- console.warn('SQLite not available, falling back to JSON storage:', error);
64
+ console.warn('SQLite not available, falling back to JSON storage:', errorMsg);
45
65
  }
46
66
 
47
67
  // Fallback to JSON for now
@@ -177,6 +197,11 @@ class SQLiteProvider implements IDatabaseProvider {
177
197
  const Database = require('better-sqlite3');
178
198
  this.db = new Database(dbPath);
179
199
  } catch (error) {
200
+ // Check for native module version mismatch (NODE_MODULE_VERSION error)
201
+ if (isNativeModuleVersionError(error)) {
202
+ const recoveryMsg = getNativeModuleRecoveryMessage(error);
203
+ throw new NativeModuleError(recoveryMsg, error as Error);
204
+ }
180
205
  throw new Error('better-sqlite3 not available. Install with: npm install better-sqlite3');
181
206
  }
182
207
  }