mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-11 12:03:31 +08:00
179 lines
4.6 KiB
JavaScript
179 lines
4.6 KiB
JavaScript
'use strict';
|
|
|
|
const INITIAL_SCHEMA_SQL = `
|
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
version INTEGER PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
applied_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
id TEXT PRIMARY KEY,
|
|
adapter_id TEXT NOT NULL,
|
|
harness TEXT NOT NULL,
|
|
state TEXT NOT NULL,
|
|
repo_root TEXT,
|
|
started_at TEXT,
|
|
ended_at TEXT,
|
|
snapshot TEXT NOT NULL CHECK (json_valid(snapshot))
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_sessions_state_started_at
|
|
ON sessions (state, started_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_sessions_started_at
|
|
ON sessions (started_at DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS skill_runs (
|
|
id TEXT PRIMARY KEY,
|
|
skill_id TEXT NOT NULL,
|
|
skill_version TEXT NOT NULL,
|
|
session_id TEXT NOT NULL,
|
|
task_description TEXT NOT NULL,
|
|
outcome TEXT NOT NULL,
|
|
failure_reason TEXT,
|
|
tokens_used INTEGER,
|
|
duration_ms INTEGER,
|
|
user_feedback TEXT,
|
|
created_at TEXT NOT NULL,
|
|
FOREIGN KEY (session_id) REFERENCES sessions (id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_skill_runs_session_id_created_at
|
|
ON skill_runs (session_id, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_skill_runs_created_at
|
|
ON skill_runs (created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_skill_runs_outcome_created_at
|
|
ON skill_runs (outcome, created_at DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS skill_versions (
|
|
skill_id TEXT NOT NULL,
|
|
version TEXT NOT NULL,
|
|
content_hash TEXT NOT NULL,
|
|
amendment_reason TEXT,
|
|
promoted_at TEXT,
|
|
rolled_back_at TEXT,
|
|
PRIMARY KEY (skill_id, version)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_skill_versions_promoted_at
|
|
ON skill_versions (promoted_at DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS decisions (
|
|
id TEXT PRIMARY KEY,
|
|
session_id TEXT NOT NULL,
|
|
title TEXT NOT NULL,
|
|
rationale TEXT NOT NULL,
|
|
alternatives TEXT NOT NULL CHECK (json_valid(alternatives)),
|
|
supersedes TEXT,
|
|
status TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
FOREIGN KEY (session_id) REFERENCES sessions (id) ON DELETE CASCADE,
|
|
FOREIGN KEY (supersedes) REFERENCES decisions (id) ON DELETE SET NULL
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_decisions_session_id_created_at
|
|
ON decisions (session_id, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_decisions_status_created_at
|
|
ON decisions (status, created_at DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS install_state (
|
|
target_id TEXT NOT NULL,
|
|
target_root TEXT NOT NULL,
|
|
profile TEXT,
|
|
modules TEXT NOT NULL CHECK (json_valid(modules)),
|
|
operations TEXT NOT NULL CHECK (json_valid(operations)),
|
|
installed_at TEXT NOT NULL,
|
|
source_version TEXT,
|
|
PRIMARY KEY (target_id, target_root)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_install_state_installed_at
|
|
ON install_state (installed_at DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS governance_events (
|
|
id TEXT PRIMARY KEY,
|
|
session_id TEXT,
|
|
event_type TEXT NOT NULL,
|
|
payload TEXT NOT NULL CHECK (json_valid(payload)),
|
|
resolved_at TEXT,
|
|
resolution TEXT,
|
|
created_at TEXT NOT NULL,
|
|
FOREIGN KEY (session_id) REFERENCES sessions (id) ON DELETE SET NULL
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_governance_events_resolved_at_created_at
|
|
ON governance_events (resolved_at, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_governance_events_session_id_created_at
|
|
ON governance_events (session_id, created_at DESC);
|
|
`;
|
|
|
|
const MIGRATIONS = [
|
|
{
|
|
version: 1,
|
|
name: '001_initial_state_store',
|
|
sql: INITIAL_SCHEMA_SQL,
|
|
},
|
|
];
|
|
|
|
function ensureMigrationTable(db) {
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
version INTEGER PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
applied_at TEXT NOT NULL
|
|
);
|
|
`);
|
|
}
|
|
|
|
function getAppliedMigrations(db) {
|
|
ensureMigrationTable(db);
|
|
return db
|
|
.prepare(`
|
|
SELECT version, name, applied_at
|
|
FROM schema_migrations
|
|
ORDER BY version ASC
|
|
`)
|
|
.all()
|
|
.map(row => ({
|
|
version: row.version,
|
|
name: row.name,
|
|
appliedAt: row.applied_at,
|
|
}));
|
|
}
|
|
|
|
function applyMigrations(db) {
|
|
ensureMigrationTable(db);
|
|
|
|
const appliedVersions = new Set(
|
|
db.prepare('SELECT version FROM schema_migrations').all().map(row => row.version)
|
|
);
|
|
const insertMigration = db.prepare(`
|
|
INSERT INTO schema_migrations (version, name, applied_at)
|
|
VALUES (@version, @name, @applied_at)
|
|
`);
|
|
|
|
const applyPending = db.transaction(() => {
|
|
for (const migration of MIGRATIONS) {
|
|
if (appliedVersions.has(migration.version)) {
|
|
continue;
|
|
}
|
|
|
|
db.exec(migration.sql);
|
|
insertMigration.run({
|
|
version: migration.version,
|
|
name: migration.name,
|
|
applied_at: new Date().toISOString(),
|
|
});
|
|
}
|
|
});
|
|
|
|
applyPending();
|
|
return getAppliedMigrations(db);
|
|
}
|
|
|
|
module.exports = {
|
|
MIGRATIONS,
|
|
applyMigrations,
|
|
getAppliedMigrations,
|
|
};
|