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 ❤️.
65 lines (64 loc) • 2.19 kB
JavaScript
// src/utils/loadRelevantFolderCapsules.ts
import { getDbForRepo } from '../db/client.js';
import path from 'path';
import fs from 'fs';
export function loadRelevantFolderCapsules(paths) {
const db = getDbForRepo();
const capsules = [];
// 1️⃣ Query DB first
const placeholders = paths.map(() => '?').join(',');
const stmt = db.prepare(`SELECT capsule_json FROM folder_capsules WHERE path IN (${placeholders})`);
const dbRows = stmt.all(...paths);
for (const row of dbRows) {
try {
const c = JSON.parse(row.capsule_json);
capsules.push(c);
}
catch {
// skip malformed JSON
}
}
// 2️⃣ Generate ephemeral capsules for missing paths
const existingPaths = new Set(capsules.map(c => c.path));
for (const p of paths) {
if (existingPaths.has(p))
continue;
if (!fs.existsSync(p))
continue;
const files = fs.readdirSync(p, { withFileTypes: true })
.filter(f => f.isFile())
.map(f => f.name);
const byType = {};
for (const f of files) {
const ext = path.extname(f).replace('.', '') || 'unknown';
byType[ext] = (byType[ext] || 0) + 1;
}
capsules.push({
path: p,
depth: p.split('/').length,
stats: { fileCount: files.length, byType },
roles: [],
concerns: [],
keyFiles: files
.filter(f => /index|main|cli|app|server|config/i.test(f))
.slice(0, 5)
.map(f => ({ path: path.join(p, f), reason: 'heuristic key file' })),
dependencies: { importsFrom: [], usedBy: [] },
confidence: 0.35,
});
}
// 3️⃣ Always add root capsule
if (!capsules.some(c => c.path === '/')) {
capsules.push({
path: '/',
depth: 1,
stats: { fileCount: 0, byType: {} },
roles: [],
concerns: [],
keyFiles: [],
dependencies: { importsFrom: [], usedBy: [] },
confidence: 0.5,
});
}
return capsules;
}