Skip to main content
Glama

COA Goldfish MCP

by anortham
cleanup-memory-files.tsโ€ข6.76 kB
#!/usr/bin/env ts-node /** * Safe cleanup of Memory object files after successful migration * Only removes files that contain Memory objects (have "type" field with memory types) * Preserves TodoLists and Checkpoints */ import { Storage } from '../src/core/storage.js'; import fs from 'fs-extra'; import { join } from 'path'; interface CleanupResult { success: boolean; totalFilesScanned: number; memoryFilesFound: number; filesDeleted: number; errors: string[]; deletedFiles: string[]; } async function cleanupMemoryFiles(dryRun: boolean = true): Promise<CleanupResult> { const result: CleanupResult = { success: true, totalFilesScanned: 0, memoryFilesFound: 0, filesDeleted: 0, errors: [], deletedFiles: [] }; try { const storage = new Storage(); const basePath = storage.getBasePath(); const workspaces = await storage.discoverWorkspaces(); console.log(`Found ${workspaces.length} workspaces to clean`); for (const workspace of workspaces) { console.log(`\n--- Cleaning workspace: ${workspace} ---`); // Check todos directory for Memory objects const todosDir = join(basePath, workspace, 'todos'); if (await fs.pathExists(todosDir)) { const files = await fs.readdir(todosDir); const jsonFiles = files.filter(f => f.endsWith('.json')); console.log(`Found ${jsonFiles.length} JSON files in todos directory`); result.totalFilesScanned += jsonFiles.length; for (const file of jsonFiles) { const filePath = join(todosDir, file); try { const data = await fs.readJson(filePath); // Check if it's a Memory object (has "type" field with memory types) if (data.type && ['general', 'todo', 'context'].includes(data.type)) { result.memoryFilesFound++; console.log(` ๐Ÿ—‘๏ธ Memory object: ${file} (type: ${data.type})`); if (!dryRun) { await fs.unlink(filePath); result.filesDeleted++; result.deletedFiles.push(filePath); } } else if (data.title && data.items && Array.isArray(data.items)) { // This is a TodoList - skip it console.log(` โœ… TodoList: ${file} (keeping)`); } else { console.log(` โ“ Unknown format: ${file} (keeping)`); } } catch (error) { const errorMsg = `Failed to process ${filePath}: ${error}`; result.errors.push(errorMsg); console.log(` โŒ ${errorMsg}`); } } } // Also check checkpoints directories for any stray Memory objects const checkpointsDir = join(basePath, workspace, 'checkpoints'); if (await fs.pathExists(checkpointsDir)) { const dateDirs = await fs.readdir(checkpointsDir); for (const dateDir of dateDirs) { const datePath = join(checkpointsDir, dateDir); const stat = await fs.stat(datePath).catch(() => null); if (!stat || !stat.isDirectory()) continue; const files = await fs.readdir(datePath); const jsonFiles = files.filter(f => f.endsWith('.json')); result.totalFilesScanned += jsonFiles.length; for (const file of jsonFiles) { const filePath = join(datePath, file); try { const data = await fs.readJson(filePath); // Check if it's a Memory object in checkpoints (shouldn't happen but check anyway) if (data.type && ['general', 'todo', 'context'].includes(data.type)) { result.memoryFilesFound++; console.log(` ๐Ÿ—‘๏ธ Memory object in checkpoints: ${file} (type: ${data.type})`); if (!dryRun) { await fs.unlink(filePath); result.filesDeleted++; result.deletedFiles.push(filePath); } } } catch (error) { // Silently skip corrupted files in checkpoints } } } } } } catch (error) { result.success = false; result.errors.push(`Cleanup failed: ${error}`); } return result; } async function main() { const args = process.argv.slice(2); const dryRun = !args.includes('--execute'); console.log('='.repeat(60)); console.log('๐Ÿงน COA Goldfish MCP - Memory Files Cleanup Tool'); console.log('='.repeat(60)); console.log(`Mode: ${dryRun ? '๐Ÿ” DRY RUN (preview only)' : 'โšก EXECUTE (will delete files)'}`); console.log(); console.log('๐ŸŽฏ Target: Memory objects (type: general|todo|context)'); console.log('โœ… Preserve: TodoLists and Checkpoints'); console.log(); try { const result = await cleanupMemoryFiles(dryRun); // Display results console.log(); console.log('๐Ÿ“Š CLEANUP RESULTS'); console.log('='.repeat(40)); console.log(`Status: ${result.success ? 'โœ… SUCCESS' : 'โŒ FAILED'}`); console.log(`Files Scanned: ${result.totalFilesScanned}`); console.log(`Memory Files Found: ${result.memoryFilesFound}`); console.log(`Files ${dryRun ? 'Would Delete' : 'Deleted'}: ${dryRun ? result.memoryFilesFound : result.filesDeleted}`); console.log(`Errors: ${result.errors.length}`); console.log(); if (result.errors.length > 0) { console.log('โŒ ERRORS'); console.log('-'.repeat(40)); result.errors.forEach(error => console.error(error)); console.log(); } if (dryRun && result.memoryFilesFound > 0) { console.log('๐Ÿ’ก To execute the cleanup, run:'); console.log(' npm run cleanup:memory -- --execute'); console.log(); console.log('โš ๏ธ This will permanently delete all Memory object files!'); console.log(' TodoLists and Checkpoints will be preserved.'); console.log(); } if (!dryRun && result.success) { console.log('๐ŸŽ‰ Cleanup completed successfully!'); console.log(`๐Ÿ—‘๏ธ Deleted ${result.filesDeleted} Memory object files`); console.log('โœ… Storage architecture simplification complete!'); console.log(); console.log('๐Ÿ“ˆ Your storage now contains only:'); console.log(' โ€ข Checkpoints (session snapshots)'); console.log(' โ€ข TodoLists (enhanced with metadata, lifecycle, etc.)'); console.log(); } } catch (error) { console.error('๐Ÿ’ฅ Cleanup failed with error:', error); process.exit(1); } } main().catch(error => { console.error('๐Ÿ’ฅ Unexpected error:', error); process.exit(1); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/anortham/coa-goldfish-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server