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 lifecycle module provides commands to manage the Evolver loop process. It supports starting, stopping, restarting, checking status, viewing logs, and performing health checks.
Location: src/ops/lifecycle.js
CLI Usage
node src/ops/lifecycle.js [start|stop|restart|status|log|check]
Functions
start()
Start the Evolver loop in detached mode.
Location: src/ops/lifecycle.js:58
Delay before starting (in milliseconds)
started or already_running
Process ID of started loop
Array of existing PIDs (if already running)
Example:
const { start } = require('./src/ops/lifecycle');
const result = start({ delayMs: 2000 });
console.log(result);
// { status: 'started', pid: 12345 }
stop()
Stop all running Evolver loop processes.
Location: src/ops/lifecycle.js:88
Array of PIDs that were stopped
Example:
const { stop } = require('./src/ops/lifecycle');
const result = stop();
console.log(result);
// { status: 'stopped', killed: [12345, 12346] }
restart()
Restart the Evolver loop (stop + start).
Location: src/ops/lifecycle.js:116
function restart(options)
Delay before restarting (in milliseconds)
Process ID of restarted loop
Example:
node src/ops/lifecycle.js restart
status()
Check if Evolver loop is running.
Location: src/ops/lifecycle.js:121
Whether the loop is running
Array of running processes with pid and cmd
Path to log file (relative to workspace)
Example:
const { status } = require('./src/ops/lifecycle');
const result = status();
console.log(result);
// {
// running: true,
// pids: [{ pid: 12345, cmd: 'node skills/feishu-evolver-wrapper/index.js --loop' }],
// log: 'memory/evolver.log'
// }
tailLog()
View recent log entries.
Location: src/ops/lifecycle.js:129
Number of lines to display
Error message (if no log file exists)
Example:
node src/ops/lifecycle.js log
checkHealth()
Check if the loop is healthy and responsive.
Location: src/ops/lifecycle.js:138
Whether the loop is healthy
Reason if unhealthy: not_running or stagnation
Minutes since last log update (if stagnant)
Array of running PIDs (if healthy)
Stagnation Detection:
Location: src/ops/lifecycle.js:13
const MAX_SILENCE_MS = 30 * 60 * 1000; // 30 minutes
if (fs.existsSync(LOG_FILE)) {
const silenceMs = Date.now() - fs.statSync(LOG_FILE).mtimeMs;
if (silenceMs > MAX_SILENCE_MS) {
return {
healthy: false,
reason: 'stagnation',
silenceMinutes: Math.round(silenceMs / 60000)
};
}
}
Example:
node src/ops/lifecycle.js check
# Automatically restarts if unhealthy
Process Discovery
Location: src/ops/lifecycle.js:25
function getRunningPids() {
const out = execSync('ps -e -o pid,args', { encoding: 'utf8' });
const pids = [];
for (const line of out.split('\n')) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith('PID')) continue;
const parts = trimmed.split(/\s+/);
const pid = parseInt(parts[0], 10);
const cmd = parts.slice(1).join(' ');
if (pid === process.pid) continue; // Skip self
// Match evolver loop processes
if (cmd.includes('node') && cmd.includes('index.js') && cmd.includes('--loop')) {
if (cmd.includes('feishu-evolver-wrapper') || cmd.includes('skills/evolver')) {
pids.push(pid);
}
}
}
return [...new Set(pids)].filter(isPidRunning);
}
Loop Script Selection
Location: src/ops/lifecycle.js:15
function getLoopScript() {
// Prefer wrapper if exists, fallback to core evolver
if (process.env.EVOLVER_LOOP_SCRIPT) {
return process.env.EVOLVER_LOOP_SCRIPT;
}
const wrapper = path.join(WORKSPACE_ROOT, 'skills/feishu-evolver-wrapper/index.js');
if (fs.existsSync(wrapper)) {
return wrapper;
}
return path.join(getRepoRoot(), 'index.js');
}
Environment Setup
Location: src/ops/lifecycle.js:73
const env = Object.assign({}, process.env);
const npmGlobal = path.join(process.env.HOME || '', '.npm-global/bin');
if (env.PATH && !env.PATH.includes(npmGlobal)) {
env.PATH = npmGlobal + ':' + env.PATH;
}
const child = spawn('node', [script, '--loop'], {
detached: true,
stdio: ['ignore', out, err],
cwd: WORKSPACE_ROOT,
env: env
});
child.unref();
Complete Example
const lifecycle = require('./src/ops/lifecycle');
// Start the loop
const startResult = lifecycle.start();
if (startResult.status === 'started') {
console.log('Evolver loop started:', startResult.pid);
}
// Check status
const statusResult = lifecycle.status();
if (statusResult.running) {
console.log('Running processes:', statusResult.pids);
console.log('Log file:', statusResult.log);
}
// Check health
const healthResult = lifecycle.checkHealth();
if (!healthResult.healthy) {
console.error('Unhealthy:', healthResult.reason);
if (healthResult.reason === 'stagnation') {
console.log('Silence:', healthResult.silenceMinutes, 'minutes');
}
// Auto-restart
lifecycle.restart();
}
// View logs
const logResult = lifecycle.tailLog(50);
if (logResult.content) {
console.log(logResult.content);
}
// Stop the loop
const stopResult = lifecycle.stop();
if (stopResult.status === 'stopped') {
console.log('Stopped PIDs:', stopResult.killed);
}