db.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.openDb = openDb;
exports.getDb = getDb;
exports.upsertProject = upsertProject;
exports.getProjectByRoot = getProjectByRoot;
exports.insertMemoryNote = insertMemoryNote;
exports.getMemoryNotes = getMemoryNotes;
exports.deleteMemoryNote = deleteMemoryNote;
exports.listProjects = listProjects;
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
const path_1 = require("path");
const os_1 = require("os");
const fs_1 = require("fs");
function openDb(dataPath) {
const raw = dataPath.trim() || (0, path_1.join)((0, os_1.homedir)(), "codebase-memory");
const dir = raw.startsWith("~/") ? (0, path_1.join)((0, os_1.homedir)(), raw.slice(2)) : raw;
(0, fs_1.mkdirSync)(dir, { recursive: true });
const db = new better_sqlite3_1.default((0, path_1.join)(dir, "codebase.db"));
db.pragma("journal_mode = WAL");
db.exec(`
CREATE TABLE IF NOT EXISTS projects (
id INTEGER PRIMARY KEY AUTOINCREMENT,
root TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
framework TEXT DEFAULT '',
language TEXT DEFAULT '',
entrypoints TEXT DEFAULT '[]',
conventions TEXT DEFAULT '[]',
createdAt TEXT NOT NULL,
updatedAt TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS memory_notes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
projectId INTEGER NOT NULL REFERENCES projects(id),
category TEXT NOT NULL,
content TEXT NOT NULL,
createdAt TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_projects_root ON projects(root);
CREATE INDEX IF NOT EXISTS idx_memory_projectId ON memory_notes(projectId);
CREATE INDEX IF NOT EXISTS idx_memory_category ON memory_notes(category);
`);
return db;
}
const _dbCache = new Map();
function getDb(dataPath) {
let db = _dbCache.get(dataPath);
if (!db) {
db = openDb(dataPath);
_dbCache.set(dataPath, db);
}
return db;
}
function upsertProject(db, root, name, framework, language, entrypoints, conventions) {
const now = new Date().toISOString();
const existing = db.prepare("SELECT id FROM projects WHERE root = ?").get(root);
if (existing) {
db.prepare(`UPDATE projects SET name=?, framework=?, language=?, entrypoints=?, conventions=?, updatedAt=? WHERE id=?`)
.run(name, framework, language, JSON.stringify(entrypoints), JSON.stringify(conventions), now, existing.id);
return existing.id;
}
const r = db.prepare("INSERT INTO projects (root, name, framework, language, entrypoints, conventions, createdAt, updatedAt) VALUES (?,?,?,?,?,?,?,?)").run(root, name, framework, language, JSON.stringify(entrypoints), JSON.stringify(conventions), now, now);
return r.lastInsertRowid;
}
function getProjectByRoot(db, root) {
return db.prepare("SELECT * FROM projects WHERE root = ?").get(root);
}
function insertMemoryNote(db, projectId, category, content) {
const r = db.prepare("INSERT INTO memory_notes (projectId, category, content, createdAt) VALUES (?, ?, ?, ?)").run(projectId, category, content, new Date().toISOString());
return r.lastInsertRowid;
}
function getMemoryNotes(db, projectId, category) {
if (category) {
return db.prepare("SELECT * FROM memory_notes WHERE projectId = ? AND category = ? ORDER BY createdAt DESC")
.all(projectId, category);
}
return db.prepare("SELECT * FROM memory_notes WHERE projectId = ? ORDER BY category, createdAt DESC")
.all(projectId);
}
function deleteMemoryNote(db, id) {
const r = db.prepare("DELETE FROM memory_notes WHERE id = ?").run(id);
return r.changes > 0;
}
function listProjects(db) {
return db.prepare("SELECT id, root, name, framework, language, updatedAt FROM projects ORDER BY updatedAt DESC")
.all();
}