scai
Version:
> **AI-powered CLI for local code analysis, commit message suggestions, and natural-language queries.** > **100% local • No token cost • Private by design • GDPR-friendly** — made in Denmark/EU with ❤️.
149 lines (134 loc) • 5.13 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'
);
`);
// --- Tasks table for collaborative workflows ---
db.exec(`
CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
-- identity & lifecycle
status TEXT NOT NULL DEFAULT 'active', -- active | paused | completed | abandoned
-- human-facing
initial_query TEXT NOT NULL, -- raw user query
summary TEXT, -- evolving short description
-- resolved collaboration state
agreed_intent TEXT,
constraints_json TEXT, -- JSON array of constraints
file_scope_json TEXT, -- JSON array of file paths
-- bookkeeping
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
`);
// --- 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)");
}