scai
Version:
> **AI-powered CLI for local code analysis, commit message suggestions, and natural-language queries.** 100% local, private, GDPR-friendly, made in Denmark/EU with ❤️.
73 lines (72 loc) • 2.86 kB
JavaScript
import * as fs from "fs/promises";
import * as path from "path";
import { logInputOutput } from "../../utils/promptLogHelper.js";
import { getDbForRepo } from "../../db/client.js";
import { updateFileWithSummary, upsertFileFtsTemplate, } from "../../db/sqlTemplates.js";
export const fileReaderModule = {
name: "fileReader",
description: "Reads files from disk only if they are not available in the DB, updates DB and FTS.",
groups: ["analysis"],
run: async (input) => {
let filePaths = [];
logInputOutput('filereader', 'input', input.content);
if (Array.isArray(input.content)) {
filePaths = input.content;
}
else if (typeof input.content === "object" && input.content !== null) {
const obj = input.content;
if (Array.isArray(obj.filePaths))
filePaths = obj.filePaths;
}
if (filePaths.length === 0) {
const emptyOutput = {
query: input.query,
data: { files: [] },
};
logInputOutput("fileReader", "output", emptyOutput.data);
return emptyOutput;
}
const db = getDbForRepo();
const files = [];
for (const filePath of filePaths) {
const fullPath = path.resolve(filePath);
// 1️⃣ Check DB for existing summary/content
const row = db
.prepare("SELECT path, content_text, summary FROM files WHERE path = ?")
.get(fullPath);
if (row?.content_text) {
files.push({ filePath: fullPath, content: row.content_text });
continue; // already in DB, no need to read disk
}
// 2️⃣ Read file from disk
let content = "";
try {
content = await fs.readFile(fullPath, "utf-8");
}
catch (err) {
content = `ERROR: ${err.message}`;
}
files.push({ filePath: fullPath, content });
// 3️⃣ Update DB and FTS if content successfully read
if (!content.startsWith("ERROR")) {
db.prepare(updateFileWithSummary).run({
path: fullPath,
summary: null, // optionally leave null; summary can be generated later
contentText: content,
});
db.prepare(upsertFileFtsTemplate).run({
path: fullPath,
filename: path.basename(fullPath),
summary: null,
contentText: content,
});
}
}
const output = {
query: input.query,
data: { files },
};
logInputOutput("fileReader", "output", output.data);
return output;
},
};