Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/EvoMap/evolver/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The cleanup module removes old GEP prompt artifacts to prevent disk bloat while preserving recent files for debugging. Location: src/ops/cleanup.js

Function

run()

Clean up old GEP artifacts. Location: src/ops/cleanup.js:20
function run()
deleted
number
Number of files deleted

Cleanup Policy

Artifact Pattern

Location: src/ops/cleanup.js:24
const files = fs.readdirSync(evoDir)
  .filter(f => /^gep_prompt_.*\.(json|txt)$/.test(f))
  .map(f => {
    const full = path.join(evoDir, f);
    const stat = fs.statSync(full);
    return { name: f, path: full, mtime: stat.mtimeMs };
  })
  .sort((a, b) => b.mtime - a.mtime); // newest first
Matched Files:
  • gep_prompt_*.json
  • gep_prompt_*.txt

Phase 1: Age-Based Cleanup

Location: src/ops/cleanup.js:9
const MAX_AGE_MS = 24 * 60 * 60 * 1000; // 24 hours
const MIN_KEEP = 10;

const filesToDelete = [];
for (let i = MIN_KEEP; i < files.length; i++) {
  if (now - files[i].mtime > MAX_AGE_MS) {
    filesToDelete.push(files[i].path);
  }
}

if (filesToDelete.length > 0) {
  deleted += safeBatchDelete(filesToDelete);
}
Policy:
  • Keep at least 10 most recent files
  • Delete files older than 24 hours (beyond the first 10)

Phase 2: Size-Based Cap

Location: src/ops/cleanup.js:49
const MAX_FILES = 10;
const remainingFiles = fs.readdirSync(evoDir)
  .filter(f => /^gep_prompt_.*\.(json|txt)$/.test(f))
  .map(f => {
    const full = path.join(evoDir, f);
    const stat = fs.statSync(full);
    return { name: f, path: full, mtime: stat.mtimeMs };
  })
  .sort((a, b) => b.mtime - a.mtime); // newest first

if (remainingFiles.length > MAX_FILES) {
  const toDelete = remainingFiles.slice(MAX_FILES).map(f => f.path);
  deleted += safeBatchDelete(toDelete);
}
Policy:
  • Keep maximum 10 files total
  • Delete oldest files beyond the cap

Safe Batch Delete

Location: src/ops/cleanup.js:12
function safeBatchDelete(batch) {
  let deleted = 0;
  for (const file of batch) {
    try {
      fs.unlinkSync(file);
      deleted++;
    } catch (_) {}
  }
  return deleted;
}
Deletion errors are silently ignored to prevent cleanup failures from blocking evolution.

CLI Usage

node src/ops/cleanup.js

Example Usage

const { run } = require('./src/ops/cleanup');

const count = run();
if (count > 0) {
  console.log('[Cleanup] Deleted', count, 'old artifacts');
} else {
  console.log('[Cleanup] No files to delete');
}

Integration with Evolution Cycle

Location: src/evolve.js:781
if (!IS_DRY_RUN) {
  performMaintenance();
} else {
  console.log('[Maintenance] Skipped (dry-run mode).');
}

function performMaintenance() {
  // Auto-update check
  checkAndAutoUpdate();
  
  // Clean up evolver's own hand sessions immediately
  const evolverFiles = files.filter(f => f.startsWith('evolver_hand_'));
  for (const f of evolverFiles) {
    try {
      fs.unlinkSync(path.join(AGENT_SESSIONS_DIR, f));
    } catch (_) {}
  }
  
  // Archive old non-evolver sessions when count exceeds threshold
  if (remaining < 100) return;
  
  const toArchive = fileStats.slice(0, fileStats.length - 50);
  for (const file of toArchive) {
    fs.renameSync(oldPath, newPath);
  }
  
  // GEP artifact cleanup
  require('./ops/cleanup').run();
}

Scheduled Cleanup

const { run } = require('./src/ops/cleanup');

function scheduleCleanup() {
  // Run cleanup every hour
  setInterval(() => {
    const count = run();
    if (count > 0) {
      console.log('[ScheduledCleanup] Deleted', count, 'artifact(s)');
    }
  }, 60 * 60 * 1000);
}

scheduleCleanup();

Cleanup Statistics

const fs = require('fs');
const path = require('path');
const { getEvolutionDir } = require('./gep/paths');

function getCleanupStats() {
  const evoDir = getEvolutionDir();
  const files = fs.readdirSync(evoDir)
    .filter(f => /^gep_prompt_.*\.(json|txt)$/.test(f))
    .map(f => {
      const full = path.join(evoDir, f);
      const stat = fs.statSync(full);
      return {
        name: f,
        size: stat.size,
        age: Date.now() - stat.mtimeMs
      };
    });
  
  const totalSize = files.reduce((sum, f) => sum + f.size, 0);
  const oldestAge = Math.max(...files.map(f => f.age));
  
  return {
    count: files.length,
    totalSizeMb: (totalSize / 1024 / 1024).toFixed(2),
    oldestAgeDays: (oldestAge / 1000 / 60 / 60 / 24).toFixed(1),
  };
}

const stats = getCleanupStats();
console.log('Artifact stats:', stats);
// Output: { count: 8, totalSizeMb: '12.5', oldestAgeDays: '2.3' }