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 ❤️.
83 lines (82 loc) • 2.95 kB
JavaScript
// indexCmd.ts
import fg from 'fast-glob';
import path from 'path';
import { initSchema } from '../db/schema.js';
import { detectFileType } from '../fileRules/detectFileType.js';
import { startDaemon } from './DaemonCmd.js';
import { IGNORED_FOLDER_GLOBS } from '../fileRules/ignoredPaths.js';
import { Config } from '../config.js';
import { log } from '../utils/log.js';
import lockfile from 'proper-lockfile';
import { classifyFile } from '../fileRules/classifyFile.js';
import { getDbForRepo, getDbPathForRepo } from '../db/client.js';
import { upsertFileTemplate } from '../db/sqlTemplates.js';
async function lockDb() {
try {
return await lockfile.lock(getDbPathForRepo());
}
catch (err) {
log('❌ Failed to acquire DB lock: ' + err);
throw err;
}
}
export async function runIndexCommand() {
try {
initSchema();
}
catch (err) {
console.error('❌ Failed to initialize schema:', err);
process.exit(1);
}
const indexDir = Config.getIndexDir() || process.cwd();
Config.setIndexDir(indexDir); // persist if not already saved
log(`📂 Indexing files in: ${indexDir}`);
const files = await fg('**/*.*', {
cwd: indexDir,
ignore: IGNORED_FOLDER_GLOBS,
absolute: true,
});
const db = getDbForRepo();
const release = await lockDb();
const countByExt = {};
let count = 0;
try {
for (const file of files) {
const classification = classifyFile(file);
if (classification !== 'valid') {
log(`⏭️ Skipping (${classification}): ${file}`);
continue;
}
try {
const normalizedPath = path.normalize(file).replace(/\\/g, '/');
const filename = path.basename(normalizedPath);
const type = detectFileType(file);
// -----------------------------
// ENQUEUE: mark file as unprocessed
// -----------------------------
db.prepare(upsertFileTemplate).run({
path: normalizedPath,
filename,
summary: null,
type,
lastModified: null,
indexedAt: null,
});
const ext = path.extname(file);
countByExt[ext] = (countByExt[ext] || 0) + 1;
log(`📄 Enqueued: ${path.relative(indexDir, file)}`);
count++;
}
catch (err) {
log(`⚠️ Skipped in indexCmd ${file}: ${err instanceof Error ? err.message : err}`);
}
}
}
finally {
await release();
}
log('📊 Files by extension:', JSON.stringify(countByExt, null, 2));
log(`✅ Done. Enqueued ${count} files for indexing.`);
// Kick the daemon — it now owns all processing
startDaemon();
}