UNPKG

claude-flow-multilang

Version:

Revolutionary multilingual AI orchestration framework with cultural awareness and DDD architecture

333 lines (273 loc) • 9.35 kB
// memory.js - Memory management commands import { printSuccess, printError, printWarning } from '../utils.js'; import { promises as fs } from 'fs'; import { cwd, exit, existsSync } from '../node-compat.js'; export async function memoryCommand(subArgs, flags) { const memorySubcommand = subArgs[0]; const memoryStore = './memory/memory-store.json'; // Helper to load memory data async function loadMemory() { try { const content = await fs.readFile(memoryStore, 'utf8'); return JSON.parse(content); } catch { return {}; } } // Helper to save memory data async function saveMemory(data) { await fs.mkdir('./memory', { recursive: true }); await fs.writeFile(memoryStore, JSON.stringify(data, null, 2, 'utf8')); } switch (memorySubcommand) { case 'store': await storeMemory(subArgs, loadMemory, saveMemory); break; case 'query': await queryMemory(subArgs, loadMemory); break; case 'stats': await showMemoryStats(loadMemory); break; case 'export': await exportMemory(subArgs, loadMemory); break; case 'import': await importMemory(subArgs, saveMemory); break; case 'clear': await clearMemory(subArgs, saveMemory); break; case 'list': await listNamespaces(loadMemory); break; default: showMemoryHelp(); } } async function storeMemory(subArgs, loadMemory, saveMemory) { const key = subArgs[1]; const value = subArgs.slice(2).join(' '); if (!key || !value) { printError('Usage: memory store <key> <value>'); return; } try { const data = await loadMemory(); const namespace = getNamespaceFromArgs(subArgs) || 'default'; if (!data[namespace]) { data[namespace] = []; } // Remove existing entry with same key data[namespace] = data[namespace].filter((e) => e.key !== key); // Add new entry data[namespace].push({ key, value, namespace, timestamp: Date.now(), }); await saveMemory(data); printSuccess('Stored successfully'); console.log(`šŸ“ Key: ${key}`); console.log(`šŸ“¦ Namespace: ${namespace}`); console.log(`šŸ’¾ Size: ${new TextEncoder().encode(value).length} bytes`); } catch (err) { printError(`Failed to store: ${err.message}`); } } async function queryMemory(subArgs, loadMemory) { const search = subArgs.slice(1).join(' '); if (!search) { printError('Usage: memory query <search>'); return; } try { const data = await loadMemory(); const namespace = getNamespaceFromArgs(subArgs); const results = []; for (const [ns, entries] of Object.entries(data)) { if (namespace && ns !== namespace) continue; for (const entry of entries) { if (entry.key.includes(search) || entry.value.includes(search)) { results.push(entry); } } } if (results.length === 0) { printWarning('No results found'); return; } printSuccess(`Found ${results.length} results:`); // Sort by timestamp (newest first) results.sort((a, b) => b.timestamp - a.timestamp); for (const entry of results.slice(0, 10)) { console.log(`\nšŸ“Œ ${entry.key}`); console.log(` Namespace: ${entry.namespace}`); console.log( ` Value: ${entry.value.substring(0, 100)}${entry.value.length > 100 ? '...' : ''}`, ); console.log(` Stored: ${new Date(entry.timestamp).toLocaleString()}`); } if (results.length > 10) { console.log(`\n... and ${results.length - 10} more results`); } } catch (err) { printError(`Failed to query: ${err.message}`); } } async function showMemoryStats(loadMemory) { try { const data = await loadMemory(); let totalEntries = 0; const namespaceStats = {}; for (const [namespace, entries] of Object.entries(data)) { namespaceStats[namespace] = entries.length; totalEntries += entries.length; } printSuccess('Memory Bank Statistics:'); console.log(` Total Entries: ${totalEntries}`); console.log(` Namespaces: ${Object.keys(data).length}`); console.log( ` Size: ${(new TextEncoder().encode(JSON.stringify(data)).length / 1024).toFixed(2)} KB`, ); if (Object.keys(data).length > 0) { console.log('\nšŸ“ Namespace Breakdown:'); for (const [namespace, count] of Object.entries(namespaceStats)) { console.log(` ${namespace}: ${count} entries`); } } } catch (err) { printError(`Failed to get stats: ${err.message}`); } } async function exportMemory(subArgs, loadMemory) { const filename = subArgs[1] || `memory-export-${Date.now()}.json`; try { const data = await loadMemory(); const namespace = getNamespaceFromArgs(subArgs); let exportData = data; if (namespace) { exportData = { [namespace]: data[namespace] || [] }; } await fs.writeFile(filename, JSON.stringify(exportData, null, 2, 'utf8')); printSuccess(`Memory exported to ${filename}`); let totalEntries = 0; for (const entries of Object.values(exportData)) { totalEntries += entries.length; } console.log( `šŸ“¦ Exported ${totalEntries} entries from ${Object.keys(exportData).length} namespace(s)`, ); } catch (err) { printError(`Failed to export memory: ${err.message}`); } } async function importMemory(subArgs, saveMemory) { const filename = subArgs[1]; if (!filename) { printError('Usage: memory import <filename>'); return; } try { const importContent = await fs.readFile(filename, 'utf8'); const importData = JSON.parse(importContent); // Load existing memory const existingData = await loadMemory(); // Merge imported data let totalImported = 0; for (const [namespace, entries] of Object.entries(importData)) { if (!existingData[namespace]) { existingData[namespace] = []; } // Add entries that don't already exist (by key) const existingKeys = new Set(existingData[namespace].map((e) => e.key)); const newEntries = entries.filter((e) => !existingKeys.has(e.key)); existingData[namespace].push(...newEntries); totalImported += newEntries.length; } await saveMemory(existingData); printSuccess(`Imported ${totalImported} new entries from ${filename}`); } catch (err) { printError(`Failed to import memory: ${err.message}`); } } async function clearMemory(subArgs, saveMemory) { const namespace = getNamespaceFromArgs(subArgs); if (!namespace) { printError('Usage: memory clear --namespace <namespace>'); printWarning('This will clear all entries in the specified namespace'); return; } try { const data = await loadMemory(); if (!data[namespace]) { printWarning(`Namespace '${namespace}' does not exist`); return; } const entryCount = data[namespace].length; delete data[namespace]; await saveMemory(data); printSuccess(`Cleared ${entryCount} entries from namespace '${namespace}'`); } catch (err) { printError(`Failed to clear memory: ${err.message}`); } } async function listNamespaces(loadMemory) { try { const data = await loadMemory(); const namespaces = Object.keys(data); if (namespaces.length === 0) { printWarning('No namespaces found'); return; } printSuccess('Available namespaces:'); for (const namespace of namespaces) { const count = data[namespace].length; console.log(` ${namespace} (${count} entries)`); } } catch (err) { printError(`Failed to list namespaces: ${err.message}`); } } function getNamespaceFromArgs(subArgs) { const namespaceIndex = subArgs.indexOf('--namespace'); if (namespaceIndex !== -1 && namespaceIndex + 1 < subArgs.length) { return subArgs[namespaceIndex + 1]; } const nsIndex = subArgs.indexOf('--ns'); if (nsIndex !== -1 && nsIndex + 1 < subArgs.length) { return subArgs[nsIndex + 1]; } return null; } // Helper to load memory data (needed for import function) async function loadMemory() { try { const content = await fs.readFile('./memory/memory-store.json', 'utf8'); return JSON.parse(content); } catch { return {}; } } function showMemoryHelp() { console.log('Memory commands:'); console.log(' store <key> <value> Store a key-value pair'); console.log(' query <search> Search for entries'); console.log(' stats Show memory statistics'); console.log(' export [filename] Export memory to file'); console.log(' import <filename> Import memory from file'); console.log(' clear --namespace <ns> Clear a namespace'); console.log(' list List all namespaces'); console.log(); console.log('Options:'); console.log(' --namespace <ns> Specify namespace for operations'); console.log(' --ns <ns> Short form of --namespace'); console.log(); console.log('Examples:'); console.log(' memory store previous_work "Research findings from yesterday"'); console.log(' memory query research --namespace sparc'); console.log(' memory export backup.json --namespace default'); console.log(' memory import project-memory.json'); console.log(' memory stats'); }