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 ❤️.
64 lines (63 loc) • 1.72 kB
JavaScript
import { getDbForRepo } from '../db/client.js';
import { log } from '../utils/log.js';
import { countUnprocessedFiles } from '../db/sqlTemplates.js';
/**
* LOOP 1 — Fast indexing
*/
export function hasUnindexedFiles() {
try {
const db = getDbForRepo();
const row = db.prepare(countUnprocessedFiles).get();
return row.count > 0;
}
catch (err) {
log('❌ hasUnindexedFiles failed:', err);
return false;
}
}
/**
* LOOP 2 — Folder capsules
* Any folder that contains files but lacks a capsule
*/
export function hasUncapsuledFolders() {
try {
const db = getDbForRepo();
const row = db.prepare(`
SELECT COUNT(*) AS count
FROM (
SELECT DISTINCT
substr(path, 1, length(path) - length(filename) - 1) AS folder
FROM files
WHERE processing_status NOT IN ('skipped', 'failed')
) folders
LEFT JOIN folder_capsules fc
ON fc.path = folders.folder
WHERE fc.path IS NULL
`).get();
return row.count > 0;
}
catch (err) {
log('❌ hasUncapsuledFolders failed:', err);
return false;
}
}
/**
* LOOP 3 — Knowledge graph
* Files indexed but KG not extracted yet
*/
export function hasPendingKgWork() {
try {
const db = getDbForRepo();
const row = db.prepare(`
SELECT COUNT(*) AS count
FROM files
WHERE functions_extracted_at IS NULL
AND processing_status NOT IN ('skipped', 'failed')
`).get();
return row.count > 0;
}
catch (err) {
log('❌ hasPendingKgWork failed:', err);
return false;
}
}