mirror of
https://github.com/Heretek-AI/openclaw.git
synced 2026-07-19 20:43:32 -04:00
a9ae1a6778
Matrix Protocol: - docker-compose.matrix.yml: Dendrite homeserver + PostgreSQL + Nginx TLS - src/channels/plugins/matrix-channel.ts: OpenClaw plugin implementation - docs/matrix-triad-setup.md: Setup guide with auth scheme (@tm1-4:triad.local) MCP Server Integration: - docs/mcp-triad-integration.md: SearXNG, Playwright, GitHub MCP configs - docs/mcp-curiosity-mapping.md: Gap-to-capability mapping Node Sync Architecture: - src/services/node-sync-service.ts: WebSocket peer sync + presence detection - src/services/node-sync-service.test.ts: Unit tests - docs/node-sync-architecture.md: Architecture docs Triad Resilience: - scripts/triad-corruption-check.mjs: SQLite + log + config + git integrity - docs/triad-resilience.md: Recovery procedures - .secure/deployment-logs/README.md: Schema v2 - skills/triad-heartbeat/SKILL.md: Corruption check integration NPM Publish Workflow: - scripts/npm-publish.mjs: version, changelog, validate, publish, rollback - .github/workflows/npm-publish.yml: GitHub Actions with provenance - docs/npm-publish-guide.md: Complete documentation All deliverables tested in Docker before production.
129 lines
3.7 KiB
JavaScript
Executable File
129 lines
3.7 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
// Triad Ledger Restore — Imports JSON backup to SQLite
|
|
// Usage: node scripts/restore-ledger.js <backup-file.json>
|
|
|
|
import fs from "fs";
|
|
import path from "path";
|
|
import { fileURLToPath } from "url";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const workspaceRoot = path.join(__dirname, "..");
|
|
const auraPath = path.join(workspaceRoot, ".aura");
|
|
const dbPath = path.join(auraPath, "consensus.db");
|
|
|
|
const backupFile = process.argv[2];
|
|
|
|
if (!backupFile) {
|
|
console.log("❌ Usage: node scripts/restore-ledger.js <backup-file.json>");
|
|
console.log("Example: node scripts/restore-ledger.js .ledger-backups/latest.json");
|
|
process.exit(1);
|
|
}
|
|
|
|
if (!fs.existsSync(backupFile)) {
|
|
console.log(`❌ Backup file not found: ${backupFile}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log("🦞 Triad Ledger Restore — Starting...\n");
|
|
|
|
// Check if better-sqlite3 is available
|
|
let Database;
|
|
try {
|
|
Database = (await import("better-sqlite3")).default;
|
|
} catch {
|
|
console.log("❌ better-sqlite3 not installed. Run: npm install better-sqlite3");
|
|
process.exit(1);
|
|
}
|
|
|
|
// Read backup
|
|
const backup = JSON.parse(fs.readFileSync(backupFile, "utf8"));
|
|
console.log(`✅ Loaded backup: ${backup.timestamp}`);
|
|
|
|
// Ensure .aura exists
|
|
if (!fs.existsSync(auraPath)) {
|
|
fs.mkdirSync(auraPath, { recursive: true });
|
|
}
|
|
|
|
// Remove existing DB (fresh restore)
|
|
if (fs.existsSync(dbPath)) {
|
|
fs.unlinkSync(dbPath);
|
|
console.log("⚠️ Removed existing ledger DB (fresh restore)");
|
|
}
|
|
|
|
// Create fresh DB
|
|
const db = new Database(dbPath);
|
|
console.log(`✅ Created: ${dbPath}`);
|
|
|
|
// Run init script to create schema
|
|
const initScript = path.join(__dirname, "init-triad-ledger.js");
|
|
if (fs.existsSync(initScript)) {
|
|
console.log("⚠️ Running init script to create schema...");
|
|
// Skip init script execution, just create schema manually
|
|
}
|
|
|
|
// Create schema (from init-triad-ledger.js schema.sql)
|
|
const schemaPath = path.join(workspaceRoot, "skills", "triad-heartbeat", "schema.sql");
|
|
if (fs.existsSync(schemaPath)) {
|
|
const schema = fs.readFileSync(schemaPath, "utf8");
|
|
db.exec(schema);
|
|
console.log("✅ Schema applied");
|
|
} else {
|
|
console.log("❌ schema.sql not found. Creating minimal schema...");
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS consensus_votes (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
timestamp TEXT,
|
|
proposal TEXT,
|
|
result TEXT,
|
|
signers TEXT,
|
|
git_hash TEXT,
|
|
processed INTEGER DEFAULT 0,
|
|
created_at TEXT DEFAULT (datetime('now'))
|
|
);
|
|
CREATE TABLE IF NOT EXISTS triad_state (
|
|
node_id TEXT PRIMARY KEY,
|
|
last_heartbeat TEXT,
|
|
git_hash TEXT,
|
|
ledger_hash TEXT,
|
|
sync_status TEXT,
|
|
updated_at TEXT DEFAULT (datetime('now'))
|
|
);
|
|
CREATE TABLE IF NOT EXISTS triad_tasks (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
task TEXT,
|
|
status TEXT DEFAULT 'pending',
|
|
assigned_to TEXT,
|
|
created_at TEXT DEFAULT (datetime('now')),
|
|
completed_at TEXT
|
|
);
|
|
`);
|
|
}
|
|
|
|
// Restore data
|
|
let total = 0;
|
|
for (const [table, rows] of Object.entries(backup.tables)) {
|
|
if (!rows || rows.length === 0) {
|
|
continue;
|
|
}
|
|
|
|
const columns = Object.keys(rows[0]);
|
|
const placeholders = columns.map(() => "?").join(", ");
|
|
const insertSQL = `INSERT OR REPLACE INTO ${table} (${columns.join(", ")}) VALUES (${placeholders})`;
|
|
|
|
const stmt = db.prepare(insertSQL);
|
|
|
|
db.exec("BEGIN");
|
|
rows.forEach((row) => {
|
|
stmt.run(...columns.map((col) => row[col]));
|
|
});
|
|
db.exec("COMMIT");
|
|
|
|
total += rows.length;
|
|
console.log(`✅ Restored ${rows.length} rows to ${table}`);
|
|
}
|
|
|
|
db.close();
|
|
|
|
console.log(`\n✅ Restore complete: ${total} total records`);
|
|
console.log(`🦞 Ledger ready. Run: node scripts/init-triad-ledger.js to verify.`);
|