erosolar-cli
Version:
Unified AI agent framework for the command line - Multi-provider support with schema-driven tools, code intelligence, and transparent reasoning
276 lines (234 loc) ⢠7.96 kB
JavaScript
/**
* ISOLATED VERIFICATION WRAPPER
*
* This script provides a clean interface between the main CLI and the
* isolated verification runner. It:
* - Spawns completely separate processes for verification
* - Handles communication via stdin/stdout
* - Provides structured results to the main CLI
* - Ensures no shared state between verification and main runtime
*
* USAGE: node scripts/isolated-verification-wrapper.mjs <command>
*/
import { spawn } from 'node:child_process';
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
const __dirname = dirname(fileURLToPath(import.meta.url));
// ============================================================================
// VERIFICATION INTERFACE
// ============================================================================
class IsolatedVerificationWrapper {
constructor() {
this.verifierPath = join(__dirname, 'isolated-verification-runner.mjs');
}
/**
* Verify task completion in isolated process
*/
async verifyTaskCompletion(taskDescription, changes = {}) {
console.log('š LAUNCHING ISOLATED VERIFICATION');
console.log('===================================');
return new Promise((resolve, reject) => {
const child = spawn(process.execPath, [
this.verifierPath,
'task',
taskDescription
], {
stdio: ['pipe', 'pipe', 'pipe'],
cwd: process.cwd(),
env: {
...process.env,
// Ensure complete isolation
NODE_NO_WARNINGS: '1',
VERIFICATION_ISOLATED: 'true',
// Prevent any shared module cache
NODE_OPTIONS: '--max-old-space-size=512 --no-warnings'
}
});
let stdout = '';
let stderr = '';
child.stdout.on('data', (data) => {
stdout += data.toString();
});
child.stderr.on('data', (data) => {
stderr += data.toString();
});
child.on('close', (code) => {
try {
if (code === 0) {
const result = JSON.parse(stdout);
resolve(result);
} else {
reject(new Error(`Verification failed with code ${code}: ${stderr}`));
}
} catch (error) {
reject(new Error(`Failed to parse verification result: ${error.message}`));
}
});
child.on('error', (error) => {
reject(new Error(`Failed to spawn verification process: ${error.message}`));
});
});
}
/**
* Verify build system in isolated process
*/
async verifyBuildSystem() {
return this.runIsolatedVerification('build');
}
/**
* Verify test system in isolated process
*/
async verifyTestSystem() {
return this.runIsolatedVerification('test');
}
/**
* Verify health check in isolated process
*/
async verifyHealthCheck() {
return this.runIsolatedVerification('health');
}
/**
* Generic isolated verification runner
*/
async runIsolatedVerification(type) {
return new Promise((resolve, reject) => {
const child = spawn(process.execPath, [
this.verifierPath,
type
], {
stdio: ['pipe', 'pipe', 'pipe'],
cwd: process.cwd(),
env: {
...process.env,
NODE_NO_WARNINGS: '1',
VERIFICATION_ISOLATED: 'true',
NODE_OPTIONS: '--max-old-space-size=512'
}
});
let stdout = '';
let stderr = '';
child.stdout.on('data', (data) => {
stdout += data.toString();
});
child.stderr.on('data', (data) => {
stderr += data.toString();
});
child.on('close', (code) => {
if (code === 0) {
try {
const result = JSON.parse(stdout);
resolve(result);
} catch (error) {
resolve({ success: true, output: stdout });
}
} else {
reject(new Error(`Verification failed: ${stderr}`));
}
});
child.on('error', (error) => {
reject(new Error(`Failed to spawn verification: ${error.message}`));
});
});
}
/**
* Generate human-readable verification report
*/
generateReport(result) {
let report = '\nš ISOLATED VERIFICATION REPORT\n';
report += '================================\n\n';
if (result.overallStatus) {
const statusIcon = result.overallStatus === 'SUCCESS' ? 'ā
' :
result.overallStatus === 'PARTIAL_SUCCESS' ? 'ā ļø' : 'ā';
report += `${statusIcon} OVERALL STATUS: ${result.overallStatus}\n\n`;
}
if (result.verificationSteps) {
report += 'š VERIFICATION STEPS:\n';
result.verificationSteps.forEach((step, index) => {
const stepIcon = step.success ? 'ā
' : step.critical ? 'ā' : 'ā ļø';
report += ` ${stepIcon} ${step.name}\n`;
if (step.details) {
const lines = step.details.split('\n').slice(0, 3);
lines.forEach(line => {
if (line.trim()) report += ` ${line}\n`;
});
}
});
}
if (result.success !== undefined) {
const icon = result.success ? 'ā
' : 'ā';
report += `\n${icon} VERIFICATION: ${result.success ? 'PASSED' : 'FAILED'}\n`;
}
report += '\nš VERIFICATION ISOLATION: COMPLETE\n';
report += ' ⢠Separate Node.js process\n';
report += ' ⢠Independent memory space\n';
report += ' ⢠No shared state with main CLI\n';
return report;
}
}
// ============================================================================
// CLI INTERFACE
// ============================================================================
/**
* Main CLI entry point
*/
async function main() {
const args = process.argv.slice(2);
if (args.length === 0) {
console.error('Usage: node scripts/isolated-verification-wrapper.mjs <command> [args...]');
console.error('');
console.error('Commands:');
console.error(' task <description> - Verify task completion');
console.error(' build - Verify build system');
console.error(' test - Verify test system');
console.error(' health - Verify health check');
console.error('');
console.error('Example:');
console.error(' node scripts/isolated-verification-wrapper.mjs task "Fix verification system"');
process.exit(1);
}
const wrapper = new IsolatedVerificationWrapper();
const command = args[0];
try {
let result;
switch (command) {
case 'task':
const taskDescription = args.slice(1).join(' ') || 'Unknown task';
result = await wrapper.verifyTaskCompletion(taskDescription);
break;
case 'build':
result = await wrapper.verifyBuildSystem();
break;
case 'test':
result = await wrapper.verifyTestSystem();
break;
case 'health':
result = await wrapper.verifyHealthCheck();
break;
default:
console.error(`Unknown command: ${command}`);
process.exit(1);
}
// Generate and display report
const report = wrapper.generateReport(result);
console.log(report);
// Exit with appropriate code
// Only exit with error if critical verification fails
const success = result.overallStatus !== 'FAILED' &&
!(result.success === false && result.critical);
process.exit(success ? 0 : 1);
} catch (error) {
console.error('ā Verification wrapper failed:', error.message);
process.exit(1);
}
}
// Run if called directly
if (import.meta.url === `file://${process.argv[1]}`) {
main().catch(error => {
console.error('Fatal error in verification wrapper:', error);
process.exit(1);
});
}
// Export for use in main CLI
export { IsolatedVerificationWrapper };