UNPKG

@sethdouglasford/claude-flow

Version:

Claude Code Flow - Advanced AI-powered development workflows with SPARC methodology

857 lines 39 kB
/** * Advanced Memory Management Commands * Implements comprehensive memory operations with advanced capabilities */ import { Command } from "../cliffy-compat.js"; import { promises as fs } from "node:fs"; import { extname } from "node:path"; import chalk from "chalk"; import { AdvancedMemoryManager } from "../../memory/advanced-memory-manager.js"; import { Logger } from "../../core/logger.js"; // Initialize logger const logger = Logger.getInstance(); // Global memory manager instance let memoryManager = null; // Helper functions function printSuccess(message) { console.log(chalk.green(`✅ ${message}`)); } function printError(message) { console.error(chalk.red(`❌ ${message}`)); } function printWarning(message) { console.warn(chalk.yellow(`⚠️ ${message}`)); } function printInfo(message) { console.log(chalk.blue(`ℹ️ ${message}`)); } function formatBytes(bytes) { if (bytes === 0) return "0 B"; const k = 1024; const sizes = ["B", "KB", "MB", "GB"]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`; } function formatDuration(ms) { if (ms < 1000) return `${ms}ms`; if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`; return `${(ms / 60000).toFixed(1)}m`; } function getErrorMessage(error) { if (error instanceof Error) return error.message; if (typeof error === "string") return error; return "Unknown error occurred"; } async function ensureMemoryManager() { if (!memoryManager) { memoryManager = new AdvancedMemoryManager({ persistenceEnabled: true, logger, }); await memoryManager.initialize(); } return memoryManager; } // === MAIN MEMORY COMMAND === export function createAdvancedMemoryCommand() { const memoryCmd = new Command("memory") .description("Advanced memory management with indexing, compression, and cross-agent sharing") .action(() => { console.log(chalk.cyan.bold("🧠 Advanced Memory Management System\n")); console.log("Available commands:"); console.log(" memory query <search> [options] - Flexible searching with filters and aggregation"); console.log(" memory export <file> [options] - Export memory data in multiple formats"); console.log(" memory import <file> [options] - Import data with validation and transformation"); console.log(" memory stats [options] - Comprehensive statistics and optimization suggestions"); console.log(" memory cleanup [options] - Intelligent cleanup with archiving and retention"); console.log(" memory store <key> <value> [opts] - Store data with advanced options"); console.log(" memory get <key> [options] - Retrieve data with caching"); console.log(" memory update <key> <value> [opts] - Update existing entries"); console.log(" memory delete <key> [options] - Delete specific entries"); console.log(" memory list [options] - List entries with filtering"); console.log(" memory namespaces - List all namespaces"); console.log(" memory types - List all data types"); console.log(" memory tags - List all tags"); console.log(" memory config [options] - View/update configuration"); console.log("\nFeatures:"); console.log(" • Advanced querying with indexing and full-text search"); console.log(" • Multiple export/import formats (JSON, CSV, XML, YAML)"); console.log(" • Intelligent cleanup with retention policies"); console.log(" • Compression and encryption support"); console.log(" • Cross-agent sharing and synchronization"); console.log(" • Performance analytics and optimization suggestions"); }); // === QUERY COMMAND === memoryCmd .command("query") .description("Advanced query with filtering, search, and aggregation") .argument("<search>", "Search term or pattern") .option("-n, --namespace <namespace>", "Filter by namespace") .option("-t, --type <type>", "Filter by data type") .option("--tags <tags>", "Filter by tags (comma-separated)") .option("--owner <owner>", "Filter by owner") .option("--access-level <level>", "Filter by access level (private|shared|public)") .option("--key-pattern <pattern>", "Key pattern (regex)") .option("--value-search <text>", "Search in values") .option("--full-text <text>", "Full-text search") .option("--created-after <date>", "Created after date (ISO format)") .option("--created-before <date>", "Created before date (ISO format)") .option("--updated-after <date>", "Updated after date (ISO format)") .option("--updated-before <date>", "Updated before date (ISO format)") .option("--size-gt <bytes>", "Size greater than (bytes)", parseInt) .option("--size-lt <bytes>", "Size less than (bytes)", parseInt) .option("--include-expired", "Include expired entries") .option("--limit <num>", "Limit results", parseInt) .option("--offset <num>", "Offset for pagination", parseInt) .option("--sort-by <field>", "Sort by field (key|createdAt|updatedAt|lastAccessedAt|size|type)") .option("--sort-order <order>", "Sort order (asc|desc)", "asc") .option("--aggregate-by <field>", "Generate aggregations (namespace|type|owner|tags)") .option("--include-metadata", "Include full metadata in results") .option("--format <format>", "Output format (table|json|csv)", "table") .action(async (search, options) => { try { const manager = await ensureMemoryManager(); const startTime = Date.now(); // Build query options // Options are already typed, no need to cast const queryOptions = { fullTextSearch: search, namespace: options.namespace, type: options.type, tags: typeof options.tags === "string" ? options.tags.split(",").map((t) => t.trim()) : undefined, owner: options.owner, keyPattern: options.keyPattern, limit: options.limit, offset: options.offset, }; const entries = manager.query(queryOptions); const duration = Date.now() - startTime; const total = entries.length; printSuccess(`Found ${total} entries in ${formatDuration(duration)}`); if (entries.length === 0) { printInfo("No entries match your query criteria."); return; } // Display results based on format switch (options.format) { case "json": console.log(JSON.stringify({ query: queryOptions, results: entries, executionTime: duration, }, null, 2)); break; case "csv": console.log("key,value,type,namespace,tags,size,created,updated"); for (const entry of entries) { console.log([ entry.key, JSON.stringify(entry.value).replace(/"/g, "\"\""), entry.type, entry.namespace, "", // tags not supported 0, // size not tracked entry.createdAt.toISOString(), entry.updatedAt.toISOString(), ].join(",")); } break; default: // table console.log(chalk.cyan("\n📋 Query Results:\n")); for (const [i, entry] of entries.entries()) { const value = typeof entry.value === "string" && entry.value.length > 100 ? `${entry.value.substring(0, 100)}...` : JSON.stringify(entry.value); console.log(chalk.blue(`${i + 1}. ${entry.key}`)); console.log(` Type: ${entry.type} | Namespace: ${entry.namespace}`); console.log(` Value: ${value}`); console.log(` Created: ${entry.createdAt.toLocaleString()} | Updated: ${entry.updatedAt.toLocaleString()}`); // Metadata not supported in simplified version console.log(); } } // Aggregations not supported in simplified version // Show pagination info if (total > entries.length) { const showing = (options.offset ?? 0) + entries.length; console.log(chalk.gray(`Showing ${showing} of ${total} entries`)); } } catch (error) { printError(`Query failed: ${getErrorMessage(error)}`); if (options.debug) { console.error(error); } } }); // === EXPORT COMMAND === memoryCmd .command("export") .description("Export memory data in multiple formats") .argument("<file>", "Output file path") .option("-f, --format <format>", "Export format (json|csv|xml|yaml)", "json") .option("-n, --namespace <namespace>", "Export specific namespace") .option("-t, --type <type>", "Export specific type") .option("--include-metadata", "Include full metadata") .option("--compression", "Enable compression") .option("--encrypt", "Enable encryption") .option("--encrypt-key <key>", "Encryption key") .option("--filter-query <json>", "Advanced filtering (JSON query options)") .action(async (file, options) => { try { const manager = await ensureMemoryManager(); // Determine format from file extension if not specified let { format } = options; if (!format) { const ext = extname(file).toLowerCase(); switch (ext) { case ".json": format = "json"; break; case ".csv": format = "csv"; break; case ".xml": format = "xml"; break; case ".yaml": case ".yml": format = "yaml"; break; default: format = "json"; } } // Parse filter query if provided // Note: _filtering is created but not used in simplified version if (typeof options.filterQuery === "string") { try { const _filtering = JSON.parse(options.filterQuery); // Filtering options are not implemented in simplified version void _filtering; // Acknowledge unused variable } catch (_error) { printError("Invalid filter query JSON format"); return; } } // Build export options const exportOptions = { format: format, pretty: true, }; printInfo(`Starting export to ${file} (format: ${format})`); const startTime = Date.now(); const data = manager.export(exportOptions); // Write to file await fs.writeFile(file, data); const stats = await fs.stat(file); const duration = Date.now() - startTime; printSuccess(`Export completed in ${formatDuration(duration)}`); console.log(`📁 File size: ${formatBytes(stats.size)}`); // Compression and encryption not supported in simplified version } catch (error) { printError(`Export failed: ${getErrorMessage(error)}`); if (options.debug) { console.error(error); } } }); // === IMPORT COMMAND === memoryCmd .command("import") .description("Import memory data with validation and transformation") .argument("<file>", "Input file path") .option("-f, --format <format>", "Import format (json|csv|xml|yaml)") .option("-n, --namespace <namespace>", "Target namespace for imported data") .option("--conflict-resolution <strategy>", "Conflict resolution (overwrite|skip|merge|rename)", "skip") .option("--validation", "Enable data validation") .option("--key-mapping <json>", "Key mapping for transformation (JSON object)") .option("--value-transform <js>", "Value transformation JavaScript function") .option("--metadata-extract <js>", "Metadata extraction JavaScript function") .option("--dry-run", "Show what would be imported without making changes") .action(async (file, options) => { try { const manager = await ensureMemoryManager(); // Check if file exists try { await fs.access(file); } catch { printError(`File not found: ${file}`); return; } // Determine format from file extension if not specified let { format } = options; if (!format) { const ext = extname(file).toLowerCase(); switch (ext) { case ".json": format = "json"; break; case ".csv": format = "csv"; break; case ".xml": format = "xml"; break; case ".yaml": case ".yml": format = "yaml"; break; default: printError("Cannot determine format from file extension. Please specify --format"); return; } } // Transformations not supported in simplified version // Build import options const importOptions = { overwrite: options.conflictResolution === "overwrite", merge: options.conflictResolution === "merge", }; if (options.dryRun) { printWarning("DRY RUN MODE - No changes will be made"); } printInfo(`Starting import from ${file} (format: ${format})`); const startTime = Date.now(); // Read file and import data const fileData = await fs.readFile(file, "utf-8"); const result = await manager.import(fileData, importOptions); const duration = Date.now() - startTime; printSuccess(`Import completed in ${formatDuration(duration)}`); if (result.imported > 0) { console.log(chalk.green(`📥 Imported: ${result.imported} entries`)); } if (result.skipped > 0) { console.log(chalk.yellow(`⏭️ Skipped: ${result.skipped} entries`)); } if (result.conflicts && result.conflicts.length > 0) { console.log(chalk.red(`⚠️ Conflicts: ${result.conflicts.length}`)); if (result.conflicts.length <= 10) { result.conflicts.forEach(conflict => { const key = conflict.entry && typeof conflict.entry === "object" && "key" in conflict.entry ? String(conflict.entry.key) : "unknown"; console.log(chalk.red(` • ${conflict.reason}: ${key}`)); }); } else { result.conflicts.slice(0, 10).forEach(conflict => { const key = conflict.entry && typeof conflict.entry === "object" && "key" in conflict.entry ? String(conflict.entry.key) : "unknown"; console.log(chalk.red(` • ${conflict.reason}: ${key}`)); }); console.log(chalk.red(` ... and ${result.conflicts.length - 10} more`)); } } } catch (error) { printError(`Import failed: ${getErrorMessage(error)}`); if (options.debug) { console.error(error); } } }); // === STATS COMMAND === memoryCmd .command("stats") .description("Comprehensive statistics with analytics and optimization suggestions") .option("--detailed", "Show detailed statistics") .option("--format <format>", "Output format (table|json)", "table") .option("--export <file>", "Export statistics to file") .action(async (options) => { try { const manager = await ensureMemoryManager(); const startTime = Date.now(); // Get stats - handle both simple and advanced stats formats const managerWithStats = manager; const rawStats = managerWithStats.getStats ? await managerWithStats.getStats() : (managerWithStats.getStatistics?.() ?? {}); // Transform simple stats to expected format if needed const stats = { overview: { totalEntries: rawStats.totalEntries ?? 0, }, distribution: { byNamespace: rawStats.namespaceStats ?? {}, byType: {}, byOwner: {}, }, temporal: { oldestEntry: null, newestEntry: null, totalDuration: 0, activityPeriods: [], inactivePeriods: [], }, performance: { averageQueryTime: 0, averageWriteTime: 0, cacheHitRate: 0, indexEfficiency: 0, }, health: { status: "healthy", fragmentation: 0, memoryUsage: rawStats.sizeBytes ?? 0, diskUsage: rawStats.sizeBytes ?? 0, errors: 0, warnings: 0, }, optimization: { suggestions: [], potentialSavings: 0, recommendedActions: 0, lastOptimized: null, }, }; const duration = Date.now() - startTime; if (options.format === "json") { const output = { statistics: stats, generatedAt: new Date().toISOString(), generationTime: duration, }; if (options.export) { await fs.writeFile(options.export, JSON.stringify(output, null, 2)); printSuccess(`Statistics exported to ${options.export}`); } else { console.log(JSON.stringify(output, null, 2)); } return; } // Table format display console.log(chalk.cyan.bold("🧠 Memory System Statistics\n")); // Overview console.log(chalk.yellow("📊 Overview:")); console.log(` Total Entries: ${stats.overview.totalEntries.toLocaleString()}`); console.log(); // Distribution console.log(chalk.yellow("📈 Distribution:")); if (Object.keys(stats.distribution.byNamespace).length > 0) { console.log(" By Namespace:"); // Distribution details not available in simplified version } if (Object.keys(stats.distribution.byType).length > 0) { console.log(" By Type:"); // Type distribution not available in simplified version } if (Object.keys(stats.distribution.byOwner).length > 0) { console.log(" By Owner:"); for (const [owner, count] of Object.entries(stats.distribution.byOwner)) { console.log(` ${owner}: ${String(count)} entries`); } } console.log(); // Temporal console.log(chalk.yellow("⏰ Temporal Analysis:")); console.log(` Total Duration: ${formatDuration(stats.temporal.totalDuration)}`); console.log(` Activity Periods: ${stats.temporal.activityPeriods.length}`); console.log(` Inactive Periods: ${stats.temporal.inactivePeriods.length}`); if (stats.temporal.oldestEntry) { console.log(` Oldest Entry: ${new Date(stats.temporal.oldestEntry).toLocaleString()}`); } if (stats.temporal.newestEntry) { console.log(` Newest Entry: ${new Date(stats.temporal.newestEntry).toLocaleString()}`); } console.log(); // Performance console.log(chalk.yellow("⚡ Performance:")); console.log(` Average Query Time: ${formatDuration(stats.performance.averageQueryTime)}`); console.log(` Average Write Time: ${formatDuration(stats.performance.averageWriteTime)}`); console.log(` Cache Hit Rate: ${(stats.performance.cacheHitRate * 100).toFixed(1)}%`); console.log(` Index Efficiency: ${(stats.performance.indexEfficiency * 100).toFixed(1)}%`); console.log(); // Health console.log(chalk.yellow("🏥 Health:")); const healthColor = stats.health.status === "healthy" ? chalk.green : chalk.red; console.log(` Status: ${healthColor(stats.health.status)}`); console.log(` Fragmentation: ${(Number(stats.health.fragmentation) * 100).toFixed(1)}%`); console.log(` Memory Usage: ${formatBytes(Number(stats.health.memoryUsage) || 0)}`); console.log(` Disk Usage: ${formatBytes(Number(stats.health.diskUsage) || 0)}`); console.log(` Errors: ${stats.health.errors}`); console.log(` Warnings: ${stats.health.warnings}`); console.log(); // Optimization if (stats.optimization.suggestions.length > 0) { console.log(chalk.yellow("💡 Optimization Suggestions:")); stats.optimization.suggestions.forEach((suggestion) => { console.log(` • ${String(suggestion)}`); }); console.log(); console.log(chalk.yellow("💰 Potential Savings:")); console.log(` Total potential savings: ${formatBytes(stats.optimization.potentialSavings)}`); console.log(); } // Index optimization details not available in current implementation console.log(chalk.gray(`Statistics generated in ${formatDuration(duration)}`)); // Export if requested if (options.export) { const output = { statistics: stats, generatedAt: new Date().toISOString(), generationTime: duration, }; await fs.writeFile(options.export, JSON.stringify(output, null, 2)); printSuccess(`Statistics exported to ${options.export}`); } } catch (error) { printError(`Statistics generation failed: ${getErrorMessage(error)}`); if (options.debug) { console.error(error); } } }); // === CLEANUP COMMAND === memoryCmd .command("cleanup") .description("Intelligent cleanup with archiving and retention policies") .option("--dry-run", "Show what would be cleaned without making changes") .option("--remove-expired", "Remove expired entries", true) .option("--remove-older-than <days>", "Remove entries older than N days", parseInt) .option("--remove-unaccessed <days>", "Remove entries not accessed in N days", parseInt) .option("--remove-orphaned", "Remove orphaned references", true) .option("--remove-duplicates", "Remove duplicate entries") .option("--compress-eligible", "Compress eligible entries", true) .option("--archive-old", "Enable archiving of old entries") .option("--archive-older-than <days>", "Archive entries older than N days", parseInt) .option("--archive-path <path>", "Archive directory path", "./memory/archive") .option("--retention-policies <json>", "Custom retention policies (JSON)") .option("--aggressive", "Use aggressive cleanup settings") .action(async (options) => { try { const manager = await ensureMemoryManager(); if (options.dryRun) { printWarning("DRY RUN MODE - No changes will be made"); } // Parse retention policies if (typeof options.retentionPolicies === "string") { try { const _retentionPolicies = JSON.parse(options.retentionPolicies); // Retention policies are not implemented in simplified version void _retentionPolicies; // Acknowledge unused variable } catch (_error) { printError("Invalid retention policies JSON format"); return; } } // Apply aggressive settings if requested if (options.aggressive) { options.removeOlderThan = options.removeOlderThan ?? 30; options.removeUnaccessed = options.removeUnaccessed ?? 7; options.removeDuplicates = true; options.archiveOld = true; options.archiveOlderThan = options.archiveOlderThan ?? 90; } // Build cleanup options const cleanupOptions = { dry: options.dryRun, maxAge: options.removeOlderThan ? options.removeOlderThan * 24 * 60 * 60 * 1000 : undefined, namespace: undefined, }; printInfo("Starting memory cleanup..."); const startTime = Date.now(); const result = await manager.cleanup(cleanupOptions); const duration = Date.now() - startTime; printSuccess(`Cleanup completed in ${formatDuration(duration)}`); if (result.removed > 0) { console.log(chalk.red(`🗑️ Removed: ${result.removed} entries`)); } if (result.actions.length > 0) { console.log(chalk.cyan("\n📋 Actions Performed:")); result.actions.forEach(action => { console.log(` • ${action.type}: ${action.id ?? "unknown"}${action.reason ? ` (${action.reason})` : ""}${action.message ? ` - ${action.message}` : ""}`); }); } if (options.dryRun && result.removed > 0) { printInfo("Run without --dry-run to perform these actions"); } } catch (error) { printError(`Cleanup failed: ${getErrorMessage(error)}`); if (options.debug) { console.error(error); } } }); // === BASIC COMMANDS === // Store command memoryCmd .command("store") .description("Store data with advanced options") .argument("<key>", "Entry key") .argument("<value>", "Entry value (JSON string)") .option("-n, --namespace <namespace>", "Target namespace", "default") .option("-t, --type <type>", "Data type") .option("--tags <tags>", "Tags (comma-separated)") .option("--metadata <json>", "Additional metadata (JSON)") .option("--owner <owner>", "Entry owner", "system") .option("--access-level <level>", "Access level (private|shared|public)", "shared") .option("--ttl <ms>", "Time-to-live in milliseconds", parseInt) .option("--compress", "Force compression") .action(async (key, value, options) => { try { const manager = await ensureMemoryManager(); // Parse value as JSON if possible let parsedValue; try { parsedValue = JSON.parse(value); } catch { parsedValue = value; } // Parse metadata if provided if (typeof options.metadata === "string") { try { const _metadata = JSON.parse(options.metadata); // Metadata is not used in simplified version void _metadata; // Acknowledge unused variable } catch (_error) { printError("Invalid metadata JSON format"); return; } } const entryId = await manager.store(key, parsedValue, { namespace: options.namespace, type: options.type, owner: options.owner, }); printSuccess("Entry stored successfully"); console.log(`📝 Entry ID: ${entryId}`); console.log(`🔑 Key: ${key}`); console.log(`📦 Namespace: ${options.namespace ?? "default"}`); console.log(`🏷️ Type: ${options.type ?? "auto-detected"}`); if (options.tags) { console.log(`🏷️ Tags: [${options.tags}]`); } if (options.ttl) { const expiresAt = new Date(Date.now() + options.ttl); console.log(`⏰ Expires: ${expiresAt.toLocaleString()}`); } } catch (error) { printError(`Store failed: ${getErrorMessage(error)}`); } }); // Get command memoryCmd .command("get") .description("Retrieve data with caching") .argument("<key>", "Entry key") .option("-n, --namespace <namespace>", "Target namespace") .option("--format <format>", "Output format (json|pretty)", "pretty") .action(async (key, options) => { try { const manager = await ensureMemoryManager(); const entry = await manager.retrieve(key); if (!entry) { printWarning(`Entry not found: ${key}`); return; } if (options.format === "json") { console.log(JSON.stringify(entry, null, 2)); } else { printSuccess(`Entry found: ${key}`); console.log(`📝 Entry ID: ${entry.id}`); console.log(`🔑 Key: ${entry.key}`); console.log(`📦 Namespace: ${entry.namespace}`); console.log(`🏷️ Type: ${entry.type}`); console.log(`👤 Owner: ${entry.owner}`); console.log(`📅 Created: ${entry.createdAt.toLocaleString()}`); console.log(`📅 Updated: ${entry.updatedAt.toLocaleString()}`); console.log("💾 Value:"); if (typeof entry.value === "string" && entry.value.length > 500) { console.log(`${entry.value.substring(0, 500)}...`); console.log(chalk.gray(`(showing first 500 characters of ${entry.value.length} total)`)); } else { console.log(JSON.stringify(entry.value, null, 2)); } } } catch (error) { printError(`Retrieve failed: ${getErrorMessage(error)}`); } }); // Delete command memoryCmd .command("delete") .description("Delete specific entries") .argument("<key>", "Entry key") .option("-n, --namespace <namespace>", "Target namespace") .option("--confirm", "Skip confirmation prompt") .action(async (key, options) => { try { const manager = await ensureMemoryManager(); // Find entry first const entry = await manager.retrieve(key); if (!entry) { printWarning(`Entry not found: ${key}`); return; } // Confirmation (simplified - in a real CLI, use a proper prompt library) if (!options.confirm) { console.log(`About to delete entry: ${key} (namespace: ${entry.namespace})`); console.log("Add --confirm to proceed without this prompt"); return; } const success = await manager.deleteEntry(entry.id); if (success) { printSuccess(`Entry deleted: ${key}`); } else { printError(`Failed to delete entry: ${key}`); } } catch (error) { printError(`Delete failed: ${getErrorMessage(error)}`); } }); // List command memoryCmd .command("list") .description("List entries with filtering") .option("-n, --namespace <namespace>", "Filter by namespace") .option("-t, --type <type>", "Filter by type") .option("--limit <num>", "Limit results", parseInt, 20) .option("--offset <num>", "Offset for pagination", parseInt, 0) .option("--sort-by <field>", "Sort by field", "updatedAt") .option("--sort-order <order>", "Sort order (asc|desc)", "desc") .action(async (options) => { try { const manager = await ensureMemoryManager(); const entries = manager.query({ namespace: options.namespace, type: options.type, limit: options.limit, offset: options.offset, }); const total = entries.length; if (entries.length === 0) { printInfo("No entries found"); return; } console.log(chalk.cyan(`\n📋 Memory Entries (${total} total):\n`)); for (const [i, entry] of entries.entries()) { const num = (options.offset || 0) + i + 1; console.log(chalk.blue(`${num}. ${entry.key}`)); console.log(` Namespace: ${entry.namespace} | Type: ${entry.type}`); console.log(` Updated: ${entry.updatedAt.toLocaleString()}`); console.log(); } if (total > entries.length) { const showing = (options.offset ?? 0) + entries.length; console.log(chalk.gray(`Showing ${showing} of ${total} entries`)); } } catch (error) { printError(`List failed: ${getErrorMessage(error)}`); } }); // Utility commands memoryCmd .command("namespaces") .description("List all namespaces") .action(async () => { try { const manager = await ensureMemoryManager(); const namespaces = await manager.listNamespaces(); if (namespaces.length === 0) { printInfo("No namespaces found"); return; } console.log(chalk.cyan("\n📁 Namespaces:\n")); namespaces.forEach((namespace, i) => { console.log(`${i + 1}. ${namespace}`); }); } catch (error) { printError(`Failed to list namespaces: ${getErrorMessage(error)}`); } }); memoryCmd .command("types") .description("List all data types") .action(async () => { try { const manager = await ensureMemoryManager(); const types = await manager.listTypes(); if (types.length === 0) { printInfo("No types found"); return; } console.log(chalk.cyan("\n🏷️ Data Types:\n")); types.forEach((type, i) => { console.log(`${i + 1}. ${type}`); }); } catch (error) { printError(`Failed to list types: ${getErrorMessage(error)}`); } }); memoryCmd .command("tags") .description("List all tags") .action(async () => { try { const manager = await ensureMemoryManager(); const tags = await manager.listTags(); if (tags.length === 0) { printInfo("No tags found"); return; } console.log(chalk.cyan("\n🏷️ Tags:\n")); tags.forEach((tag, i) => { console.log(`${i + 1}. ${tag}`); }); } catch (error) { printError(`Failed to list tags: ${getErrorMessage(error)}`); } }); // Configuration command memoryCmd .command("config") .description("View/update memory system configuration") .option("--show", "Show current configuration") .option("--set <json>", "Update configuration (JSON)") .action(async (options) => { try { const manager = await ensureMemoryManager(); if (typeof options.set === "string") { try { const updates = JSON.parse(options.set); await manager.updateConfiguration(updates); printSuccess("Configuration updated"); } catch (_error) { printError("Invalid configuration JSON format"); return; } } if (options.show || !options.set) { const config = await manager.getConfiguration(); console.log(chalk.cyan("\n⚙️ Memory System Configuration:\n")); console.log(JSON.stringify(config, null, 2)); } } catch (error) { printError(`Configuration operation failed: ${getErrorMessage(error)}`); } }); return memoryCmd; } //# sourceMappingURL=advanced-memory-commands.js.map