arela
Version:
AI-powered CTO with multi-agent orchestration, code summarization, visual testing (web + mobile) for blazing fast development.
67 lines • 2.13 kB
JavaScript
import path from "node:path";
import fs from "fs-extra";
import { VectorMemory } from "./vector.js";
import { GraphMemory } from "./graph.js";
import { AuditMemory } from "./audit.js";
export class TriMemory {
cwd;
vector;
graph;
audit;
constructor(cwd = process.cwd()) {
this.cwd = cwd;
this.vector = new VectorMemory(cwd);
this.graph = new GraphMemory(cwd);
this.audit = new AuditMemory(cwd);
}
async init(options) {
await fs.ensureDir(path.join(this.cwd, ".arela", "memory"));
if (options?.refreshGraph || !(await this.graph.isReady())) {
const { ingestCodebase } = await import("../ingest/index.js");
await ingestCodebase(this.cwd, {
refresh: true,
verbose: options?.verbose,
});
}
if (options?.refreshVector) {
await this.vector.rebuildIndex({
progress: options.verbose,
});
}
await this.audit.init();
return this.getStats();
}
async query(question, topK) {
const semantic = await this.vector.query(question, topK);
const relatedFiles = new Set();
for (const match of semantic) {
const neighbors = await this.graph.findSlice(match.file);
neighbors.forEach((file) => relatedFiles.add(file));
}
return {
question,
semantic,
relatedFiles: Array.from(relatedFiles).sort(),
timestamp: new Date().toISOString(),
};
}
async impact(filePath) {
return this.graph.impact(filePath);
}
async auditTrail(filter) {
return this.audit.getAuditTrail(filter);
}
async logDecision(entry) {
await this.audit.logDecision(entry);
}
async getStats() {
const [vector, graph, audit] = await Promise.all([
this.vector.getStats(),
this.graph.getStats(),
this.audit.getStats(),
]);
return { vector, graph, audit };
}
}
export * from "./types.js";
//# sourceMappingURL=index.js.map