docs: enterprise refactor plan with ralph specs

This commit is contained in:
debian
2026-03-04 16:17:03 -05:00
parent 4c92712d20
commit f8191133c8
204 changed files with 32722 additions and 422 deletions

94
src/index.ts Normal file
View File

@@ -0,0 +1,94 @@
/**
* ABE — Autonomous Bug Explorer
* Entry point: wires all components together and starts exploration.
*
* Usage:
* npm run explore -- --url http://localhost:3000 --output ./reports
* ts-node src/index.ts http://localhost:3000
*/
import { ExplorationEngine } from './core/ExplorationEngine';
import { StateGraph } from './core/StateGraph';
import { FileLogger } from './core/Logger';
import { PlaywrightAgent } from './plugins/agents/PlaywrightAgent';
import { ScreenshotCollector } from './plugins/collectors/ScreenshotCollector';
import { NetworkCollector } from './plugins/collectors/NetworkCollector';
import { DOMSnapshotCollector } from './plugins/collectors/DOMSnapshotCollector';
import { JSONExporter } from './plugins/exporters/JSONExporter';
import { MarkdownExporter } from './plugins/exporters/MarkdownExporter';
import { PlaywrightReproducer } from './plugins/reproducers/PlaywrightReproducer';
// ─── Parse CLI arguments ─────────────────────────────────────────────────────
function parseArgs(): { url: string; outputDir: string; seed: number; maxSteps: number } {
const args = process.argv.slice(2);
let url = 'http://localhost:3000';
let outputDir = './reports';
let seed = 42;
let maxSteps = 100;
for (let i = 0; i < args.length; i++) {
if (args[i] === '--url' && args[i + 1]) url = args[++i];
else if (args[i] === '--output' && args[i + 1]) outputDir = args[++i];
else if (args[i] === '--seed' && args[i + 1]) seed = parseInt(args[++i], 10);
else if (args[i] === '--max-steps' && args[i + 1]) maxSteps = parseInt(args[++i], 10);
else if (!args[i].startsWith('--')) url = args[i];
}
return { url, outputDir, seed, maxSteps };
}
// ─── Main ─────────────────────────────────────────────────────────────────────
async function main(): Promise<void> {
const { url, outputDir, seed, maxSteps } = parseArgs();
const sessionId = `${new Date().toISOString().replace(/[:.]/g, '-')}_seed${seed}`;
const logger = new FileLogger('./logs', sessionId);
const graph = new StateGraph();
const agent = new PlaywrightAgent({ seed, headless: true, logger });
const collectors = [
new ScreenshotCollector(outputDir),
new NetworkCollector(),
new DOMSnapshotCollector(outputDir),
];
const exporters = [
new JSONExporter(url),
new MarkdownExporter(),
];
const reproducer = new PlaywrightReproducer();
const engine = new ExplorationEngine({
graph,
agent,
collectors,
exporters,
reproducer,
logger,
seed,
url,
maxSteps,
outputDir,
});
console.log(`[ABE] Starting exploration of ${url} (seed=${seed}, maxSteps=${maxSteps})`);
try {
const result = await engine.run();
console.log(`[ABE] Exploration complete.`);
console.log(` States visited : ${result.statesVisited}`);
console.log(` Anomalies found: ${result.anomaliesFound}`);
if (result.anomaliesFound > 0) {
console.log(` Reports saved to: ${outputDir}/`);
}
} catch (err) {
console.error('[ABE] Fatal error:', err);
process.exit(1);
}
}
main();