@stackmemoryai/stackmemory
Version:
Lossless, project-scoped memory for AI coding tools. Durable context across sessions with 56 MCP tools, FTS5 search, conductor orchestrator, loop/watch monitoring, snapshot capture, pre-flight overlap checks, Claude/Codex/OpenCode wrappers, Linear sync, a
100 lines (99 loc) • 2.92 kB
JavaScript
import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
const SCHEMA = `
CREATE TABLE IF NOT EXISTS rules (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
description TEXT NOT NULL DEFAULT '',
trigger_type TEXT NOT NULL DEFAULT 'on-demand',
severity TEXT NOT NULL DEFAULT 'warn',
scope TEXT NOT NULL DEFAULT '**/*',
enabled INTEGER NOT NULL DEFAULT 1,
builtin INTEGER NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
)`;
class RuleStore {
constructor(db) {
this.db = db;
this.db.exec(SCHEMA);
}
upsert(rule) {
const now = Date.now();
this.db.prepare(
`INSERT INTO rules (id, name, description, trigger_type, severity, scope, enabled, builtin, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE SET
name = excluded.name,
description = excluded.description,
trigger_type = excluded.trigger_type,
severity = excluded.severity,
scope = excluded.scope,
enabled = excluded.enabled,
builtin = excluded.builtin,
updated_at = excluded.updated_at`
).run(
rule.id,
rule.name,
rule.description,
rule.trigger_type,
rule.severity,
rule.scope,
rule.enabled,
rule.builtin,
now,
now
);
}
getAll() {
return this.db.prepare("SELECT * FROM rules ORDER BY id").all();
}
getEnabled() {
return this.db.prepare("SELECT * FROM rules WHERE enabled = 1 ORDER BY id").all();
}
getByTrigger(trigger) {
return this.db.prepare(
"SELECT * FROM rules WHERE enabled = 1 AND trigger_type = ? ORDER BY id"
).all(trigger);
}
getById(id) {
return this.db.prepare("SELECT * FROM rules WHERE id = ?").get(id);
}
setEnabled(id, enabled) {
const result = this.db.prepare("UPDATE rules SET enabled = ?, updated_at = ? WHERE id = ?").run(enabled ? 1 : 0, Date.now(), id);
return result.changes > 0;
}
delete(id) {
const result = this.db.prepare("DELETE FROM rules WHERE id = ?").run(id);
return result.changes > 0;
}
seedBuiltins(rules) {
const now = Date.now();
const stmt = this.db.prepare(
`INSERT OR IGNORE INTO rules (id, name, description, trigger_type, severity, scope, enabled, builtin, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
);
const tx = this.db.transaction(() => {
for (const rule of rules) {
stmt.run(
rule.id,
rule.name,
rule.description,
rule.trigger_type,
rule.severity,
rule.scope,
rule.enabled,
rule.builtin,
now,
now
);
}
});
tx();
}
}
export {
RuleStore
};