claude-flow 2.7.19 → 2.7.21
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/simple-cli.js +173 -79
- package/dist/src/cli/simple-cli.js.map +1 -1
- package/dist/src/cli/validation-helper.js.map +1 -1
- package/dist/src/core/version.js +1 -1
- package/dist/src/reasoningbank/reasoningbank-adapter.js +22 -4
- package/dist/src/reasoningbank/reasoningbank-adapter.js.map +1 -1
- package/dist/src/utils/error-handler.js.map +1 -1
- package/dist/src/utils/key-redactor.js.map +1 -1
- package/docs/NPX_MEMORY_FIX_v2.7.19.md +305 -0
- package/package.json +3 -3
- package/scripts/fix-agentic-flow-sqlite.sh +30 -0
- package/src/reasoningbank/reasoningbank-adapter.js +30 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/validation-helper.
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/validation-helper.js"],"sourcesContent":["/**\n * CLI Parameter Validation Helper\n * Provides standardized error messages for invalid parameters\n */\n\nimport { HelpFormatter } from './help-formatter.js';\n\nexport class ValidationHelper {\n /**\n * Validate enum parameter\n */\n static validateEnum(value, paramName, validOptions, commandPath) {\n if (!validOptions.includes(value)) {\n console.error(\n HelpFormatter.formatValidationError(value, paramName, validOptions, commandPath),\n );\n process.exit(1);\n }\n }\n\n /**\n * Validate numeric parameter\n */\n static validateNumber(value, paramName, min, max, commandPath) {\n const num = parseInt(value, 10);\n\n if (isNaN(num)) {\n console.error(\n HelpFormatter.formatError(\n `'${value}' is not a valid number for ${paramName}.`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n\n if (min !== undefined && num < min) {\n console.error(\n HelpFormatter.formatError(\n `${paramName} must be at least ${min}. Got: ${num}`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n\n if (max !== undefined && num > max) {\n console.error(\n HelpFormatter.formatError(\n `${paramName} must be at most ${max}. Got: ${num}`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n\n return num;\n }\n\n /**\n * Validate required parameter\n */\n static validateRequired(value, paramName, commandPath) {\n if (!value || (typeof value === 'string' && value.trim() === '')) {\n console.error(\n HelpFormatter.formatError(\n `Missing required parameter: ${paramName}`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n }\n\n /**\n * Validate file path exists\n */\n static async validateFilePath(path, paramName, commandPath) {\n try {\n const fs = await import('fs/promises');\n await fs.access(path);\n } catch (error) {\n console.error(\n HelpFormatter.formatError(\n `File not found for ${paramName}: ${path}`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n }\n\n /**\n * Validate boolean flag\n */\n static validateBoolean(value, paramName, commandPath) {\n const lowerValue = value.toLowerCase();\n if (lowerValue === 'true' || lowerValue === '1' || lowerValue === 'yes') {\n return true;\n }\n if (lowerValue === 'false' || lowerValue === '0' || lowerValue === 'no') {\n return false;\n }\n\n console.error(\n HelpFormatter.formatError(\n `'${value}' is not a valid boolean for ${paramName}. Use: true, false, yes, no, 1, or 0.`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n}\n"],"names":["HelpFormatter","ValidationHelper","validateEnum","value","paramName","validOptions","commandPath","includes","console","error","formatValidationError","process","exit","validateNumber","min","max","num","parseInt","isNaN","formatError","undefined","validateRequired","trim","validateFilePath","path","fs","access","validateBoolean","lowerValue","toLowerCase"],"mappings":"AAKA,SAASA,aAAa,QAAQ,sBAAsB;AAEpD,OAAO,MAAMC;IAIX,OAAOC,aAAaC,KAAK,EAAEC,SAAS,EAAEC,YAAY,EAAEC,WAAW,EAAE;QAC/D,IAAI,CAACD,aAAaE,QAAQ,CAACJ,QAAQ;YACjCK,QAAQC,KAAK,CACXT,cAAcU,qBAAqB,CAACP,OAAOC,WAAWC,cAAcC;YAEtEK,QAAQC,IAAI,CAAC;QACf;IACF;IAKA,OAAOC,eAAeV,KAAK,EAAEC,SAAS,EAAEU,GAAG,EAAEC,GAAG,EAAET,WAAW,EAAE;QAC7D,MAAMU,MAAMC,SAASd,OAAO;QAE5B,IAAIe,MAAMF,MAAM;YACdR,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,CAAC,CAAC,EAAEhB,MAAM,4BAA4B,EAAEC,UAAU,CAAC,CAAC,EACpDE,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;QAEA,IAAIE,QAAQM,aAAaJ,MAAMF,KAAK;YAClCN,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,GAAGf,UAAU,kBAAkB,EAAEU,IAAI,OAAO,EAAEE,KAAK,EACnDV,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;QAEA,IAAIG,QAAQK,aAAaJ,MAAMD,KAAK;YAClCP,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,GAAGf,UAAU,iBAAiB,EAAEW,IAAI,OAAO,EAAEC,KAAK,EAClDV,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;QAEA,OAAOI;IACT;IAKA,OAAOK,iBAAiBlB,KAAK,EAAEC,SAAS,EAAEE,WAAW,EAAE;QACrD,IAAI,CAACH,SAAU,OAAOA,UAAU,YAAYA,MAAMmB,IAAI,OAAO,IAAK;YAChEd,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,CAAC,4BAA4B,EAAEf,WAAW,EAC1CE,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;IACF;IAKA,aAAaW,iBAAiBC,IAAI,EAAEpB,SAAS,EAAEE,WAAW,EAAE;QAC1D,IAAI;YACF,MAAMmB,KAAK,MAAM,MAAM,CAAC;YACxB,MAAMA,GAAGC,MAAM,CAACF;QAClB,EAAE,OAAOf,OAAO;YACdD,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,CAAC,mBAAmB,EAAEf,UAAU,EAAE,EAAEoB,MAAM,EAC1ClB,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;IACF;IAKA,OAAOe,gBAAgBxB,KAAK,EAAEC,SAAS,EAAEE,WAAW,EAAE;QACpD,MAAMsB,aAAazB,MAAM0B,WAAW;QACpC,IAAID,eAAe,UAAUA,eAAe,OAAOA,eAAe,OAAO;YACvE,OAAO;QACT;QACA,IAAIA,eAAe,WAAWA,eAAe,OAAOA,eAAe,MAAM;YACvE,OAAO;QACT;QAEApB,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,CAAC,CAAC,EAAEhB,MAAM,6BAA6B,EAAEC,UAAU,qCAAqC,CAAC,EACzFE,eAAe;QAGnBK,QAAQC,IAAI,CAAC;IACf;AACF"}MsB,aAAazB,MAAM0B,WAAW;QACpC,IAAID,eAAe,UAAUA,eAAe,OAAOA,eAAe,OAAO;YACvE,OAAO;QACT;QACA,IAAIA,eAAe,WAAWA,eAAe,OAAOA,eAAe,MAAM;YACvE,OAAO;QACT;QAEApB,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,CAAC,CAAC,EAAEhB,MAAM,6BAA6B,EAAEC,UAAU,qCAAqC,CAAC,EACzFE,eAAe;QAGnBK,QAAQC,IAAI,CAAC;IACf;AACF"}
|
package/dist/src/core/version.js
CHANGED
|
@@ -45,7 +45,10 @@ export async function initializeReasoningBank() {
|
|
|
45
45
|
return result;
|
|
46
46
|
}
|
|
47
47
|
export async function storeMemory(key, value, options = {}) {
|
|
48
|
-
await ensureInitialized();
|
|
48
|
+
const initialized = await ensureInitialized();
|
|
49
|
+
if (!initialized) {
|
|
50
|
+
throw new Error('ReasoningBank not available (better-sqlite3 missing). Use JSON mode instead.');
|
|
51
|
+
}
|
|
49
52
|
try {
|
|
50
53
|
const memoryId = options.id || uuidv4();
|
|
51
54
|
const memory = {
|
|
@@ -88,7 +91,10 @@ export async function queryMemories(searchQuery, options = {}) {
|
|
|
88
91
|
if (cached) {
|
|
89
92
|
return cached;
|
|
90
93
|
}
|
|
91
|
-
await ensureInitialized();
|
|
94
|
+
const initialized = await ensureInitialized();
|
|
95
|
+
if (!initialized) {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
92
98
|
const limit = options.limit || 10;
|
|
93
99
|
const namespace = options.namespace || options.domain || 'default';
|
|
94
100
|
try {
|
|
@@ -154,7 +160,10 @@ export async function queryMemories(searchQuery, options = {}) {
|
|
|
154
160
|
}
|
|
155
161
|
}
|
|
156
162
|
export async function listMemories(options = {}) {
|
|
157
|
-
await ensureInitialized();
|
|
163
|
+
const initialized = await ensureInitialized();
|
|
164
|
+
if (!initialized) {
|
|
165
|
+
return [];
|
|
166
|
+
}
|
|
158
167
|
const limit = options.limit || 10;
|
|
159
168
|
const namespace = options.namespace;
|
|
160
169
|
try {
|
|
@@ -180,7 +189,16 @@ export async function listMemories(options = {}) {
|
|
|
180
189
|
}
|
|
181
190
|
}
|
|
182
191
|
export async function getStatus() {
|
|
183
|
-
await ensureInitialized();
|
|
192
|
+
const initialized = await ensureInitialized();
|
|
193
|
+
if (!initialized) {
|
|
194
|
+
return {
|
|
195
|
+
total_memories: 0,
|
|
196
|
+
total_categories: 0,
|
|
197
|
+
storage_backend: 'Unavailable',
|
|
198
|
+
error: 'ReasoningBank initialization failed (better-sqlite3 not available)',
|
|
199
|
+
fallback_available: true
|
|
200
|
+
};
|
|
201
|
+
}
|
|
184
202
|
try {
|
|
185
203
|
const db = ReasoningBank.db.getDb();
|
|
186
204
|
const patterns = db.prepare("SELECT COUNT(*) as count FROM patterns WHERE type = 'reasoning_memory'").get();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/reasoningbank/reasoningbank-adapter.js"],"sourcesContent":["/**\n * ReasoningBank Adapter for Claude-Flow (Node.js Backend)\n *\n * Uses agentic-flow@1.5.13 Node.js backend with SQLite for persistent storage\n * Provides semantic search via embeddings and MMR ranking\n *\n * Backend: SQLite with better-sqlite3\n * Features: Persistent storage, semantic search, memory consolidation\n */\n\nimport * as ReasoningBank from 'agentic-flow/reasoningbank';\nimport { v4 as uuidv4 } from 'uuid';\n\n// Backend instance (singleton)\nlet backendInitialized = false;\nlet initPromise = null;\n\n// Query result cache (LRU)\nconst queryCache = new Map();\nconst CACHE_SIZE = 100;\nconst CACHE_TTL = 60000; // 60 seconds\n\n/**\n * Initialize ReasoningBank Node.js backend\n * @returns {Promise<boolean>}\n */\nasync function ensureInitialized() {\n if (backendInitialized) {\n return true;\n }\n\n if (initPromise) {\n return initPromise;\n }\n\n initPromise = (async () => {\n try {\n // Initialize Node.js backend with SQLite database\n await ReasoningBank.initialize();\n backendInitialized = true;\n console.log('[ReasoningBank] Node.js backend initialized successfully');\n return true;\n } catch (error) {\n // Check if this is the better-sqlite3 missing error (npx issue)\n const isSqliteError = error.message?.includes('BetterSqlite3 is not a constructor') ||\n error.message?.includes('better-sqlite3') ||\n error.message?.includes('could not run migrations');\n const isNpx = process.env.npm_config_user_agent?.includes('npx') ||\n process.cwd().includes('_npx');\n\n if (isSqliteError && isNpx) {\n // NPX limitation - show helpful message but DON'T throw\n // This allows the command to fall back to JSON mode\n console.error('\\n⚠️ NPX LIMITATION DETECTED\\n');\n console.error('ReasoningBank requires better-sqlite3, which is not available in npx temp directories.\\n');\n console.error('📚 Solutions:\\n');\n console.error(' 1. LOCAL INSTALL (Recommended):');\n console.error(' npm install && node_modules/.bin/claude-flow memory store \"key\" \"value\"\\n');\n console.error(' 2. USE MCP TOOLS instead:');\n console.error(' mcp__claude-flow__memory_usage({ action: \"store\", key: \"test\", value: \"data\" })\\n');\n console.error(' 3. USE JSON FALLBACK (automatic):');\n console.error(' Command will continue with JSON storage...\\n');\n console.error('See: docs/MEMORY_COMMAND_FIX.md for details\\n');\n\n // Return false to signal initialization failed but allow fallback\n return false;\n }\n\n // Not npx or not SQLite error - log and throw\n console.error('[ReasoningBank] Backend initialization failed:', error);\n throw new Error(`Failed to initialize ReasoningBank: ${error.message}`);\n }\n })();\n\n return initPromise;\n}\n\n/**\n * Initialize ReasoningBank database (Node.js version)\n * Returns true if initialized, false if failed (allows fallback)\n */\nexport async function initializeReasoningBank() {\n // Initialize the Node.js backend\n const result = await ensureInitialized();\n return result;\n}\n\n/**\n * Store a memory in ReasoningBank (Node.js backend with SQLite)\n *\n * Maps claude-flow memory model to ReasoningBank pattern model:\n * - key -> title\n * - value -> content (searchable text)\n * - namespace -> domain\n * - confidence -> confidence score\n */\nexport async function storeMemory(key, value, options = {}) {\n await ensureInitialized();\n\n try {\n const memoryId = options.id || uuidv4();\n\n // Map our memory model to ReasoningBank pattern model\n const memory = {\n id: memoryId,\n type: 'reasoning_memory',\n pattern_data: {\n title: key,\n content: value,\n domain: options.namespace || 'default',\n agent: options.agent || 'memory-agent',\n task_type: options.type || 'fact',\n // Store original values for compatibility\n original_key: key,\n original_value: value,\n namespace: options.namespace || 'default'\n },\n confidence: options.confidence || 0.8,\n usage_count: 0\n };\n\n // Store memory using Node.js backend\n ReasoningBank.db.upsertMemory(memory);\n\n // Generate and store embedding for semantic search\n try {\n const embedding = await ReasoningBank.computeEmbedding(value);\n ReasoningBank.db.upsertEmbedding({\n id: memoryId,\n model: 'text-embedding-3-small', // Default model\n dims: embedding.length,\n vector: embedding\n });\n } catch (embeddingError) {\n console.warn('[ReasoningBank] Failed to generate embedding:', embeddingError.message);\n // Continue without embedding - memory is still stored\n }\n\n // Invalidate query cache when new memory is added\n queryCache.clear();\n\n return memoryId;\n } catch (error) {\n console.error('[ReasoningBank] storeMemory failed:', error);\n throw new Error(`Failed to store memory: ${error.message}`);\n }\n}\n\n/**\n * Query memories from ReasoningBank (Node.js backend with semantic search)\n *\n * Uses retrieveMemories for semantic search via embeddings and MMR ranking\n * Fallback to database query if semantic search fails\n */\nexport async function queryMemories(searchQuery, options = {}) {\n // Check cache first\n const cached = getCachedQuery(searchQuery, options);\n if (cached) {\n return cached;\n }\n\n await ensureInitialized();\n const limit = options.limit || 10;\n // Accept both 'namespace' and 'domain' for compatibility\n const namespace = options.namespace || options.domain || 'default';\n\n try {\n // Try semantic search first using retrieveMemories\n const results = await ReasoningBank.retrieveMemories(searchQuery, {\n domain: namespace,\n agent: options.agent || 'query-agent',\n k: limit,\n minConfidence: options.minConfidence || 0.3\n });\n\n // Map backend results to our memory format\n // retrieveMemories returns: { id, title, content, description, score, components }\n const memories = results.map(memory => ({\n id: memory.id,\n key: memory.title || 'unknown',\n value: memory.content || memory.description || '',\n namespace: namespace, // Use the namespace from our query\n confidence: memory.components?.reliability || 0.8,\n usage_count: memory.usage_count || 0,\n created_at: memory.created_at || new Date().toISOString(),\n score: memory.score || 0,\n // Include original pattern for debugging\n _pattern: memory\n }));\n\n // If no results, try direct database query as fallback\n if (memories.length === 0) {\n console.warn('[ReasoningBank] Semantic search returned 0 results, trying database fallback');\n const fallbackResults = ReasoningBank.db.fetchMemoryCandidates({\n domain: namespace,\n minConfidence: options.minConfidence || 0.3\n });\n\n const fallbackMemories = fallbackResults.slice(0, limit).map(memory => ({\n id: memory.id,\n key: memory.pattern_data?.title || memory.pattern_data?.original_key || 'unknown',\n value: memory.pattern_data?.content || memory.pattern_data?.original_value || '',\n namespace: memory.pattern_data?.domain || memory.pattern_data?.namespace || 'default',\n confidence: memory.confidence || 0.8,\n usage_count: memory.usage_count || 0,\n created_at: memory.created_at || new Date().toISOString()\n }));\n\n // Cache and return fallback results\n setCachedQuery(searchQuery, options, fallbackMemories);\n return fallbackMemories;\n }\n\n // Cache successful results\n setCachedQuery(searchQuery, options, memories);\n return memories;\n } catch (error) {\n console.warn('[ReasoningBank] Query failed, trying database fallback:', error.message);\n\n try {\n // Final fallback: direct database query\n const fallbackResults = ReasoningBank.db.fetchMemoryCandidates({\n domain: namespace,\n minConfidence: options.minConfidence || 0.3\n });\n\n const fallbackMemories = fallbackResults.slice(0, limit).map(memory => ({\n id: memory.id,\n key: memory.pattern_data?.title || 'unknown',\n value: memory.pattern_data?.content || '',\n namespace: memory.pattern_data?.domain || 'default',\n confidence: memory.confidence || 0.8,\n usage_count: memory.usage_count || 0,\n created_at: memory.created_at || new Date().toISOString()\n }));\n\n setCachedQuery(searchQuery, options, fallbackMemories);\n return fallbackMemories;\n } catch (fallbackError) {\n console.error('[ReasoningBank] All query methods failed:', fallbackError);\n return [];\n }\n }\n}\n\n/**\n * List all memories (using Node.js backend database query)\n */\nexport async function listMemories(options = {}) {\n await ensureInitialized();\n const limit = options.limit || 10;\n const namespace = options.namespace;\n\n try {\n let memories;\n\n if (namespace && namespace !== 'default') {\n // Filter by namespace/domain\n const allMemories = ReasoningBank.db.getAllActiveMemories();\n memories = allMemories\n .filter(m => m.pattern_data?.domain === namespace)\n .slice(0, limit);\n } else {\n // Get all active memories\n memories = ReasoningBank.db.getAllActiveMemories().slice(0, limit);\n }\n\n return memories.map(memory => ({\n id: memory.id,\n key: memory.pattern_data?.title || memory.pattern_data?.original_key || 'unknown',\n value: memory.pattern_data?.content || memory.pattern_data?.original_value || '',\n namespace: memory.pattern_data?.domain || memory.pattern_data?.namespace || 'default',\n confidence: memory.confidence || 0.8,\n usage_count: memory.usage_count || 0,\n created_at: memory.created_at || new Date().toISOString()\n }));\n } catch (error) {\n console.error('[ReasoningBank] listMemories failed:', error);\n return [];\n }\n}\n\n/**\n * Get ReasoningBank statistics (Node.js backend)\n */\nexport async function getStatus() {\n await ensureInitialized();\n\n try {\n const db = ReasoningBank.db.getDb();\n\n // Count patterns\n const patterns = db.prepare(\"SELECT COUNT(*) as count FROM patterns WHERE type = 'reasoning_memory'\").get();\n const embeddings = db.prepare(\"SELECT COUNT(*) as count FROM pattern_embeddings\").get();\n const trajectories = db.prepare(\"SELECT COUNT(*) as count FROM task_trajectories\").get();\n const links = db.prepare(\"SELECT COUNT(*) as count FROM pattern_links\").get();\n\n // Get average confidence\n const avgConf = db.prepare(\"SELECT AVG(confidence) as avg FROM patterns WHERE type = 'reasoning_memory'\").get();\n\n // Count unique domains\n const domains = db.prepare(\"SELECT COUNT(DISTINCT json_extract(pattern_data, '$.domain')) as count FROM patterns WHERE type = 'reasoning_memory'\").get();\n\n return {\n total_memories: patterns.count || 0,\n total_categories: domains.count || 0,\n storage_backend: 'SQLite (Node.js)',\n database_path: process.env.CLAUDE_FLOW_DB_PATH || '.swarm/memory.db',\n performance: 'SQLite with persistent storage',\n avg_confidence: avgConf.avg || 0.8,\n total_embeddings: embeddings.count || 0,\n total_trajectories: trajectories.count || 0,\n total_links: links.count || 0\n };\n } catch (error) {\n console.error('[ReasoningBank] getStatus failed:', error);\n return {\n total_memories: 0,\n error: error.message\n };\n }\n}\n\n/**\n * Check which ReasoningBank tables are present (Node.js backend)\n */\nexport async function checkReasoningBankTables() {\n try {\n await ensureInitialized();\n const db = ReasoningBank.db.getDb();\n\n const tables = db.prepare(\"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'pattern%'\").all();\n const tableNames = tables.map(t => t.name);\n\n const requiredTables = ['patterns', 'pattern_embeddings', 'pattern_links', 'task_trajectories'];\n const missingTables = requiredTables.filter(t => !tableNames.includes(t));\n\n return {\n exists: true,\n existingTables: tableNames,\n missingTables: missingTables,\n requiredTables: requiredTables,\n backend: 'SQLite (Node.js)',\n note: missingTables.length > 0 ? 'Some tables are missing - run migrations' : 'All tables present'\n };\n } catch (error) {\n return {\n exists: false,\n existingTables: [],\n missingTables: [],\n requiredTables: [],\n error: error.message\n };\n }\n}\n\n/**\n * Migrate existing database (Node.js backend - run migrations)\n */\nexport async function migrateReasoningBank() {\n try {\n await ReasoningBank.db.runMigrations();\n\n return {\n success: true,\n message: 'Database migrations completed successfully',\n migrated: true,\n database_path: process.env.CLAUDE_FLOW_DB_PATH || '.swarm/memory.db'\n };\n } catch (error) {\n return {\n success: false,\n message: `Migration failed: ${error.message}`,\n error: error.message\n };\n }\n}\n\n/**\n * Get cached query results\n */\nfunction getCachedQuery(searchQuery, options) {\n const cacheKey = JSON.stringify({ searchQuery, options });\n const cached = queryCache.get(cacheKey);\n\n if (cached && Date.now() - cached.timestamp < CACHE_TTL) {\n return cached.results;\n }\n\n return null;\n}\n\n/**\n * Set cached query results (LRU eviction)\n */\nfunction setCachedQuery(searchQuery, options, results) {\n const cacheKey = JSON.stringify({ searchQuery, options });\n\n // LRU eviction\n if (queryCache.size >= CACHE_SIZE) {\n const firstKey = queryCache.keys().next().value;\n queryCache.delete(firstKey);\n }\n\n queryCache.set(cacheKey, {\n results,\n timestamp: Date.now()\n });\n}\n\n/**\n * Close database connection and cleanup resources\n * Should be called when done with ReasoningBank operations\n */\nexport function cleanup() {\n try {\n if (backendInitialized) {\n // Clear embedding cache (prevents memory leaks)\n ReasoningBank.clearEmbeddingCache();\n\n // Close database connection\n ReasoningBank.db.closeDb();\n backendInitialized = false;\n initPromise = null;\n console.log('[ReasoningBank] Database connection closed');\n }\n } catch (error) {\n console.error('[ReasoningBank] Cleanup failed:', error.message);\n }\n}\n"],"names":["ReasoningBank","v4","uuidv4","backendInitialized","initPromise","queryCache","Map","CACHE_SIZE","CACHE_TTL","ensureInitialized","initialize","console","log","error","isSqliteError","message","includes","isNpx","process","env","npm_config_user_agent","cwd","Error","initializeReasoningBank","result","storeMemory","key","value","options","memoryId","id","memory","type","pattern_data","title","content","domain","namespace","agent","task_type","original_key","original_value","confidence","usage_count","db","upsertMemory","embedding","computeEmbedding","upsertEmbedding","model","dims","length","vector","embeddingError","warn","clear","queryMemories","searchQuery","cached","getCachedQuery","limit","results","retrieveMemories","k","minConfidence","memories","map","description","components","reliability","created_at","Date","toISOString","score","_pattern","fallbackResults","fetchMemoryCandidates","fallbackMemories","slice","setCachedQuery","fallbackError","listMemories","allMemories","getAllActiveMemories","filter","m","getStatus","getDb","patterns","prepare","get","embeddings","trajectories","links","avgConf","domains","total_memories","count","total_categories","storage_backend","database_path","CLAUDE_FLOW_DB_PATH","performance","avg_confidence","avg","total_embeddings","total_trajectories","total_links","checkReasoningBankTables","tables","all","tableNames","t","name","requiredTables","missingTables","exists","existingTables","backend","note","migrateReasoningBank","runMigrations","success","migrated","cacheKey","JSON","stringify","now","timestamp","size","firstKey","keys","next","delete","set","cleanup","clearEmbeddingCache","closeDb"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/reasoningbank/reasoningbank-adapter.js"],"sourcesContent":["/**\n * ReasoningBank Adapter for Claude-Flow (Node.js Backend)\n *\n * Uses agentic-flow@1.5.13 Node.js backend with SQLite for persistent storage\n * Provides semantic search via embeddings and MMR ranking\n *\n * Backend: SQLite with better-sqlite3\n * Features: Persistent storage, semantic search, memory consolidation\n */\n\nimport * as ReasoningBank from 'agentic-flow/reasoningbank';\nimport { v4 as uuidv4 } from 'uuid';\n\n// Backend instance (singleton)\nlet backendInitialized = false;\nlet initPromise = null;\n\n// Query result cache (LRU)\nconst queryCache = new Map();\nconst CACHE_SIZE = 100;\nconst CACHE_TTL = 60000; // 60 seconds\n\n/**\n * Initialize ReasoningBank Node.js backend\n * @returns {Promise<boolean>}\n */\nasync function ensureInitialized() {\n if (backendInitialized) {\n return true;\n }\n\n if (initPromise) {\n return initPromise;\n }\n\n initPromise = (async () => {\n try {\n // Initialize Node.js backend with SQLite database\n await ReasoningBank.initialize();\n backendInitialized = true;\n console.log('[ReasoningBank] Node.js backend initialized successfully');\n return true;\n } catch (error) {\n // Check if this is the better-sqlite3 missing error (npx issue)\n const isSqliteError = error.message?.includes('BetterSqlite3 is not a constructor') ||\n error.message?.includes('better-sqlite3') ||\n error.message?.includes('could not run migrations');\n const isNpx = process.env.npm_config_user_agent?.includes('npx') ||\n process.cwd().includes('_npx');\n\n if (isSqliteError && isNpx) {\n // NPX limitation - show helpful message but DON'T throw\n // This allows the command to fall back to JSON mode\n console.error('\\n⚠️ NPX LIMITATION DETECTED\\n');\n console.error('ReasoningBank requires better-sqlite3, which is not available in npx temp directories.\\n');\n console.error('📚 Solutions:\\n');\n console.error(' 1. LOCAL INSTALL (Recommended):');\n console.error(' npm install && node_modules/.bin/claude-flow memory store \"key\" \"value\"\\n');\n console.error(' 2. USE MCP TOOLS instead:');\n console.error(' mcp__claude-flow__memory_usage({ action: \"store\", key: \"test\", value: \"data\" })\\n');\n console.error(' 3. USE JSON FALLBACK (automatic):');\n console.error(' Command will continue with JSON storage...\\n');\n console.error('See: docs/MEMORY_COMMAND_FIX.md for details\\n');\n\n // Return false to signal initialization failed but allow fallback\n return false;\n }\n\n // Not npx or not SQLite error - log and throw\n console.error('[ReasoningBank] Backend initialization failed:', error);\n throw new Error(`Failed to initialize ReasoningBank: ${error.message}`);\n }\n })();\n\n return initPromise;\n}\n\n/**\n * Initialize ReasoningBank database (Node.js version)\n * Returns true if initialized, false if failed (allows fallback)\n */\nexport async function initializeReasoningBank() {\n // Initialize the Node.js backend\n const result = await ensureInitialized();\n return result;\n}\n\n/**\n * Store a memory in ReasoningBank (Node.js backend with SQLite)\n *\n * Maps claude-flow memory model to ReasoningBank pattern model:\n * - key -> title\n * - value -> content (searchable text)\n * - namespace -> domain\n * - confidence -> confidence score\n */\nexport async function storeMemory(key, value, options = {}) {\n const initialized = await ensureInitialized();\n\n // If initialization failed, throw with clear message\n if (!initialized) {\n throw new Error('ReasoningBank not available (better-sqlite3 missing). Use JSON mode instead.');\n }\n\n try {\n const memoryId = options.id || uuidv4();\n\n // Map our memory model to ReasoningBank pattern model\n const memory = {\n id: memoryId,\n type: 'reasoning_memory',\n pattern_data: {\n title: key,\n content: value,\n domain: options.namespace || 'default',\n agent: options.agent || 'memory-agent',\n task_type: options.type || 'fact',\n // Store original values for compatibility\n original_key: key,\n original_value: value,\n namespace: options.namespace || 'default'\n },\n confidence: options.confidence || 0.8,\n usage_count: 0\n };\n\n // Store memory using Node.js backend\n ReasoningBank.db.upsertMemory(memory);\n\n // Generate and store embedding for semantic search\n try {\n const embedding = await ReasoningBank.computeEmbedding(value);\n ReasoningBank.db.upsertEmbedding({\n id: memoryId,\n model: 'text-embedding-3-small', // Default model\n dims: embedding.length,\n vector: embedding\n });\n } catch (embeddingError) {\n console.warn('[ReasoningBank] Failed to generate embedding:', embeddingError.message);\n // Continue without embedding - memory is still stored\n }\n\n // Invalidate query cache when new memory is added\n queryCache.clear();\n\n return memoryId;\n } catch (error) {\n console.error('[ReasoningBank] storeMemory failed:', error);\n throw new Error(`Failed to store memory: ${error.message}`);\n }\n}\n\n/**\n * Query memories from ReasoningBank (Node.js backend with semantic search)\n *\n * Uses retrieveMemories for semantic search via embeddings and MMR ranking\n * Fallback to database query if semantic search fails\n */\nexport async function queryMemories(searchQuery, options = {}) {\n // Check cache first\n const cached = getCachedQuery(searchQuery, options);\n if (cached) {\n return cached;\n }\n\n const initialized = await ensureInitialized();\n\n // If initialization failed, return empty results\n if (!initialized) {\n return [];\n }\n const limit = options.limit || 10;\n // Accept both 'namespace' and 'domain' for compatibility\n const namespace = options.namespace || options.domain || 'default';\n\n try {\n // Try semantic search first using retrieveMemories\n const results = await ReasoningBank.retrieveMemories(searchQuery, {\n domain: namespace,\n agent: options.agent || 'query-agent',\n k: limit,\n minConfidence: options.minConfidence || 0.3\n });\n\n // Map backend results to our memory format\n // retrieveMemories returns: { id, title, content, description, score, components }\n const memories = results.map(memory => ({\n id: memory.id,\n key: memory.title || 'unknown',\n value: memory.content || memory.description || '',\n namespace: namespace, // Use the namespace from our query\n confidence: memory.components?.reliability || 0.8,\n usage_count: memory.usage_count || 0,\n created_at: memory.created_at || new Date().toISOString(),\n score: memory.score || 0,\n // Include original pattern for debugging\n _pattern: memory\n }));\n\n // If no results, try direct database query as fallback\n if (memories.length === 0) {\n console.warn('[ReasoningBank] Semantic search returned 0 results, trying database fallback');\n const fallbackResults = ReasoningBank.db.fetchMemoryCandidates({\n domain: namespace,\n minConfidence: options.minConfidence || 0.3\n });\n\n const fallbackMemories = fallbackResults.slice(0, limit).map(memory => ({\n id: memory.id,\n key: memory.pattern_data?.title || memory.pattern_data?.original_key || 'unknown',\n value: memory.pattern_data?.content || memory.pattern_data?.original_value || '',\n namespace: memory.pattern_data?.domain || memory.pattern_data?.namespace || 'default',\n confidence: memory.confidence || 0.8,\n usage_count: memory.usage_count || 0,\n created_at: memory.created_at || new Date().toISOString()\n }));\n\n // Cache and return fallback results\n setCachedQuery(searchQuery, options, fallbackMemories);\n return fallbackMemories;\n }\n\n // Cache successful results\n setCachedQuery(searchQuery, options, memories);\n return memories;\n } catch (error) {\n console.warn('[ReasoningBank] Query failed, trying database fallback:', error.message);\n\n try {\n // Final fallback: direct database query\n const fallbackResults = ReasoningBank.db.fetchMemoryCandidates({\n domain: namespace,\n minConfidence: options.minConfidence || 0.3\n });\n\n const fallbackMemories = fallbackResults.slice(0, limit).map(memory => ({\n id: memory.id,\n key: memory.pattern_data?.title || 'unknown',\n value: memory.pattern_data?.content || '',\n namespace: memory.pattern_data?.domain || 'default',\n confidence: memory.confidence || 0.8,\n usage_count: memory.usage_count || 0,\n created_at: memory.created_at || new Date().toISOString()\n }));\n\n setCachedQuery(searchQuery, options, fallbackMemories);\n return fallbackMemories;\n } catch (fallbackError) {\n console.error('[ReasoningBank] All query methods failed:', fallbackError);\n return [];\n }\n }\n}\n\n/**\n * List all memories (using Node.js backend database query)\n */\nexport async function listMemories(options = {}) {\n const initialized = await ensureInitialized();\n\n // If initialization failed, return empty list\n if (!initialized) {\n return [];\n }\n const limit = options.limit || 10;\n const namespace = options.namespace;\n\n try {\n let memories;\n\n if (namespace && namespace !== 'default') {\n // Filter by namespace/domain\n const allMemories = ReasoningBank.db.getAllActiveMemories();\n memories = allMemories\n .filter(m => m.pattern_data?.domain === namespace)\n .slice(0, limit);\n } else {\n // Get all active memories\n memories = ReasoningBank.db.getAllActiveMemories().slice(0, limit);\n }\n\n return memories.map(memory => ({\n id: memory.id,\n key: memory.pattern_data?.title || memory.pattern_data?.original_key || 'unknown',\n value: memory.pattern_data?.content || memory.pattern_data?.original_value || '',\n namespace: memory.pattern_data?.domain || memory.pattern_data?.namespace || 'default',\n confidence: memory.confidence || 0.8,\n usage_count: memory.usage_count || 0,\n created_at: memory.created_at || new Date().toISOString()\n }));\n } catch (error) {\n console.error('[ReasoningBank] listMemories failed:', error);\n return [];\n }\n}\n\n/**\n * Get ReasoningBank statistics (Node.js backend)\n */\nexport async function getStatus() {\n const initialized = await ensureInitialized();\n\n // If initialization failed, return error status\n if (!initialized) {\n return {\n total_memories: 0,\n total_categories: 0,\n storage_backend: 'Unavailable',\n error: 'ReasoningBank initialization failed (better-sqlite3 not available)',\n fallback_available: true\n };\n }\n\n try {\n const db = ReasoningBank.db.getDb();\n\n // Count patterns\n const patterns = db.prepare(\"SELECT COUNT(*) as count FROM patterns WHERE type = 'reasoning_memory'\").get();\n const embeddings = db.prepare(\"SELECT COUNT(*) as count FROM pattern_embeddings\").get();\n const trajectories = db.prepare(\"SELECT COUNT(*) as count FROM task_trajectories\").get();\n const links = db.prepare(\"SELECT COUNT(*) as count FROM pattern_links\").get();\n\n // Get average confidence\n const avgConf = db.prepare(\"SELECT AVG(confidence) as avg FROM patterns WHERE type = 'reasoning_memory'\").get();\n\n // Count unique domains\n const domains = db.prepare(\"SELECT COUNT(DISTINCT json_extract(pattern_data, '$.domain')) as count FROM patterns WHERE type = 'reasoning_memory'\").get();\n\n return {\n total_memories: patterns.count || 0,\n total_categories: domains.count || 0,\n storage_backend: 'SQLite (Node.js)',\n database_path: process.env.CLAUDE_FLOW_DB_PATH || '.swarm/memory.db',\n performance: 'SQLite with persistent storage',\n avg_confidence: avgConf.avg || 0.8,\n total_embeddings: embeddings.count || 0,\n total_trajectories: trajectories.count || 0,\n total_links: links.count || 0\n };\n } catch (error) {\n console.error('[ReasoningBank] getStatus failed:', error);\n return {\n total_memories: 0,\n error: error.message\n };\n }\n}\n\n/**\n * Check which ReasoningBank tables are present (Node.js backend)\n */\nexport async function checkReasoningBankTables() {\n try {\n await ensureInitialized();\n const db = ReasoningBank.db.getDb();\n\n const tables = db.prepare(\"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'pattern%'\").all();\n const tableNames = tables.map(t => t.name);\n\n const requiredTables = ['patterns', 'pattern_embeddings', 'pattern_links', 'task_trajectories'];\n const missingTables = requiredTables.filter(t => !tableNames.includes(t));\n\n return {\n exists: true,\n existingTables: tableNames,\n missingTables: missingTables,\n requiredTables: requiredTables,\n backend: 'SQLite (Node.js)',\n note: missingTables.length > 0 ? 'Some tables are missing - run migrations' : 'All tables present'\n };\n } catch (error) {\n return {\n exists: false,\n existingTables: [],\n missingTables: [],\n requiredTables: [],\n error: error.message\n };\n }\n}\n\n/**\n * Migrate existing database (Node.js backend - run migrations)\n */\nexport async function migrateReasoningBank() {\n try {\n await ReasoningBank.db.runMigrations();\n\n return {\n success: true,\n message: 'Database migrations completed successfully',\n migrated: true,\n database_path: process.env.CLAUDE_FLOW_DB_PATH || '.swarm/memory.db'\n };\n } catch (error) {\n return {\n success: false,\n message: `Migration failed: ${error.message}`,\n error: error.message\n };\n }\n}\n\n/**\n * Get cached query results\n */\nfunction getCachedQuery(searchQuery, options) {\n const cacheKey = JSON.stringify({ searchQuery, options });\n const cached = queryCache.get(cacheKey);\n\n if (cached && Date.now() - cached.timestamp < CACHE_TTL) {\n return cached.results;\n }\n\n return null;\n}\n\n/**\n * Set cached query results (LRU eviction)\n */\nfunction setCachedQuery(searchQuery, options, results) {\n const cacheKey = JSON.stringify({ searchQuery, options });\n\n // LRU eviction\n if (queryCache.size >= CACHE_SIZE) {\n const firstKey = queryCache.keys().next().value;\n queryCache.delete(firstKey);\n }\n\n queryCache.set(cacheKey, {\n results,\n timestamp: Date.now()\n });\n}\n\n/**\n * Close database connection and cleanup resources\n * Should be called when done with ReasoningBank operations\n */\nexport function cleanup() {\n try {\n if (backendInitialized) {\n // Clear embedding cache (prevents memory leaks)\n ReasoningBank.clearEmbeddingCache();\n\n // Close database connection\n ReasoningBank.db.closeDb();\n backendInitialized = false;\n initPromise = null;\n console.log('[ReasoningBank] Database connection closed');\n }\n } catch (error) {\n console.error('[ReasoningBank] Cleanup failed:', error.message);\n }\n}\n"],"names":["ReasoningBank","v4","uuidv4","backendInitialized","initPromise","queryCache","Map","CACHE_SIZE","CACHE_TTL","ensureInitialized","initialize","console","log","error","isSqliteError","message","includes","isNpx","process","env","npm_config_user_agent","cwd","Error","initializeReasoningBank","result","storeMemory","key","value","options","initialized","memoryId","id","memory","type","pattern_data","title","content","domain","namespace","agent","task_type","original_key","original_value","confidence","usage_count","db","upsertMemory","embedding","computeEmbedding","upsertEmbedding","model","dims","length","vector","embeddingError","warn","clear","queryMemories","searchQuery","cached","getCachedQuery","limit","results","retrieveMemories","k","minConfidence","memories","map","description","components","reliability","created_at","Date","toISOString","score","_pattern","fallbackResults","fetchMemoryCandidates","fallbackMemories","slice","setCachedQuery","fallbackError","listMemories","allMemories","getAllActiveMemories","filter","m","getStatus","total_memories","total_categories","storage_backend","fallback_available","getDb","patterns","prepare","get","embeddings","trajectories","links","avgConf","domains","count","database_path","CLAUDE_FLOW_DB_PATH","performance","avg_confidence","avg","total_embeddings","total_trajectories","total_links","checkReasoningBankTables","tables","all","tableNames","t","name","requiredTables","missingTables","exists","existingTables","backend","note","migrateReasoningBank","runMigrations","success","migrated","cacheKey","JSON","stringify","now","timestamp","size","firstKey","keys","next","delete","set","cleanup","clearEmbeddingCache","closeDb"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/error-handler.
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/error-handler.js"],"sourcesContent":["// Re-export from TypeScript file\nexport * from './error-handler.ts';\n"],"names":[],"mappings":"AACA,cAAc,qBAAqB"}rorStack as getErrorStk,\n isError as isErr,\n} from './type-guards.js';\n\nexport class AppError extends Error {\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n ) {\n super(message);\n this.name = 'AppError';\n Object.setPrototypeOf(this, AppError.prototype);\n }\n}\n\n// Re-export from type-guards for backward compatibility\nexport const isError = isErr;\nexport const getErrorMessage = getErrorMsg;\nexport const getErrorStack = getErrorStk;\n\nexport function handleError(error: unknown, context?: string): never {\n const message = getErrorMessage(error);\n const stack = getErrorStack(error);\n\n console.error(`Error${context ? ` in ${context}` : ''}: ${message}`);\n if (stack && process.env.NODE_ENV === 'development') {\n console.error('Stack trace:', stack);\n }\n\n process.exit(1);\n}\n"],"names":["getErrorMessage","getErrorMsg","getErrorStack","getErrorStk","isError","isErr","AppError","Error","message","code","statusCode","name","Object","setPrototypeOf","prototype","handleError","error","context","stack","console","process","env","NODE_ENV","exit"],"mappings":"AAIA,SACEA,mBAAmBC,WAAW,EAC9BC,iBAAiBC,WAAW,EAC5BC,WAAWC,KAAK,QACX,mBAAmB;AAE1B,OAAO,MAAMC,iBAAiBC;;;IAC5B,YACEC,OAAe,EACf,AAAOC,IAAa,EACpB,AAAOC,UAAmB,CAC1B;QACA,KAAK,CAACF,eAHCC,OAAAA,WACAC,aAAAA;QAGP,IAAI,CAACC,IAAI,GAAG;QACZC,OAAOC,cAAc,CAAC,IAAI,EAAEP,SAASQ,SAAS;IAChD;AACF;AAGA,OAAO,MAAMV,UAAUC,MAAM;AAC7B,OAAO,MAAML,kBAAkBC,YAAY;AAC3C,OAAO,MAAMC,gBAAgBC,YAAY;AAEzC,OAAO,SAASY,YAAYC,KAAc,EAAEC,OAAgB;IAC1D,MAAMT,UAAUR,gBAAgBgB;IAChC,MAAME,QAAQhB,cAAcc;IAE5BG,QAAQH,KAAK,CAAC,CAAC,KAAK,EAAEC,UAAU,CAAC,IAAI,EAAEA,SAAS,GAAG,GAAG,EAAE,EAAET,SAAS;IACnE,IAAIU,SAASE,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;QACnDH,QAAQH,KAAK,CAAC,gBAAgBE;IAChC;IAEAE,QAAQG,IAAI,CAAC;AACf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/key-redactor.js"],"sourcesContent":["/**\n * API Key Redaction Utility\n * Prevents sensitive data from leaking into logs, memory, or git commits\n */\n\nexport class KeyRedactor {\n static API_KEY_PATTERNS = [\n // Anthropic API keys\n /sk-ant-[a-zA-Z0-9_-]{95,}/gi,\n\n // OpenRouter API keys\n /sk-or-[a-zA-Z0-9_-]{32,}/gi,\n\n // Google/Gemini API keys\n /AIza[a-zA-Z0-9_-]{35}/gi,\n\n // Generic API keys\n /[a-zA-Z0-9_-]{20,}API[a-zA-Z0-9_-]{20,}/gi,\n\n // Bearer tokens\n /Bearer\\s+[a-zA-Z0-9_\\-\\.]{20,}/gi,\n\n // Environment variable format\n /([A-Z_]+_API_KEY|[A-Z_]+_TOKEN|[A-Z_]+_SECRET)=[\"']?([^\"'\\s]+)[\"']?/gi,\n\n // Supabase keys\n /eyJ[a-zA-Z0-9_-]*\\.eyJ[a-zA-Z0-9_-]*\\.[a-zA-Z0-9_-]*/gi,\n ];\n\n static SENSITIVE_FIELDS = [\n 'apiKey',\n 'api_key',\n 'token',\n 'secret',\n 'password',\n 'private_key',\n 'privateKey',\n 'accessToken',\n 'access_token',\n 'refreshToken',\n 'refresh_token',\n ];\n\n /**\n * Redact API keys and sensitive data from text\n */\n static redact(text, showPrefix = true) {\n if (!text) return text;\n\n let redacted = text;\n\n // Redact using patterns\n this.API_KEY_PATTERNS.forEach(pattern => {\n redacted = redacted.replace(pattern, (match) => {\n if (showPrefix && match.length > 8) {\n const prefix = match.substring(0, 8);\n return `${prefix}...[REDACTED]`;\n }\n return '[REDACTED_API_KEY]';\n });\n });\n\n return redacted;\n }\n\n /**\n * Redact sensitive fields in objects\n */\n static redactObject(obj, deep = true) {\n if (!obj || typeof obj !== 'object') return obj;\n\n const redacted = { ...obj };\n\n Object.keys(redacted).forEach(key => {\n const lowerKey = key.toLowerCase();\n\n // Check if field name is sensitive\n const isSensitive = this.SENSITIVE_FIELDS.some(field =>\n lowerKey.includes(field)\n );\n\n if (isSensitive && typeof redacted[key] === 'string') {\n const value = redacted[key];\n if (value && value.length > 8) {\n redacted[key] = `${value.substring(0, 4)}...[REDACTED]`;\n } else {\n redacted[key] = '[REDACTED]';\n }\n } else if (deep && typeof redacted[key] === 'object' && redacted[key] !== null) {\n redacted[key] = this.redactObject(redacted[key], deep);\n } else if (typeof redacted[key] === 'string') {\n // Redact any API keys in string values\n redacted[key] = this.redact(redacted[key]);\n }\n });\n\n return redacted;\n }\n\n /**\n * Sanitize text for safe logging\n */\n static sanitize(text) {\n return this.redact(text, true);\n }\n\n /**\n * Sanitize command arguments\n */\n static sanitizeArgs(args) {\n return args.map(arg => {\n // Check if arg is a flag value pair\n if (arg.includes('key') || arg.includes('token') || arg.includes('secret')) {\n return this.redact(arg);\n }\n return arg;\n });\n }\n\n /**\n * Check if text contains unredacted sensitive data\n */\n static containsSensitiveData(text) {\n return this.API_KEY_PATTERNS.some(pattern => pattern.test(text));\n }\n\n /**\n * Validate that text is safe for logging/storage\n */\n static validate(text) {\n const warnings = [];\n\n this.API_KEY_PATTERNS.forEach((pattern, index) => {\n if (pattern.test(text)) {\n warnings.push(`Potential API key detected (pattern ${index + 1})`);\n }\n });\n\n return {\n safe: warnings.length === 0,\n warnings,\n };\n }\n\n /**\n * Redact environment variables\n */\n static redactEnv(env) {\n const redacted = {};\n\n Object.keys(env).forEach(key => {\n const value = env[key];\n if (!value) {\n redacted[key] = '';\n return;\n }\n\n const lowerKey = key.toLowerCase();\n const isSensitive = lowerKey.includes('key') ||\n lowerKey.includes('token') ||\n lowerKey.includes('secret') ||\n lowerKey.includes('password');\n\n if (isSensitive) {\n redacted[key] = value.length > 8\n ? `${value.substring(0, 4)}...[REDACTED]`\n : '[REDACTED]';\n } else {\n redacted[key] = value;\n }\n });\n\n return redacted;\n }\n}\n\n// Export singleton instance\nexport const redactor = KeyRedactor;\n"],"names":["KeyRedactor","API_KEY_PATTERNS","SENSITIVE_FIELDS","redact","text","showPrefix","redacted","forEach","pattern","replace","match","length","prefix","substring","redactObject","obj","deep","Object","keys","key","lowerKey","toLowerCase","isSensitive","some","field","includes","value","sanitize","sanitizeArgs","args","map","arg","containsSensitiveData","test","validate","warnings","index","push","safe","redactEnv","env","redactor"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/key-redactor.js"],"sourcesContent":["/**\n * API Key Redaction Utility\n * Prevents sensitive data from leaking into logs, memory, or git commits\n */\n\nexport class KeyRedactor {\n static API_KEY_PATTERNS = [\n // Anthropic API keys\n /sk-ant-[a-zA-Z0-9_-]{95,}/gi,\n\n // OpenRouter API keys\n /sk-or-[a-zA-Z0-9_-]{32,}/gi,\n\n // Google/Gemini API keys\n /AIza[a-zA-Z0-9_-]{35}/gi,\n\n // Generic API keys\n /[a-zA-Z0-9_-]{20,}API[a-zA-Z0-9_-]{20,}/gi,\n\n // Bearer tokens\n /Bearer\\s+[a-zA-Z0-9_\\-\\.]{20,}/gi,\n\n // Environment variable format\n /([A-Z_]+_API_KEY|[A-Z_]+_TOKEN|[A-Z_]+_SECRET)=[\"']?([^\"'\\s]+)[\"']?/gi,\n\n // Supabase keys\n /eyJ[a-zA-Z0-9_-]*\\.eyJ[a-zA-Z0-9_-]*\\.[a-zA-Z0-9_-]*/gi,\n ];\n\n static SENSITIVE_FIELDS = [\n 'apiKey',\n 'api_key',\n 'token',\n 'secret',\n 'password',\n 'private_key',\n 'privateKey',\n 'accessToken',\n 'access_token',\n 'refreshToken',\n 'refresh_token',\n ];\n\n /**\n * Redact API keys and sensitive data from text\n */\n static redact(text, showPrefix = true) {\n if (!text) return text;\n\n let redacted = text;\n\n // Redact using patterns\n this.API_KEY_PATTERNS.forEach(pattern => {\n redacted = redacted.replace(pattern, (match) => {\n if (showPrefix && match.length > 8) {\n const prefix = match.substring(0, 8);\n return `${prefix}...[REDACTED]`;\n }\n return '[REDACTED_API_KEY]';\n });\n });\n\n return redacted;\n }\n\n /**\n * Redact sensitive fields in objects\n */\n static redactObject(obj, deep = true) {\n if (!obj || typeof obj !== 'object') return obj;\n\n const redacted = { ...obj };\n\n Object.keys(redacted).forEach(key => {\n const lowerKey = key.toLowerCase();\n\n // Check if field name is sensitive\n const isSensitive = this.SENSITIVE_FIELDS.some(field =>\n lowerKey.includes(field)\n );\n\n if (isSensitive && typeof redacted[key] === 'string') {\n const value = redacted[key];\n if (value && value.length > 8) {\n redacted[key] = `${value.substring(0, 4)}...[REDACTED]`;\n } else {\n redacted[key] = '[REDACTED]';\n }\n } else if (deep && typeof redacted[key] === 'object' && redacted[key] !== null) {\n redacted[key] = this.redactObject(redacted[key], deep);\n } else if (typeof redacted[key] === 'string') {\n // Redact any API keys in string values\n redacted[key] = this.redact(redacted[key]);\n }\n });\n\n return redacted;\n }\n\n /**\n * Sanitize text for safe logging\n */\n static sanitize(text) {\n return this.redact(text, true);\n }\n\n /**\n * Sanitize command arguments\n */\n static sanitizeArgs(args) {\n return args.map(arg => {\n // Check if arg is a flag value pair\n if (arg.includes('key') || arg.includes('token') || arg.includes('secret')) {\n return this.redact(arg);\n }\n return arg;\n });\n }\n\n /**\n * Check if text contains unredacted sensitive data\n */\n static containsSensitiveData(text) {\n return this.API_KEY_PATTERNS.some(pattern => pattern.test(text));\n }\n\n /**\n * Validate that text is safe for logging/storage\n */\n static validate(text) {\n const warnings = [];\n\n this.API_KEY_PATTERNS.forEach((pattern, index) => {\n if (pattern.test(text)) {\n warnings.push(`Potential API key detected (pattern ${index + 1})`);\n }\n });\n\n return {\n safe: warnings.length === 0,\n warnings,\n };\n }\n\n /**\n * Redact environment variables\n */\n static redactEnv(env) {\n const redacted = {};\n\n Object.keys(env).forEach(key => {\n const value = env[key];\n if (!value) {\n redacted[key] = '';\n return;\n }\n\n const lowerKey = key.toLowerCase();\n const isSensitive = lowerKey.includes('key') ||\n lowerKey.includes('token') ||\n lowerKey.includes('secret') ||\n lowerKey.includes('password');\n\n if (isSensitive) {\n redacted[key] = value.length > 8\n ? `${value.substring(0, 4)}...[REDACTED]`\n : '[REDACTED]';\n } else {\n redacted[key] = value;\n }\n });\n\n return redacted;\n }\n}\n\n// Export singleton instance\nexport const redactor = KeyRedactor;\n"],"names":["KeyRedactor","API_KEY_PATTERNS","SENSITIVE_FIELDS","redact","text","showPrefix","redacted","forEach","pattern","replace","match","length","prefix","substring","redactObject","obj","deep","Object","keys","key","lowerKey","toLowerCase","isSensitive","some","field","includes","value","sanitize","sanitizeArgs","args","map","arg","containsSensitiveData","test","validate","warnings","index","push","safe","redactEnv","env","redactor"],"mappings":"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"},GAAG,CAACrB,IAAI;YACtB,IAAI,CAACO,OAAO;gBACVpB,QAAQ,CAACa,IAAI,GAAG;gBAChB;YACF;YAEA,MAAMC,WAAWD,IAAIE,WAAW;YAChC,MAAMC,cAAcF,SAASK,QAAQ,CAAC,UACnBL,SAASK,QAAQ,CAAC,YAClBL,SAASK,QAAQ,CAAC,aAClBL,SAASK,QAAQ,CAAC;YAErC,IAAIH,aAAa;gBACfhB,QAAQ,CAACa,IAAI,GAAGO,MAAMf,MAAM,GAAG,IAC3B,GAAGe,MAAMb,SAAS,CAAC,GAAG,GAAG,aAAa,CAAC,GACvC;YACN,OAAO;gBACLP,QAAQ,CAACa,IAAI,GAAGO;YAClB;QACF;QAEA,OAAOpB;IACT;AACF;AAGA,OAAO,MAAMmC,WAAWzC,YAAY"}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
# NPX Memory Command Fix - v2.7.19 Final Solution
|
|
2
|
+
|
|
3
|
+
**Issue:** `npx claude-flow@alpha memory` commands fail with BetterSqlite3 constructor error
|
|
4
|
+
**Status:** ✅ **FIXED in v2.7.19**
|
|
5
|
+
**Date:** 2025-10-25
|
|
6
|
+
**Versions:** v2.7.16 → v2.7.17 → v2.7.18 → **v2.7.19 (WORKING)**
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Problem Summary
|
|
11
|
+
|
|
12
|
+
When users run memory commands via `npx claude-flow@alpha memory store ...`, they encounter:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
TypeError: BetterSqlite3 is not a constructor
|
|
16
|
+
Migration error: TypeError: BetterSqlite3 is not a constructor
|
|
17
|
+
❌ Failed to store: Failed to initialize ReasoningBank: could not run migrations
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Root Cause
|
|
21
|
+
|
|
22
|
+
1. **npx installs packages in temporary directories** (`/home/user/.npm/_npx/{hash}/`)
|
|
23
|
+
2. **Optional dependencies are not installed** in npx temp directories
|
|
24
|
+
3. **better-sqlite3 is an optional dependency** required by ReasoningBank
|
|
25
|
+
4. **ReasoningBank initialization fails** when better-sqlite3 is missing
|
|
26
|
+
5. **Command crashes** instead of falling back gracefully
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Solution Evolution
|
|
31
|
+
|
|
32
|
+
### ❌ v2.7.16 (First Attempt)
|
|
33
|
+
**What was done:**
|
|
34
|
+
- Added npx detection in `reasoningbank-adapter.js`
|
|
35
|
+
- Showed helpful error message
|
|
36
|
+
- **Problem:** Still threw error, preventing fallback
|
|
37
|
+
|
|
38
|
+
### ❌ v2.7.17 (Second Attempt)
|
|
39
|
+
**What was done:**
|
|
40
|
+
- Expanded error detection to include "could not run migrations"
|
|
41
|
+
- **Problem:** Still throwing error at ensureInitialized()
|
|
42
|
+
|
|
43
|
+
### ❌ v2.7.18 (Third Attempt)
|
|
44
|
+
**What was done:**
|
|
45
|
+
- Changed `ensureInitialized()` to return `false` instead of throwing
|
|
46
|
+
- **Problem:** `detectMemoryMode()` didn't check return value, still tried to use ReasoningBank
|
|
47
|
+
|
|
48
|
+
### ✅ v2.7.19 (WORKING SOLUTION)
|
|
49
|
+
**What was done:**
|
|
50
|
+
1. `ensureInitialized()` returns `false` when initialization fails in npx (instead of throwing)
|
|
51
|
+
2. `detectMemoryMode()` checks if initialization returned `false` and falls back to JSON
|
|
52
|
+
3. Shows helpful error message with 3 solutions
|
|
53
|
+
4. Command completes successfully with JSON storage
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Technical Implementation
|
|
58
|
+
|
|
59
|
+
### File 1: `src/reasoningbank/reasoningbank-adapter.js`
|
|
60
|
+
|
|
61
|
+
**Change:** Return `false` instead of throwing error on npx failure
|
|
62
|
+
|
|
63
|
+
```javascript
|
|
64
|
+
initPromise = (async () => {
|
|
65
|
+
try {
|
|
66
|
+
await ReasoningBank.initialize();
|
|
67
|
+
backendInitialized = true;
|
|
68
|
+
return true;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
const isSqliteError = error.message?.includes('BetterSqlite3 is not a constructor') ||
|
|
71
|
+
error.message?.includes('better-sqlite3') ||
|
|
72
|
+
error.message?.includes('could not run migrations');
|
|
73
|
+
const isNpx = process.env.npm_config_user_agent?.includes('npx') ||
|
|
74
|
+
process.cwd().includes('_npx');
|
|
75
|
+
|
|
76
|
+
if (isSqliteError && isNpx) {
|
|
77
|
+
// Show helpful message but DON'T throw - allow fallback
|
|
78
|
+
console.error('\n⚠️ NPX LIMITATION DETECTED\n');
|
|
79
|
+
console.error('ReasoningBank requires better-sqlite3, not available in npx.\n');
|
|
80
|
+
console.error('📚 Solutions:\n');
|
|
81
|
+
console.error(' 1. LOCAL INSTALL: npm install && node_modules/.bin/claude-flow\n');
|
|
82
|
+
console.error(' 2. USE MCP TOOLS: mcp__claude-flow__memory_usage(...)\n');
|
|
83
|
+
console.error(' 3. USE JSON FALLBACK (automatic): Command will continue...\n');
|
|
84
|
+
return false; // Signal failure but allow fallback
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Other errors - throw normally
|
|
88
|
+
throw new Error(`Failed to initialize ReasoningBank: ${error.message}`);
|
|
89
|
+
}
|
|
90
|
+
})();
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### File 2: `src/cli/simple-commands/memory.js`
|
|
94
|
+
|
|
95
|
+
**Change:** Check initialization result before using ReasoningBank
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
async function detectMemoryMode(flags, subArgs) {
|
|
99
|
+
// ... [earlier code]
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
const { initializeReasoningBank } = await import('../../reasoningbank/reasoningbank-adapter.js');
|
|
103
|
+
const initialized = await initializeReasoningBank();
|
|
104
|
+
|
|
105
|
+
// Check if initialization succeeded
|
|
106
|
+
if (!initialized) {
|
|
107
|
+
// Initialization failed - fall back to JSON
|
|
108
|
+
const isNpx = process.env.npm_config_user_agent?.includes('npx') ||
|
|
109
|
+
process.cwd().includes('_npx');
|
|
110
|
+
if (isNpx) {
|
|
111
|
+
console.log('\n✅ Automatically using JSON fallback for this command\n');
|
|
112
|
+
} else {
|
|
113
|
+
printWarning(`⚠️ SQLite unavailable, using JSON fallback`);
|
|
114
|
+
}
|
|
115
|
+
return 'basic'; // Use JSON mode
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Success - use ReasoningBank
|
|
119
|
+
printInfo('🗄️ Initialized SQLite backend (.swarm/memory.db)');
|
|
120
|
+
return 'reasoningbank';
|
|
121
|
+
} catch (error) {
|
|
122
|
+
// Handle other errors...
|
|
123
|
+
return 'basic';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Expected User Experience (v2.7.19+)
|
|
131
|
+
|
|
132
|
+
### With npx (Automatic Fallback)
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
$ npx claude-flow@alpha memory store "api-design" "REST with JWT auth"
|
|
136
|
+
|
|
137
|
+
⚠️ NPX LIMITATION DETECTED
|
|
138
|
+
|
|
139
|
+
ReasoningBank requires better-sqlite3, not available in npx temp directories.
|
|
140
|
+
|
|
141
|
+
📚 Solutions:
|
|
142
|
+
1. LOCAL INSTALL (Recommended):
|
|
143
|
+
npm install && node_modules/.bin/claude-flow memory store "key" "value"
|
|
144
|
+
|
|
145
|
+
2. USE MCP TOOLS instead:
|
|
146
|
+
mcp__claude-flow__memory_usage({ action: "store", key: "test", value: "data" })
|
|
147
|
+
|
|
148
|
+
3. USE JSON FALLBACK (automatic):
|
|
149
|
+
Command will continue with JSON storage...
|
|
150
|
+
|
|
151
|
+
✅ Automatically using JSON fallback for this command
|
|
152
|
+
|
|
153
|
+
✅ Stored successfully
|
|
154
|
+
📝 Key: api-design
|
|
155
|
+
📦 Namespace: default
|
|
156
|
+
💾 Size: 18 bytes
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### With Local Install (Full Features)
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
$ npm install
|
|
163
|
+
$ node_modules/.bin/claude-flow memory store "api-design" "REST with JWT auth"
|
|
164
|
+
|
|
165
|
+
🗄️ Initialized SQLite backend (.swarm/memory.db)
|
|
166
|
+
✅ Stored successfully in ReasoningBank
|
|
167
|
+
📝 Key: api-design
|
|
168
|
+
🧠 Memory ID: abc123...
|
|
169
|
+
📦 Namespace: default
|
|
170
|
+
💾 Size: 18 bytes
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Validation Tests
|
|
176
|
+
|
|
177
|
+
### Test 1: Version Check
|
|
178
|
+
```bash
|
|
179
|
+
$ npx claude-flow@alpha --version
|
|
180
|
+
v2.7.19
|
|
181
|
+
✅ PASS
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Test 2: Memory Store (npx)
|
|
185
|
+
```bash
|
|
186
|
+
$ npx claude-flow@alpha memory store "test-key" "test-value"
|
|
187
|
+
⚠️ NPX LIMITATION DETECTED
|
|
188
|
+
✅ Automatically using JSON fallback for this command
|
|
189
|
+
✅ Stored successfully
|
|
190
|
+
✅ PASS
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Test 3: Memory Query (npx)
|
|
194
|
+
```bash
|
|
195
|
+
$ npx claude-flow@alpha memory query "test"
|
|
196
|
+
✅ Found 1 result(s):
|
|
197
|
+
test-key = test-value (namespace: default)
|
|
198
|
+
✅ PASS
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Test 4: Memory Stats (npx)
|
|
202
|
+
```bash
|
|
203
|
+
$ npx claude-flow@alpha memory stats
|
|
204
|
+
✅ Memory Bank Statistics:
|
|
205
|
+
Total Entries: 1
|
|
206
|
+
Namespaces: 1
|
|
207
|
+
Size: 10 bytes
|
|
208
|
+
✅ PASS
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Files Changed
|
|
214
|
+
|
|
215
|
+
1. **src/reasoningbank/reasoningbank-adapter.js**
|
|
216
|
+
- Modified `ensureInitialized()` to return false instead of throwing
|
|
217
|
+
- Added npx detection and helpful error messages
|
|
218
|
+
- Lines changed: 36-76
|
|
219
|
+
|
|
220
|
+
2. **src/cli/simple-commands/memory.js**
|
|
221
|
+
- Modified `detectMemoryMode()` to check initialization return value
|
|
222
|
+
- Added automatic fallback logic
|
|
223
|
+
- Lines changed: 418-457
|
|
224
|
+
|
|
225
|
+
3. **package.json**
|
|
226
|
+
- Version: 2.7.16 → 2.7.19
|
|
227
|
+
|
|
228
|
+
4. **docs/MEMORY_COMMAND_FIX.md**
|
|
229
|
+
- Updated with v2.7.19 solution
|
|
230
|
+
- Documented automatic fallback behavior
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Why Previous Versions Failed
|
|
235
|
+
|
|
236
|
+
### v2.7.16 → v2.7.17
|
|
237
|
+
- Error detection worked
|
|
238
|
+
- Error message showed
|
|
239
|
+
- **But:** Still threw error, command failed
|
|
240
|
+
|
|
241
|
+
### v2.7.18
|
|
242
|
+
- Stopped throwing error (returned false)
|
|
243
|
+
- **But:** `detectMemoryMode()` didn't check return value
|
|
244
|
+
- Still tried to use ReasoningBank, called `storeMemory()`, which failed
|
|
245
|
+
|
|
246
|
+
### v2.7.19 ✅
|
|
247
|
+
- Returns false on failure
|
|
248
|
+
- **AND:** Checks return value before using ReasoningBank
|
|
249
|
+
- Falls back to JSON successfully
|
|
250
|
+
- Command completes without error
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Key Learnings
|
|
255
|
+
|
|
256
|
+
1. **npx limitation is real:** Optional dependencies never install in temp directories
|
|
257
|
+
2. **Silent failures are better than crashes:** Return false, don't throw
|
|
258
|
+
3. **Check all return values:** Even if initialization "succeeds", verify the result
|
|
259
|
+
4. **Graceful degradation:** JSON fallback works fine for most use cases
|
|
260
|
+
5. **Clear error messages:** Tell users exactly what happened and how to fix it
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Recommended Usage
|
|
265
|
+
|
|
266
|
+
### For Quick Testing (npx)
|
|
267
|
+
```bash
|
|
268
|
+
npx claude-flow@alpha memory store "key" "value"
|
|
269
|
+
# Works with JSON fallback - no installation required
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### For Production (local install)
|
|
273
|
+
```bash
|
|
274
|
+
npm install claude-flow@alpha
|
|
275
|
+
node_modules/.bin/claude-flow memory store "key" "value"
|
|
276
|
+
# Uses SQLite with full ReasoningBank features
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### For Workflows (MCP tools)
|
|
280
|
+
```javascript
|
|
281
|
+
// In Claude Code / Claude Desktop
|
|
282
|
+
mcp__claude-flow__memory_usage({
|
|
283
|
+
action: "store",
|
|
284
|
+
key: "api-pattern",
|
|
285
|
+
value: "REST with JWT auth",
|
|
286
|
+
namespace: "default"
|
|
287
|
+
})
|
|
288
|
+
// Best integration, no dependency issues
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## Summary
|
|
294
|
+
|
|
295
|
+
**Problem:** npx memory commands crashed due to missing better-sqlite3
|
|
296
|
+
**Solution:** Detect npx, return false instead of throwing, check return value, fall back to JSON
|
|
297
|
+
**Result:** Commands work via npx with helpful error messages and automatic JSON fallback
|
|
298
|
+
|
|
299
|
+
**Status:** ✅ **FIXED AND VALIDATED**
|
|
300
|
+
**Version:** v2.7.19
|
|
301
|
+
**Date:** 2025-10-25
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
**All npx memory commands now work correctly with automatic JSON fallback!**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-flow",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.21",
|
|
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",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"format": "prettier --write 'src/**/*.{ts,js,json}'",
|
|
51
51
|
"diagnostics": "node -e \"import('./dist/monitoring/diagnostics.js').then(m => m.DiagnosticManager.quickDiagnostic().then(console.log))\"",
|
|
52
52
|
"health-check": "node -e \"import('./dist/monitoring/health-check.js').then(m => new m.HealthCheckManager().performHealthCheck().then(console.log))\"",
|
|
53
|
-
"postinstall": "node scripts/install-arm64.js || true && bash scripts/fix-agentdb-imports.sh || true",
|
|
53
|
+
"postinstall": "node scripts/install-arm64.js || true && bash scripts/fix-agentdb-imports.sh || true && bash scripts/fix-agentic-flow-sqlite.sh || true",
|
|
54
54
|
"prepublishOnly": "npm run update-version",
|
|
55
55
|
"publish:alpha": "npm publish --tag alpha",
|
|
56
56
|
"publish:major": "npm version major && npm publish",
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"@anthropic-ai/claude-code": "^2.0.1",
|
|
121
121
|
"@anthropic-ai/sdk": "^0.65.0",
|
|
122
122
|
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
123
|
-
"agentic-flow": "
|
|
123
|
+
"agentic-flow": "^1.8.4",
|
|
124
124
|
"blessed": "^0.1.81",
|
|
125
125
|
"chalk": "^4.1.2",
|
|
126
126
|
"cli-table3": "^0.6.3",
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Fix agentic-flow's broken better-sqlite3 import
|
|
3
|
+
# The dist/reasoningbank/db/queries.js file has BetterSqlite3 = null
|
|
4
|
+
# This script patches it to properly import better-sqlite3
|
|
5
|
+
|
|
6
|
+
QUERIES_FILE="node_modules/agentic-flow/dist/reasoningbank/db/queries.js"
|
|
7
|
+
|
|
8
|
+
if [ ! -f "$QUERIES_FILE" ]; then
|
|
9
|
+
echo "❌ File not found: $QUERIES_FILE"
|
|
10
|
+
exit 1
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
echo "🔧 Fixing agentic-flow better-sqlite3 import..."
|
|
14
|
+
|
|
15
|
+
# Check if already fixed
|
|
16
|
+
if grep -q "import Database from 'better-sqlite3'" "$QUERIES_FILE"; then
|
|
17
|
+
echo "✅ Already fixed!"
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# Backup original
|
|
22
|
+
cp "$QUERIES_FILE" "${QUERIES_FILE}.backup"
|
|
23
|
+
|
|
24
|
+
# Replace the broken import
|
|
25
|
+
sed -i '5s/const BetterSqlite3 = null; \/\/ Not used/import Database from '\''better-sqlite3'\'';/' "$QUERIES_FILE"
|
|
26
|
+
sed -i 's/new BetterSqlite3(/new Database(/g' "$QUERIES_FILE"
|
|
27
|
+
|
|
28
|
+
echo "✅ Fixed agentic-flow better-sqlite3 import!"
|
|
29
|
+
echo " Patched: $QUERIES_FILE"
|
|
30
|
+
echo " Backup: ${QUERIES_FILE}.backup"
|