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 ❤️.
125 lines (115 loc) • 4.38 kB
JavaScript
import { getDbForRepo } from "./client.js";
export function initSchema() {
const db = getDbForRepo();
// --- Core tables ---
db.exec(`
CREATE TABLE IF NOT EXISTS files (
id INTEGER PRIMARY KEY AUTOINCREMENT,
path TEXT UNIQUE, -- full path
filename TEXT,
summary TEXT, -- optional, can be generated later
content_text TEXT, -- actual file content
type TEXT, -- file type
last_modified TEXT, -- file system last modified
indexed_at TEXT, -- timestamp when indexed
functions_extracted_at TEXT, -- timestamp when functions/classes extracted
processing_status TEXT NOT NULL DEFAULT 'unprocessed' -- tracks pipeline stage
);
CREATE VIRTUAL TABLE IF NOT EXISTS files_fts
USING fts5(
filename,
summary,
path,
content_text,
content='files',
content_rowid='id'
);
`);
// --- Folder capsules ---
db.exec(`
CREATE TABLE IF NOT EXISTS folder_capsules (
id INTEGER PRIMARY KEY AUTOINCREMENT,
path TEXT UNIQUE NOT NULL,
depth INTEGER NOT NULL,
capsule_json TEXT NOT NULL,
confidence REAL,
last_generated TEXT,
source_file_count INTEGER
);
CREATE INDEX IF NOT EXISTS idx_folder_capsules_path
ON folder_capsules(path);
CREATE INDEX IF NOT EXISTS idx_folder_capsules_depth
ON folder_capsules(depth);
`);
// --- Functions table ---
db.exec(`
CREATE TABLE IF NOT EXISTS functions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
file_id INTEGER REFERENCES files(id),
name TEXT,
unique_id TEXT UNIQUE, -- e.g. "buildContextualPrompt@cli/src/utils/buildContextualPrompt.ts"
start_line INTEGER,
end_line INTEGER,
content TEXT,
lang TEXT
);
CREATE INDEX IF NOT EXISTS idx_functions_file_id ON functions(file_id);
CREATE INDEX IF NOT EXISTS idx_functions_unique_id ON functions(unique_id);
`);
// --- Graph-specific additions ---
db.exec(`
CREATE TABLE IF NOT EXISTS graph_classes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
file_id INTEGER REFERENCES files(id),
name TEXT,
unique_id TEXT UNIQUE,
start_line INTEGER,
end_line INTEGER,
content TEXT,
lang TEXT
);
CREATE INDEX IF NOT EXISTS idx_graph_classes_file_id ON graph_classes(file_id);
CREATE INDEX IF NOT EXISTS idx_graph_classes_unique_id ON graph_classes(unique_id);
`);
db.exec(`
CREATE TABLE IF NOT EXISTS graph_edges (
id INTEGER PRIMARY KEY AUTOINCREMENT,
source_type TEXT NOT NULL,
source_unique_id TEXT NOT NULL,
target_type TEXT NOT NULL,
target_unique_id TEXT NOT NULL,
relation TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_graph_edges_source ON graph_edges(source_type, source_unique_id);
CREATE INDEX IF NOT EXISTS idx_graph_edges_target ON graph_edges(target_type, target_unique_id);
CREATE INDEX IF NOT EXISTS idx_graph_edges_relation ON graph_edges(relation);
`);
db.exec(`
CREATE TABLE IF NOT EXISTS graph_tags_master (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE NOT NULL
);
CREATE TABLE IF NOT EXISTS graph_entity_tags (
id INTEGER PRIMARY KEY AUTOINCREMENT,
entity_type TEXT NOT NULL,
entity_unique_id TEXT NOT NULL,
tag_id INTEGER NOT NULL REFERENCES graph_tags_master(id),
UNIQUE(entity_type, entity_unique_id, tag_id)
);
CREATE INDEX IF NOT EXISTS idx_graph_entity_tags_entity ON graph_entity_tags(entity_type, entity_unique_id);
CREATE INDEX IF NOT EXISTS idx_graph_entity_tags_tag ON graph_entity_tags(tag_id);
`);
db.exec(`
CREATE TABLE IF NOT EXISTS summaries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
path TEXT UNIQUE,
type TEXT NOT NULL CHECK (type IN ('folder','project')),
summary TEXT,
last_generated TEXT,
child_latest_modified TEXT
);
CREATE INDEX IF NOT EXISTS idx_summaries_type ON summaries(type);
CREATE INDEX IF NOT EXISTS idx_summaries_path ON summaries(path);
`);
console.log("✅ Graph schema initialized (files, functions, classes, edges, tags, summaries, FTS content_text)");
}