superdesign_cleanup
Automatically remove outdated design files by specifying age and count limits. Set max age in days and keep only the latest designs to optimize storage. Optionally preview deletions with dry run mode.
Instructions
Clean up old design files based on age and count limits
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Show what would be deleted without actually deleting | |
| max_age_days | No | Delete designs older than X days (default: 30) | |
| max_count | No | Keep only the latest X designs (default: 50) | |
| workspace_path | No | Workspace path (defaults to current directory) |
Implementation Reference
- src/index.ts:2402-2457 (handler)MCP tool handler for 'superdesign_cleanup' that parses input, calls performCleanup helper, formats and returns cleanup results.case "superdesign_cleanup": { const { workspace_path, max_age_days, max_count, dry_run } = CleanupSchema.parse(args); try { const superdesignDir = getSuperdeignDirectory(workspace_path); const result = performCleanup(superdesignDir, max_age_days, max_count, dry_run || false); let response = `CLEANUP RESULTS:\n\n`; if (dry_run) { response += `DRY RUN - No files were actually deleted\n\n`; } if (result.deleted.length > 0) { response += `Files ${dry_run ? 'to be deleted' : 'deleted'} (${result.deleted.length}):\n`; result.deleted.forEach(file => { response += ` - ${file}\n`; }); response += `\n`; } if (result.kept.length > 0) { response += `Files kept (${result.kept.length}):\n`; result.kept.forEach(file => { response += ` - ${file}\n`; }); response += `\n`; } if (result.errors.length > 0) { response += `Errors (${result.errors.length}):\n`; result.errors.forEach(error => { response += ` - ${error}\n`; }); response += `\n`; } if (result.deleted.length === 0 && result.errors.length === 0) { response += `No files needed cleanup.\n`; } const settings = getCleanupSettings(superdesignDir); response += `\nCleanup settings:\n`; response += ` - Max age: ${max_age_days || settings.maxAgeDays} days\n`; response += ` - Max count: ${max_count || settings.maxCount} files\n`; response += ` - Enabled: ${settings.enabled}\n`; return { content: [{ type: "text", text: response }], }; } catch (error: any) { return { content: [{ type: "text", text: `Error during cleanup: ${error.message}` }], }; } }
- src/index.ts:54-59 (schema)Zod schema for validating input parameters to the superdesign_cleanup tool.const CleanupSchema = z.object({ workspace_path: z.string().optional().describe("Workspace path (defaults to current directory)"), max_age_days: z.number().optional().describe("Delete designs older than X days (default: 30)"), max_count: z.number().optional().describe("Keep only the latest X designs (default: 50)"), dry_run: z.boolean().optional().describe("Show what would be deleted without actually deleting") });
- src/index.ts:2024-2035 (registration)Tool registration in the list of available MCP tools, including name, description, and JSON input schema.name: "superdesign_cleanup", description: "Clean up old design files based on age and count limits", inputSchema: { type: "object", properties: { workspace_path: { type: "string", description: "Workspace path (defaults to current directory)" }, max_age_days: { type: "number", description: "Delete designs older than X days (default: 30)" }, max_count: { type: "number", description: "Keep only the latest X designs (default: 50)" }, dry_run: { type: "boolean", description: "Show what would be deleted without actually deleting" } }, }, },
- src/index.ts:235-283 (helper)Core cleanup logic: sorts designs by age, deletes old/excess files or simulates in dry-run, updates metadata.function performCleanup(superdesignDir: string, maxAgeDays?: number, maxCount?: number, dryRun: boolean = false): { deleted: string[], kept: string[], errors: string[] } { const settings = getCleanupSettings(superdesignDir); const actualMaxAge = maxAgeDays ?? settings.maxAgeDays; const actualMaxCount = maxCount ?? settings.maxCount; const metadata = getDesignMetadata(superdesignDir); const now = new Date(); const cutoffDate = new Date(now.getTime() - (actualMaxAge * 24 * 60 * 60 * 1000)); // Sort by creation date (newest first) const sortedMetadata = metadata.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()); const deleted: string[] = []; const kept: string[] = []; const errors: string[] = []; for (let i = 0; i < sortedMetadata.length; i++) { const design = sortedMetadata[i]; const createdAt = new Date(design.createdAt); const shouldDelete = i >= actualMaxCount || createdAt < cutoffDate; if (shouldDelete) { if (!dryRun) { try { const designIterationsDir = path.join(superdesignDir, 'design_iterations'); const filePath = path.join(designIterationsDir, design.fileName); if (existsSync(filePath)) { unlinkSync(filePath); // Remove from metadata const allMetadata = loadMetadata(superdesignDir); const filteredMetadata = allMetadata.filter(m => m.fileName !== design.fileName); saveMetadata(superdesignDir, filteredMetadata); } deleted.push(design.fileName); } catch (error: any) { errors.push(`Failed to delete ${design.fileName}: ${error.message}`); } } else { deleted.push(design.fileName); } } else { kept.push(design.fileName); } } return { deleted, kept, errors }; }