mirror of
https://github.com/samvallad33/vestige.git
synced 2026-04-25 00:36:22 +02:00
Replace all engram references with vestige
Updated TypeScript packages, npm package, and config files. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
d9b762030e
commit
449d60754a
27 changed files with 277 additions and 277 deletions
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import Database from 'better-sqlite3';
|
||||
import { initializeDatabase, EngramDatabase, analyzeSentimentIntensity } from '../../core/database.js';
|
||||
import { initializeDatabase, VestigeDatabase, analyzeSentimentIntensity } from '../../core/database.js';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
|
|
@ -26,18 +26,18 @@ import os from 'os';
|
|||
* Create a test database in a temporary location
|
||||
*/
|
||||
function createTestDatabase(): Database.Database {
|
||||
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'engram-test-'));
|
||||
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vestige-test-'));
|
||||
const dbPath = path.join(tempDir, 'test.db');
|
||||
return initializeDatabase(dbPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test EngramDatabase instance
|
||||
* Create a test VestigeDatabase instance
|
||||
*/
|
||||
function createTestEngramDatabase(): { db: EngramDatabase; path: string } {
|
||||
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'engram-test-'));
|
||||
function createTestVestigeDatabase(): { db: VestigeDatabase; path: string } {
|
||||
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vestige-test-'));
|
||||
const dbPath = path.join(tempDir, 'test.db');
|
||||
const db = new EngramDatabase(dbPath);
|
||||
const db = new VestigeDatabase(dbPath);
|
||||
return { db, path: dbPath };
|
||||
}
|
||||
|
||||
|
|
@ -53,9 +53,9 @@ function cleanupTestDatabase(db: Database.Database): void {
|
|||
}
|
||||
|
||||
/**
|
||||
* Clean up EngramDatabase and its files
|
||||
* Clean up VestigeDatabase and its files
|
||||
*/
|
||||
function cleanupEngramDatabase(db: EngramDatabase, dbPath: string): void {
|
||||
function cleanupVestigeDatabase(db: VestigeDatabase, dbPath: string): void {
|
||||
try {
|
||||
db.close();
|
||||
// Clean up temp directory
|
||||
|
|
@ -171,14 +171,14 @@ function backdateNode(db: Database.Database, id: string, daysAgo: number): void
|
|||
|
||||
describe('Dual-Strength Memory Model', () => {
|
||||
describe('Storage Strength', () => {
|
||||
let testDb: { db: EngramDatabase; path: string };
|
||||
let testDb: { db: VestigeDatabase; path: string };
|
||||
|
||||
beforeEach(() => {
|
||||
testDb = createTestEngramDatabase();
|
||||
testDb = createTestVestigeDatabase();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanupEngramDatabase(testDb.db, testDb.path);
|
||||
cleanupVestigeDatabase(testDb.db, testDb.path);
|
||||
});
|
||||
|
||||
it('should start at 1.0 for new nodes', () => {
|
||||
|
|
@ -364,14 +364,14 @@ describe('Dual-Strength Memory Model', () => {
|
|||
// ============================================================================
|
||||
|
||||
describe('Retrieval Strength', () => {
|
||||
let testDb: { db: EngramDatabase; path: string };
|
||||
let testDb: { db: VestigeDatabase; path: string };
|
||||
|
||||
beforeEach(() => {
|
||||
testDb = createTestEngramDatabase();
|
||||
testDb = createTestVestigeDatabase();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanupEngramDatabase(testDb.db, testDb.path);
|
||||
cleanupVestigeDatabase(testDb.db, testDb.path);
|
||||
});
|
||||
|
||||
it('should start at 1.0 for new nodes', () => {
|
||||
|
|
@ -746,14 +746,14 @@ describe('Dual-Strength Memory Model', () => {
|
|||
// ============================================================================
|
||||
|
||||
describe('Edge Cases', () => {
|
||||
let testDb: { db: EngramDatabase; path: string };
|
||||
let testDb: { db: VestigeDatabase; path: string };
|
||||
|
||||
beforeEach(() => {
|
||||
testDb = createTestEngramDatabase();
|
||||
testDb = createTestVestigeDatabase();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanupEngramDatabase(testDb.db, testDb.path);
|
||||
cleanupVestigeDatabase(testDb.db, testDb.path);
|
||||
});
|
||||
|
||||
it('should handle new node with no accesses correctly', () => {
|
||||
|
|
@ -959,14 +959,14 @@ describe('Dual-Strength Memory Model', () => {
|
|||
// ============================================================================
|
||||
|
||||
describe('Desirable Difficulty Principle', () => {
|
||||
let testDb: { db: EngramDatabase; path: string };
|
||||
let testDb: { db: VestigeDatabase; path: string };
|
||||
|
||||
beforeEach(() => {
|
||||
testDb = createTestEngramDatabase();
|
||||
testDb = createTestVestigeDatabase();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanupEngramDatabase(testDb.db, testDb.path);
|
||||
cleanupVestigeDatabase(testDb.db, testDb.path);
|
||||
});
|
||||
|
||||
it('should reward difficult recalls with higher storage increase', () => {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {
|
|||
generateTestId,
|
||||
} from './setup.js';
|
||||
|
||||
describe('EngramDatabase', () => {
|
||||
describe('VestigeDatabase', () => {
|
||||
let db: Database.Database;
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
@ -36,7 +36,7 @@ describe('EngramDatabase', () => {
|
|||
expect(tableNames).toContain('graph_edges');
|
||||
expect(tableNames).toContain('sources');
|
||||
expect(tableNames).toContain('embeddings');
|
||||
expect(tableNames).toContain('engram_metadata');
|
||||
expect(tableNames).toContain('vestige_metadata');
|
||||
});
|
||||
|
||||
it('should create required indexes', () => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Integration tests for all 14 MCP tools in Engram MCP
|
||||
* Integration tests for all 14 MCP tools in Vestige MCP
|
||||
*
|
||||
* Tests cover the complete tool functionality including:
|
||||
* - Input validation
|
||||
|
|
@ -9,14 +9,14 @@
|
|||
*/
|
||||
|
||||
import { describe, it, expect, beforeAll, afterAll, beforeEach } from '@rstest/core';
|
||||
import { EngramDatabase } from '../../core/database.js';
|
||||
import { VestigeDatabase } from '../../core/database.js';
|
||||
import type { KnowledgeNode, PersonNode } from '../../core/types.js';
|
||||
|
||||
/**
|
||||
* Creates an in-memory test database instance
|
||||
*/
|
||||
function createTestDatabase(): EngramDatabase {
|
||||
return new EngramDatabase(':memory:');
|
||||
function createTestDatabase(): VestigeDatabase {
|
||||
return new VestigeDatabase(':memory:');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -36,7 +36,7 @@ function mockTimestamp(daysAgo: number = 0): Date {
|
|||
* Creates mock MCP tool handlers that simulate the actual tool behavior
|
||||
* These handlers call the same database methods as the real MCP server
|
||||
*/
|
||||
function createMCPToolHandler(db: EngramDatabase) {
|
||||
function createMCPToolHandler(db: VestigeDatabase) {
|
||||
return {
|
||||
// --- Tool 1: ingest ---
|
||||
async ingest(args: {
|
||||
|
|
@ -429,7 +429,7 @@ function createMCPToolHandler(db: EngramDatabase) {
|
|||
// ============================================================================
|
||||
|
||||
describe('MCP Tools Integration', () => {
|
||||
let db: EngramDatabase;
|
||||
let db: VestigeDatabase;
|
||||
let tools: ReturnType<typeof createMCPToolHandler>;
|
||||
|
||||
beforeAll(() => {
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ export function createTestDatabase(): Database.Database {
|
|||
|
||||
// Metadata table
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS engram_metadata (
|
||||
CREATE TABLE IF NOT EXISTS vestige_metadata (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Engram CLI - Management commands for the Memory Palace
|
||||
* Vestige CLI - Management commands for the Memory Palace
|
||||
*
|
||||
* Usage:
|
||||
* engram stats - Show knowledge base statistics and health
|
||||
* engram health - Detailed health check
|
||||
* engram review - Start a review session
|
||||
* engram people - List people in your network
|
||||
* engram backup - Create a backup
|
||||
* engram backups - List available backups
|
||||
* engram restore <path> - Restore from a backup
|
||||
* engram optimize - Optimize the database
|
||||
* engram decay - Apply memory decay
|
||||
* engram eat <url|path> - Ingest documentation/content (Man Page Absorber)
|
||||
* vestige stats - Show knowledge base statistics and health
|
||||
* vestige health - Detailed health check
|
||||
* vestige review - Start a review session
|
||||
* vestige people - List people in your network
|
||||
* vestige backup - Create a backup
|
||||
* vestige backups - List available backups
|
||||
* vestige restore <path> - Restore from a backup
|
||||
* vestige optimize - Optimize the database
|
||||
* vestige decay - Apply memory decay
|
||||
* vestige eat <url|path> - Ingest documentation/content (Man Page Absorber)
|
||||
*/
|
||||
|
||||
import { EngramDatabase, EngramDatabaseError } from './core/database.js';
|
||||
import { VestigeDatabase, VestigeDatabaseError } from './core/database.js';
|
||||
import {
|
||||
captureContext,
|
||||
formatContextForInjection,
|
||||
|
|
@ -297,7 +297,7 @@ function splitLargeSection(content: string, section: string, startIndex: number,
|
|||
/**
|
||||
* Ingest content from URL or file path
|
||||
*/
|
||||
async function eatContent(source: string, db: EngramDatabase): Promise<void> {
|
||||
async function eatContent(source: string, db: VestigeDatabase): Promise<void> {
|
||||
console.log(`\n Fetching content from: ${source}`);
|
||||
|
||||
// Determine if URL or file
|
||||
|
|
@ -383,14 +383,14 @@ async function eatContent(source: string, db: EngramDatabase): Promise<void> {
|
|||
|
||||
console.log(` Created ${edgesCreated} sequential connections`);
|
||||
console.log(`\n Successfully ingested ${chunks.length} chunks from ${sourceName}`);
|
||||
console.log(` Use 'engram recall' or ask Claude to find this knowledge.\n`);
|
||||
console.log(` Use 'vestige recall' or ask Claude to find this knowledge.\n`);
|
||||
}
|
||||
|
||||
const command = process.argv[2];
|
||||
const args = process.argv.slice(3);
|
||||
|
||||
async function main() {
|
||||
const db = new EngramDatabase();
|
||||
const db = new VestigeDatabase();
|
||||
|
||||
try {
|
||||
switch (command) {
|
||||
|
|
@ -503,7 +503,7 @@ async function main() {
|
|||
const health = db.checkHealth();
|
||||
const size = db.getDatabaseSize();
|
||||
|
||||
console.log('\n Engram Health Check\n');
|
||||
console.log('\n Vestige Health Check\n');
|
||||
console.log(` Status: ${getStatusEmoji(health.status)} ${health.status.toUpperCase()}`);
|
||||
console.log(` Database Path: ${health.dbPath}`);
|
||||
console.log(` Database Size: ${size.formatted}`);
|
||||
|
|
@ -594,7 +594,7 @@ async function main() {
|
|||
case 'backups': {
|
||||
const backups = db.listBackups();
|
||||
if (backups.length === 0) {
|
||||
console.log('\n No backups found. Create one with: engram backup\n');
|
||||
console.log('\n No backups found. Create one with: vestige backup\n');
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -611,8 +611,8 @@ async function main() {
|
|||
case 'restore': {
|
||||
const backupPath = args[0];
|
||||
if (!backupPath) {
|
||||
console.log('\n Usage: engram restore <backup-path>');
|
||||
console.log(' Use "engram backups" to see available backups.\n');
|
||||
console.log('\n Usage: vestige restore <backup-path>');
|
||||
console.log(' Use "vestige backups" to see available backups.\n');
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -639,7 +639,7 @@ async function main() {
|
|||
db.restore(safePath);
|
||||
console.log(' Restore completed successfully!\n');
|
||||
} catch (error) {
|
||||
if (error instanceof EngramDatabaseError) {
|
||||
if (error instanceof VestigeDatabaseError) {
|
||||
console.error(` Error: ${error.message} (${error.code})\n`);
|
||||
} else {
|
||||
console.error(` Error: ${error instanceof Error ? error.message : 'Unknown error'}\n`);
|
||||
|
|
@ -753,7 +753,7 @@ async function main() {
|
|||
case 'search': {
|
||||
const query = args.slice(1).join(' ');
|
||||
if (!query) {
|
||||
console.log('\n Usage: engram embeddings search "<query>"\n');
|
||||
console.log('\n Usage: vestige embeddings search "<query>"\n');
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -800,9 +800,9 @@ async function main() {
|
|||
|
||||
default:
|
||||
console.log(`
|
||||
Engram Embeddings - Semantic Understanding
|
||||
Vestige Embeddings - Semantic Understanding
|
||||
|
||||
Usage: engram embeddings <command>
|
||||
Usage: vestige embeddings <command>
|
||||
|
||||
Commands:
|
||||
status Check embedding service availability
|
||||
|
|
@ -810,10 +810,10 @@ async function main() {
|
|||
search "<query>" Semantic similarity search
|
||||
|
||||
Examples:
|
||||
engram embeddings status
|
||||
engram embeddings generate
|
||||
engram embeddings generate abc12345
|
||||
engram embeddings search "authentication flow"
|
||||
vestige embeddings status
|
||||
vestige embeddings generate
|
||||
vestige embeddings generate abc12345
|
||||
vestige embeddings search "authentication flow"
|
||||
`);
|
||||
}
|
||||
break;
|
||||
|
|
@ -821,11 +821,11 @@ async function main() {
|
|||
|
||||
case 'config': {
|
||||
const configCmd = args[0];
|
||||
const configPath = path.join(os.homedir(), '.engram', 'config.json');
|
||||
const configPath = path.join(os.homedir(), '.vestige', 'config.json');
|
||||
|
||||
switch (configCmd) {
|
||||
case 'show': {
|
||||
console.log('\n Engram Configuration\n');
|
||||
console.log('\n Vestige Configuration\n');
|
||||
const config = getConfig();
|
||||
console.log(JSON.stringify(config, null, 2));
|
||||
console.log(`\n Config file: ${configPath}\n`);
|
||||
|
|
@ -837,11 +837,11 @@ async function main() {
|
|||
const value = args.slice(2).join(' ');
|
||||
|
||||
if (!key || !value) {
|
||||
console.log('\n Usage: engram config set <section.key> <value>');
|
||||
console.log('\n Usage: vestige config set <section.key> <value>');
|
||||
console.log('\n Examples:');
|
||||
console.log(' engram config set logging.level debug');
|
||||
console.log(' engram config set fsrs.desiredRetention 0.85');
|
||||
console.log(' engram config set rem.enabled false\n');
|
||||
console.log(' vestige config set logging.level debug');
|
||||
console.log(' vestige config set fsrs.desiredRetention 0.85');
|
||||
console.log(' vestige config set rem.enabled false\n');
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -916,9 +916,9 @@ async function main() {
|
|||
|
||||
default:
|
||||
console.log(`
|
||||
Engram Configuration Management
|
||||
Vestige Configuration Management
|
||||
|
||||
Usage: engram config <command>
|
||||
Usage: vestige config <command>
|
||||
|
||||
Commands:
|
||||
show Display current configuration
|
||||
|
|
@ -926,10 +926,10 @@ async function main() {
|
|||
reset Reset to default configuration
|
||||
|
||||
Examples:
|
||||
engram config show
|
||||
engram config set logging.level debug
|
||||
engram config set fsrs.desiredRetention 0.85
|
||||
engram config reset
|
||||
vestige config show
|
||||
vestige config set logging.level debug
|
||||
vestige config set fsrs.desiredRetention 0.85
|
||||
vestige config reset
|
||||
|
||||
Configuration Sections:
|
||||
database - Database paths and settings
|
||||
|
|
@ -947,7 +947,7 @@ async function main() {
|
|||
}
|
||||
|
||||
case 'test': {
|
||||
console.log('\n Engram Self-Test Suite\n');
|
||||
console.log('\n Vestige Self-Test Suite\n');
|
||||
console.log(' Running diagnostic tests...\n');
|
||||
|
||||
let allPassed = true;
|
||||
|
|
@ -1026,11 +1026,11 @@ async function main() {
|
|||
case 'ingest': {
|
||||
const content = args.join(' ');
|
||||
if (!content) {
|
||||
console.log('\n Usage: engram ingest "<content>"');
|
||||
console.log('\n Store knowledge directly into Engram.');
|
||||
console.log('\n Usage: vestige ingest "<content>"');
|
||||
console.log('\n Store knowledge directly into Vestige.');
|
||||
console.log('\n Examples:');
|
||||
console.log(' engram ingest "API rate limit is 100 req/min"');
|
||||
console.log(' engram ingest "Meeting with John: discussed Q4 roadmap"\n');
|
||||
console.log(' vestige ingest "API rate limit is 100 req/min"');
|
||||
console.log(' vestige ingest "Meeting with John: discussed Q4 roadmap"\n');
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1071,11 +1071,11 @@ async function main() {
|
|||
case 'recall': {
|
||||
const query = args.join(' ');
|
||||
if (!query) {
|
||||
console.log('\n Usage: engram recall "<query>"');
|
||||
console.log('\n Usage: vestige recall "<query>"');
|
||||
console.log('\n Search your memories.');
|
||||
console.log('\n Examples:');
|
||||
console.log(' engram recall "rate limit"');
|
||||
console.log(' engram recall "meeting John"\n');
|
||||
console.log(' vestige recall "rate limit"');
|
||||
console.log(' vestige recall "meeting John"\n');
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1107,11 +1107,11 @@ async function main() {
|
|||
case 'eat': {
|
||||
const source = args[0];
|
||||
if (!source) {
|
||||
console.log('\n Usage: engram eat <url|path>');
|
||||
console.log('\n Usage: vestige eat <url|path>');
|
||||
console.log('\n Examples:');
|
||||
console.log(' engram eat https://docs.rs/tauri/latest/');
|
||||
console.log(' engram eat ./README.md');
|
||||
console.log(' engram eat ~/Documents/notes.txt');
|
||||
console.log(' vestige eat https://docs.rs/tauri/latest/');
|
||||
console.log(' vestige eat ./README.md');
|
||||
console.log(' vestige eat ~/Documents/notes.txt');
|
||||
console.log('\n The Man Page Absorber chunks content intelligently and');
|
||||
console.log(' creates interconnected knowledge nodes for retrieval.\n');
|
||||
break;
|
||||
|
|
@ -1246,11 +1246,11 @@ async function main() {
|
|||
case 'problem': {
|
||||
const description = args.join(' ');
|
||||
if (!description) {
|
||||
console.log('\n Usage: engram problem <description>');
|
||||
console.log('\n Usage: vestige problem <description>');
|
||||
console.log('\n Log an unsolved problem for your Shadow to work on.\n');
|
||||
console.log(' Examples:');
|
||||
console.log(' engram problem "How to implement efficient graph traversal"');
|
||||
console.log(' engram problem "Why is the memory leak happening in the worker"');
|
||||
console.log(' vestige problem "How to implement efficient graph traversal"');
|
||||
console.log(' vestige problem "Why is the memory leak happening in the worker"');
|
||||
console.log('\n The Shadow Self will periodically revisit these problems');
|
||||
console.log(' when new knowledge might provide insights.\n');
|
||||
break;
|
||||
|
|
@ -1285,7 +1285,7 @@ async function main() {
|
|||
|
||||
if (problems.length === 0) {
|
||||
console.log(' No open problems. Your mind is at peace.\n');
|
||||
console.log(' Log a problem with: engram problem "<description>"\n');
|
||||
console.log(' Log a problem with: vestige problem "<description>"\n');
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1313,11 +1313,11 @@ async function main() {
|
|||
const solution = args.slice(1).join(' ');
|
||||
|
||||
if (!problemId) {
|
||||
console.log('\n Usage: engram solve <problem-id> <solution>');
|
||||
console.log('\n Usage: vestige solve <problem-id> <solution>');
|
||||
console.log('\n Mark a problem as solved with the solution.\n');
|
||||
console.log(' Example:');
|
||||
console.log(' engram solve abc123 "Used memoization to optimize the traversal"');
|
||||
console.log('\n Use "engram problems" to see problem IDs.\n');
|
||||
console.log(' vestige solve abc123 "Used memoization to optimize the traversal"');
|
||||
console.log('\n Use "vestige problems" to see problem IDs.\n');
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1329,7 +1329,7 @@ async function main() {
|
|||
|
||||
if (!match) {
|
||||
console.log(`\n Problem not found: ${problemId}`);
|
||||
console.log(' Use "engram problems" to see open problems.\n');
|
||||
console.log(' Use "vestige problems" to see open problems.\n');
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1383,9 +1383,9 @@ async function main() {
|
|||
case 'help':
|
||||
default:
|
||||
console.log(`
|
||||
Engram CLI - Git Blame for AI Thoughts
|
||||
Vestige CLI - Git Blame for AI Thoughts
|
||||
|
||||
Usage: engram <command> [options]
|
||||
Usage: vestige <command> [options]
|
||||
|
||||
Core Commands:
|
||||
ingest <content> Store knowledge directly
|
||||
|
|
@ -1429,14 +1429,14 @@ async function main() {
|
|||
people List people in your network
|
||||
|
||||
Examples:
|
||||
engram ingest "API rate limit is 100 req/min"
|
||||
engram recall "rate limit"
|
||||
engram stats detailed
|
||||
engram embeddings search "authentication"
|
||||
engram config set logging.level debug
|
||||
engram eat https://docs.example.com/api
|
||||
vestige ingest "API rate limit is 100 req/min"
|
||||
vestige recall "rate limit"
|
||||
vestige stats detailed
|
||||
vestige embeddings search "authentication"
|
||||
vestige config set logging.level debug
|
||||
vestige eat https://docs.example.com/api
|
||||
|
||||
The Engram MCP server runs automatically when connected to Claude.
|
||||
The Vestige MCP server runs automatically when connected to Claude.
|
||||
Your brain gets smarter while you sleep.
|
||||
`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
/**
|
||||
* Configuration Management for Engram MCP
|
||||
* Configuration Management for Vestige MCP
|
||||
*
|
||||
* Provides centralized configuration with:
|
||||
* - Zod schema validation
|
||||
* - File-based configuration (~/.engram/config.json)
|
||||
* - File-based configuration (~/.vestige/config.json)
|
||||
* - Environment variable overrides
|
||||
* - Type-safe accessors for all config sections
|
||||
*
|
||||
|
|
@ -27,9 +27,9 @@ import fs from 'fs';
|
|||
*/
|
||||
const DatabaseConfigSchema = z.object({
|
||||
/** Path to the SQLite database file */
|
||||
path: z.string().default(path.join(os.homedir(), '.engram', 'engram.db')),
|
||||
path: z.string().default(path.join(os.homedir(), '.vestige', 'vestige.db')),
|
||||
/** Directory for database backups */
|
||||
backupDir: z.string().default(path.join(os.homedir(), '.engram', 'backups')),
|
||||
backupDir: z.string().default(path.join(os.homedir(), '.vestige', 'backups')),
|
||||
/** SQLite busy timeout in milliseconds */
|
||||
busyTimeout: z.number().default(5000),
|
||||
/** SQLite cache size in pages (negative = KB) */
|
||||
|
|
@ -133,7 +133,7 @@ const VectorStoreConfigSchema = z.object({
|
|||
/** ChromaDB host URL */
|
||||
chromaHost: z.string().default('http://localhost:8000'),
|
||||
/** Name of the embeddings collection */
|
||||
collectionName: z.string().default('engram_embeddings'),
|
||||
collectionName: z.string().default('vestige_embeddings'),
|
||||
}).default({});
|
||||
|
||||
/**
|
||||
|
|
@ -198,7 +198,7 @@ const ConfigSchema = z.object({
|
|||
/**
|
||||
* Inferred TypeScript type from the Zod schema
|
||||
*/
|
||||
export type EngramConfig = z.infer<typeof ConfigSchema>;
|
||||
export type VestigeConfig = z.infer<typeof ConfigSchema>;
|
||||
|
||||
// ============================================================================
|
||||
// CONFIGURATION LOADING
|
||||
|
|
@ -207,12 +207,12 @@ export type EngramConfig = z.infer<typeof ConfigSchema>;
|
|||
/**
|
||||
* Singleton configuration instance
|
||||
*/
|
||||
let config: EngramConfig | null = null;
|
||||
let config: VestigeConfig | null = null;
|
||||
|
||||
/**
|
||||
* Partial configuration type for environment overrides
|
||||
*/
|
||||
interface PartialEngramConfig {
|
||||
interface PartialVestigeConfig {
|
||||
database?: {
|
||||
path?: string;
|
||||
backupDir?: string;
|
||||
|
|
@ -242,12 +242,12 @@ interface PartialEngramConfig {
|
|||
* Load environment variable overrides
|
||||
* Environment variables take precedence over file configuration
|
||||
*/
|
||||
function loadEnvConfig(): PartialEngramConfig {
|
||||
const env: PartialEngramConfig = {};
|
||||
function loadEnvConfig(): PartialVestigeConfig {
|
||||
const env: PartialVestigeConfig = {};
|
||||
|
||||
// Database configuration
|
||||
const dbPath = process.env['ENGRAM_DB_PATH'];
|
||||
const backupDir = process.env['ENGRAM_BACKUP_DIR'];
|
||||
const dbPath = process.env['VESTIGE_DB_PATH'];
|
||||
const backupDir = process.env['VESTIGE_BACKUP_DIR'];
|
||||
if (dbPath || backupDir) {
|
||||
env.database = {};
|
||||
if (dbPath) env.database.path = dbPath;
|
||||
|
|
@ -255,14 +255,14 @@ function loadEnvConfig(): PartialEngramConfig {
|
|||
}
|
||||
|
||||
// Logging configuration
|
||||
const logLevel = process.env['ENGRAM_LOG_LEVEL'];
|
||||
const logLevel = process.env['VESTIGE_LOG_LEVEL'];
|
||||
if (logLevel) {
|
||||
env.logging = { level: logLevel };
|
||||
}
|
||||
|
||||
// Embeddings configuration
|
||||
const ollamaHost = process.env['OLLAMA_HOST'];
|
||||
const embeddingModel = process.env['ENGRAM_EMBEDDING_MODEL'];
|
||||
const embeddingModel = process.env['VESTIGE_EMBEDDING_MODEL'];
|
||||
if (ollamaHost || embeddingModel) {
|
||||
env.embeddings = {};
|
||||
if (ollamaHost) env.embeddings.ollamaHost = ollamaHost;
|
||||
|
|
@ -276,7 +276,7 @@ function loadEnvConfig(): PartialEngramConfig {
|
|||
}
|
||||
|
||||
// FSRS configuration
|
||||
const desiredRetention = process.env['ENGRAM_DESIRED_RETENTION'];
|
||||
const desiredRetention = process.env['VESTIGE_DESIRED_RETENTION'];
|
||||
if (desiredRetention) {
|
||||
const retention = parseFloat(desiredRetention);
|
||||
if (!isNaN(retention)) {
|
||||
|
|
@ -285,14 +285,14 @@ function loadEnvConfig(): PartialEngramConfig {
|
|||
}
|
||||
|
||||
// REM configuration
|
||||
const remEnabled = process.env['ENGRAM_REM_ENABLED'];
|
||||
const remEnabled = process.env['VESTIGE_REM_ENABLED'];
|
||||
if (remEnabled) {
|
||||
const enabled = remEnabled.toLowerCase() === 'true';
|
||||
env.rem = { enabled };
|
||||
}
|
||||
|
||||
// Consolidation configuration
|
||||
const consolidationEnabled = process.env['ENGRAM_CONSOLIDATION_ENABLED'];
|
||||
const consolidationEnabled = process.env['VESTIGE_CONSOLIDATION_ENABLED'];
|
||||
if (consolidationEnabled) {
|
||||
const enabled = consolidationEnabled.toLowerCase() === 'true';
|
||||
env.consolidation = { enabled };
|
||||
|
|
@ -338,10 +338,10 @@ function deepMerge<T extends Record<string, unknown>>(target: T, source: Partial
|
|||
* @param customPath - Optional custom path to config file
|
||||
* @returns Validated configuration object
|
||||
*/
|
||||
export function loadConfig(customPath?: string): EngramConfig {
|
||||
export function loadConfig(customPath?: string): VestigeConfig {
|
||||
if (config) return config;
|
||||
|
||||
const configPath = customPath || path.join(os.homedir(), '.engram', 'config.json');
|
||||
const configPath = customPath || path.join(os.homedir(), '.vestige', 'config.json');
|
||||
let fileConfig: Record<string, unknown> = {};
|
||||
|
||||
// Load from file if it exists
|
||||
|
|
@ -371,7 +371,7 @@ export function loadConfig(customPath?: string): EngramConfig {
|
|||
*
|
||||
* @returns The current configuration object
|
||||
*/
|
||||
export function getConfig(): EngramConfig {
|
||||
export function getConfig(): VestigeConfig {
|
||||
if (!config) {
|
||||
return loadConfig();
|
||||
}
|
||||
|
|
@ -455,7 +455,7 @@ export const getLimitsConfig = () => getConfig().limits;
|
|||
* @returns Validated configuration object
|
||||
* @throws ZodError if validation fails
|
||||
*/
|
||||
export function validateConfig(configObj: unknown): EngramConfig {
|
||||
export function validateConfig(configObj: unknown): VestigeConfig {
|
||||
return ConfigSchema.parse(configObj);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* - Spreading Activation: Related memories are co-activated and strengthened
|
||||
*/
|
||||
|
||||
import { EngramDatabase } from './database.js';
|
||||
import { VestigeDatabase } from './database.js';
|
||||
import { runREMCycle } from './rem-cycle.js';
|
||||
import type { KnowledgeNode } from './types.js';
|
||||
import { logger } from '../utils/logger.js';
|
||||
|
|
@ -89,7 +89,7 @@ const MAX_CONNECTIONS_FOR_IMPORTANCE = 5;
|
|||
* These are candidates for consolidation processing
|
||||
*/
|
||||
async function getShortTermMemories(
|
||||
db: EngramDatabase,
|
||||
db: VestigeDatabase,
|
||||
windowHours: number
|
||||
): Promise<KnowledgeNode[]> {
|
||||
const windowStart = new Date(Date.now() - windowHours * 60 * 60 * 1000);
|
||||
|
|
@ -109,7 +109,7 @@ async function getShortTermMemories(
|
|||
*
|
||||
* @returns Importance score from 0 to 1
|
||||
*/
|
||||
function calculateImportance(db: EngramDatabase, memory: KnowledgeNode): number {
|
||||
function calculateImportance(db: VestigeDatabase, memory: KnowledgeNode): number {
|
||||
// Get connection count for this memory
|
||||
const connections = db.getRelatedNodes(memory.id, 1).length;
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ function calculateImportance(db: EngramDatabase, memory: KnowledgeNode): number
|
|||
* Boost factor ranges from 1x (importance=0) to 3x (importance=1)
|
||||
*/
|
||||
async function promoteToLongTerm(
|
||||
db: EngramDatabase,
|
||||
db: VestigeDatabase,
|
||||
nodeId: string,
|
||||
importance: number
|
||||
): Promise<void> {
|
||||
|
|
@ -180,7 +180,7 @@ async function promoteToLongTerm(
|
|||
* User-created connections are preserved regardless of weight.
|
||||
*/
|
||||
async function pruneWeakConnections(
|
||||
db: EngramDatabase,
|
||||
db: VestigeDatabase,
|
||||
threshold: number
|
||||
): Promise<number> {
|
||||
// Access the internal database connection
|
||||
|
|
@ -232,12 +232,12 @@ async function pruneWeakConnections(
|
|||
* - Emotional memories decay slower
|
||||
* - Well-encoded memories (high storage strength) decay slower
|
||||
*
|
||||
* @param db - EngramDatabase instance
|
||||
* @param db - VestigeDatabase instance
|
||||
* @param options - Consolidation configuration options
|
||||
* @returns Results of the consolidation cycle
|
||||
*/
|
||||
export async function runConsolidation(
|
||||
db: EngramDatabase,
|
||||
db: VestigeDatabase,
|
||||
options: ConsolidationOptions = {}
|
||||
): Promise<ConsolidationResult> {
|
||||
const startTime = Date.now();
|
||||
|
|
@ -358,7 +358,7 @@ export function getNextConsolidationTime(): Date {
|
|||
* actual modification phases.
|
||||
*/
|
||||
export async function previewConsolidation(
|
||||
db: EngramDatabase,
|
||||
db: VestigeDatabase,
|
||||
options: ConsolidationOptions = {}
|
||||
): Promise<{
|
||||
shortTermCount: number;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* Ghost in the Shell - Context Watcher
|
||||
*
|
||||
* Watches the active window and clipboard to provide contextual awareness.
|
||||
* Engram sees what you see.
|
||||
* Vestige sees what you see.
|
||||
*
|
||||
* Features:
|
||||
* - Active window title detection (macOS via AppleScript)
|
||||
|
|
@ -35,7 +35,7 @@ export interface SystemContext {
|
|||
// CONTEXT FILE LOCATION
|
||||
// ============================================================================
|
||||
|
||||
const CONTEXT_FILE = path.join(os.homedir(), '.engram', 'context.json');
|
||||
const CONTEXT_FILE = path.join(os.homedir(), '.vestige', 'context.json');
|
||||
|
||||
// ============================================================================
|
||||
// PLATFORM-SPECIFIC IMPLEMENTATIONS
|
||||
|
|
|
|||
|
|
@ -162,8 +162,8 @@ export function captureGitContext(): GitContext | undefined {
|
|||
// CONSTANTS & CONFIGURATION
|
||||
// ============================================================================
|
||||
|
||||
const DEFAULT_DB_PATH = path.join(os.homedir(), '.engram', 'engram.db');
|
||||
const BACKUP_DIR = path.join(os.homedir(), '.engram', 'backups');
|
||||
const DEFAULT_DB_PATH = path.join(os.homedir(), '.vestige', 'vestige.db');
|
||||
const BACKUP_DIR = path.join(os.homedir(), '.vestige', 'backups');
|
||||
|
||||
// Size thresholds (in bytes)
|
||||
const SIZE_WARNING_THRESHOLD = 100 * 1024 * 1024; // 100MB
|
||||
|
|
@ -217,7 +217,7 @@ function validateBackupPath(backupPath: string): void {
|
|||
|
||||
// Check path is within backup directory
|
||||
if (!isPathWithinDirectory(resolvedPath, resolvedBackupDir)) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Backup path must be within the backup directory',
|
||||
'INVALID_BACKUP_PATH'
|
||||
);
|
||||
|
|
@ -225,7 +225,7 @@ function validateBackupPath(backupPath: string): void {
|
|||
|
||||
// Validate file extension
|
||||
if (!resolvedPath.endsWith('.db')) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Backup file must have .db extension',
|
||||
'INVALID_BACKUP_EXTENSION'
|
||||
);
|
||||
|
|
@ -233,7 +233,7 @@ function validateBackupPath(backupPath: string): void {
|
|||
|
||||
// Check for null bytes or other suspicious characters
|
||||
if (backupPath.includes('\0') || backupPath.includes('..')) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Invalid characters in backup path',
|
||||
'INVALID_BACKUP_PATH'
|
||||
);
|
||||
|
|
@ -275,7 +275,7 @@ function sanitizeErrorMessage(message: string): string {
|
|||
*/
|
||||
function validateStringLength(value: string, maxLength: number, fieldName: string): void {
|
||||
if (value && value.length > maxLength) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
`${fieldName} exceeds maximum length of ${maxLength} characters`,
|
||||
'INPUT_TOO_LONG'
|
||||
);
|
||||
|
|
@ -287,7 +287,7 @@ function validateStringLength(value: string, maxLength: number, fieldName: strin
|
|||
*/
|
||||
function validateArrayLength<T>(arr: T[] | undefined, maxLength: number, fieldName: string): void {
|
||||
if (arr && arr.length > maxLength) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
`${fieldName} exceeds maximum count of ${maxLength} items`,
|
||||
'INPUT_TOO_MANY_ITEMS'
|
||||
);
|
||||
|
|
@ -298,7 +298,7 @@ function validateArrayLength<T>(arr: T[] | undefined, maxLength: number, fieldNa
|
|||
// ERROR TYPES
|
||||
// ============================================================================
|
||||
|
||||
export class EngramDatabaseError extends Error {
|
||||
export class VestigeDatabaseError extends Error {
|
||||
constructor(
|
||||
message: string,
|
||||
public readonly code: string,
|
||||
|
|
@ -306,7 +306,7 @@ export class EngramDatabaseError extends Error {
|
|||
) {
|
||||
// Sanitize the message to prevent sensitive data leakage
|
||||
super(sanitizeErrorMessage(message));
|
||||
this.name = 'EngramDatabaseError';
|
||||
this.name = 'VestigeDatabaseError';
|
||||
// Don't expose the original cause in production - it may contain sensitive info
|
||||
if (process.env.NODE_ENV === 'development' && cause) {
|
||||
this.cause = cause;
|
||||
|
|
@ -350,7 +350,7 @@ export interface PaginatedResult<T> {
|
|||
// ============================================================================
|
||||
|
||||
export function getDbPath(): string {
|
||||
const envPath = process.env['ENGRAM_DB_PATH'];
|
||||
const envPath = process.env['VESTIGE_DB_PATH'];
|
||||
return envPath || DEFAULT_DB_PATH;
|
||||
}
|
||||
|
||||
|
|
@ -599,7 +599,7 @@ function createTables(db: Database.Database): void {
|
|||
|
||||
// Metadata table for tracking backups and system info
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS engram_metadata (
|
||||
CREATE TABLE IF NOT EXISTS vestige_metadata (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
|
|
@ -729,7 +729,7 @@ class OperationMutex {
|
|||
}
|
||||
}
|
||||
|
||||
export class EngramDatabase {
|
||||
export class VestigeDatabase {
|
||||
private db: Database.Database;
|
||||
private dbPath: string;
|
||||
private readonly writeMutex = new OperationMutex();
|
||||
|
|
@ -815,7 +815,7 @@ export class EngramDatabase {
|
|||
// Get last backup time
|
||||
let lastBackup: string | null = null;
|
||||
try {
|
||||
const row = this.db.prepare('SELECT value FROM engram_metadata WHERE key = ?').get('last_backup') as { value: string } | undefined;
|
||||
const row = this.db.prepare('SELECT value FROM vestige_metadata WHERE key = ?').get('last_backup') as { value: string } | undefined;
|
||||
lastBackup = row?.value || null;
|
||||
|
||||
// Warn if no backup in 7 days
|
||||
|
|
@ -884,7 +884,7 @@ export class EngramDatabase {
|
|||
backup(customPath?: string): string {
|
||||
// Generate safe backup filename with timestamp
|
||||
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
||||
const backupFileName = `engram-backup-${timestamp}.db`;
|
||||
const backupFileName = `vestige-backup-${timestamp}.db`;
|
||||
|
||||
// Determine backup path - always force it to be within BACKUP_DIR for security
|
||||
let backupPath: string;
|
||||
|
|
@ -899,7 +899,7 @@ export class EngramDatabase {
|
|||
} else if (isPathWithinDirectory(resolvedCustom, resolvedBackupDir)) {
|
||||
backupPath = resolvedCustom;
|
||||
} else {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Custom backup path must be within the backup directory',
|
||||
'INVALID_BACKUP_PATH'
|
||||
);
|
||||
|
|
@ -931,7 +931,7 @@ export class EngramDatabase {
|
|||
// Update metadata
|
||||
const now = new Date().toISOString();
|
||||
this.db.prepare(`
|
||||
INSERT OR REPLACE INTO engram_metadata (key, value, updated_at)
|
||||
INSERT OR REPLACE INTO vestige_metadata (key, value, updated_at)
|
||||
VALUES (?, ?, ?)
|
||||
`).run('last_backup', now, now);
|
||||
|
||||
|
|
@ -950,7 +950,7 @@ export class EngramDatabase {
|
|||
}
|
||||
|
||||
const files = fs.readdirSync(BACKUP_DIR)
|
||||
.filter(f => f.startsWith('engram-backup-') && f.endsWith('.db'))
|
||||
.filter(f => f.startsWith('vestige-backup-') && f.endsWith('.db'))
|
||||
.map(f => {
|
||||
const fullPath = path.join(BACKUP_DIR, f);
|
||||
const stats = fs.statSync(fullPath);
|
||||
|
|
@ -979,7 +979,7 @@ export class EngramDatabase {
|
|||
const resolvedPath = path.resolve(backupPath);
|
||||
|
||||
if (!fs.existsSync(resolvedPath)) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Backup file not found',
|
||||
'BACKUP_NOT_FOUND'
|
||||
);
|
||||
|
|
@ -995,14 +995,14 @@ export class EngramDatabase {
|
|||
// SQLite database files start with "SQLite format 3\0"
|
||||
const sqliteHeader = 'SQLite format 3\0';
|
||||
if (header.toString('utf8', 0, 16) !== sqliteHeader) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Invalid backup file format - not a valid SQLite database',
|
||||
'INVALID_BACKUP_FORMAT'
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof EngramDatabaseError) throw error;
|
||||
throw new EngramDatabaseError(
|
||||
if (error instanceof VestigeDatabaseError) throw error;
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to validate backup file',
|
||||
'BACKUP_VALIDATION_FAILED'
|
||||
);
|
||||
|
|
@ -1051,7 +1051,7 @@ export class EngramDatabase {
|
|||
this.db = initializeDatabase(this.dbPath);
|
||||
fs.unlinkSync(preRestoreBackup);
|
||||
}
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to restore backup',
|
||||
'RESTORE_FAILED'
|
||||
);
|
||||
|
|
@ -1156,8 +1156,8 @@ export class EngramDatabase {
|
|||
|
||||
return { ...node, id } as KnowledgeNode;
|
||||
} catch (error) {
|
||||
if (error instanceof EngramDatabaseError) throw error;
|
||||
throw new EngramDatabaseError(
|
||||
if (error instanceof VestigeDatabaseError) throw error;
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to insert knowledge node',
|
||||
'INSERT_NODE_FAILED'
|
||||
);
|
||||
|
|
@ -1171,7 +1171,7 @@ export class EngramDatabase {
|
|||
if (!row) return null;
|
||||
return this.rowToNode(row);
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
`Failed to get node: ${id}`,
|
||||
'GET_NODE_FAILED',
|
||||
error
|
||||
|
|
@ -1194,7 +1194,7 @@ export class EngramDatabase {
|
|||
`);
|
||||
stmt.run(new Date().toISOString(), id);
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
`Failed to update node access: ${id}`,
|
||||
'UPDATE_ACCESS_FAILED',
|
||||
error
|
||||
|
|
@ -1222,7 +1222,7 @@ export class EngramDatabase {
|
|||
try {
|
||||
const node = this.getNode(id);
|
||||
if (!node) {
|
||||
throw new EngramDatabaseError(`Node not found: ${id}`, 'NODE_NOT_FOUND');
|
||||
throw new VestigeDatabaseError(`Node not found: ${id}`, 'NODE_NOT_FOUND');
|
||||
}
|
||||
|
||||
const currentStability = node.stabilityFactor ?? SM2_MIN_STABILITY;
|
||||
|
|
@ -1285,8 +1285,8 @@ export class EngramDatabase {
|
|||
id
|
||||
);
|
||||
} catch (error) {
|
||||
if (error instanceof EngramDatabaseError) throw error;
|
||||
throw new EngramDatabaseError(
|
||||
if (error instanceof VestigeDatabaseError) throw error;
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to mark node as reviewed',
|
||||
'MARK_REVIEWED_FAILED'
|
||||
);
|
||||
|
|
@ -1346,8 +1346,8 @@ export class EngramDatabase {
|
|||
hasMore: safeOffset + items.length < total,
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof EngramDatabaseError) throw error;
|
||||
throw new EngramDatabaseError(
|
||||
if (error instanceof VestigeDatabaseError) throw error;
|
||||
throw new VestigeDatabaseError(
|
||||
'Search operation failed',
|
||||
'SEARCH_FAILED'
|
||||
);
|
||||
|
|
@ -1380,7 +1380,7 @@ export class EngramDatabase {
|
|||
hasMore: offset + items.length < total,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to get recent nodes',
|
||||
'GET_RECENT_FAILED',
|
||||
error
|
||||
|
|
@ -1419,7 +1419,7 @@ export class EngramDatabase {
|
|||
hasMore: offset + items.length < total,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to get decaying nodes',
|
||||
'GET_DECAYING_FAILED',
|
||||
error
|
||||
|
|
@ -1433,7 +1433,7 @@ export class EngramDatabase {
|
|||
const result = stmt.get() as { count: number };
|
||||
return result.count;
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to get node count',
|
||||
'COUNT_FAILED',
|
||||
error
|
||||
|
|
@ -1450,7 +1450,7 @@ export class EngramDatabase {
|
|||
const result = stmt.run(id);
|
||||
return result.changes > 0;
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
`Failed to delete node: ${id}`,
|
||||
'DELETE_NODE_FAILED',
|
||||
error
|
||||
|
|
@ -1504,8 +1504,8 @@ export class EngramDatabase {
|
|||
|
||||
return { ...person, id, createdAt: new Date(now), updatedAt: new Date(now) } as PersonNode;
|
||||
} catch (error) {
|
||||
if (error instanceof EngramDatabaseError) throw error;
|
||||
throw new EngramDatabaseError(
|
||||
if (error instanceof VestigeDatabaseError) throw error;
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to insert person',
|
||||
'INSERT_PERSON_FAILED'
|
||||
);
|
||||
|
|
@ -1519,7 +1519,7 @@ export class EngramDatabase {
|
|||
if (!row) return null;
|
||||
return this.rowToPerson(row);
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
`Failed to get person: ${id}`,
|
||||
'GET_PERSON_FAILED',
|
||||
error
|
||||
|
|
@ -1548,8 +1548,8 @@ export class EngramDatabase {
|
|||
if (!row) return null;
|
||||
return this.rowToPerson(row);
|
||||
} catch (error) {
|
||||
if (error instanceof EngramDatabaseError) throw error;
|
||||
throw new EngramDatabaseError(
|
||||
if (error instanceof VestigeDatabaseError) throw error;
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to get person by name',
|
||||
'GET_PERSON_BY_NAME_FAILED'
|
||||
);
|
||||
|
|
@ -1578,7 +1578,7 @@ export class EngramDatabase {
|
|||
hasMore: offset + items.length < total,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to get all people',
|
||||
'GET_ALL_PEOPLE_FAILED',
|
||||
error
|
||||
|
|
@ -1622,7 +1622,7 @@ export class EngramDatabase {
|
|||
hasMore: offset + items.length < total,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to get people to reconnect',
|
||||
'GET_RECONNECT_FAILED',
|
||||
error
|
||||
|
|
@ -1643,7 +1643,7 @@ export class EngramDatabase {
|
|||
const now = new Date().toISOString();
|
||||
stmt.run(now, now, id);
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
`Failed to update person contact: ${id}`,
|
||||
'UPDATE_CONTACT_FAILED',
|
||||
error
|
||||
|
|
@ -1660,7 +1660,7 @@ export class EngramDatabase {
|
|||
const result = stmt.run(id);
|
||||
return result.changes > 0;
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
`Failed to delete person: ${id}`,
|
||||
'DELETE_PERSON_FAILED',
|
||||
error
|
||||
|
|
@ -1691,7 +1691,7 @@ export class EngramDatabase {
|
|||
|
||||
return { ...edge, id, createdAt: new Date(now) } as GraphEdge;
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to insert edge',
|
||||
'INSERT_EDGE_FAILED',
|
||||
error
|
||||
|
|
@ -1731,7 +1731,7 @@ export class EngramDatabase {
|
|||
|
||||
return Array.from(visited);
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
`Failed to get related nodes: ${nodeId}`,
|
||||
'GET_RELATED_FAILED',
|
||||
error
|
||||
|
|
@ -1755,7 +1755,7 @@ export class EngramDatabase {
|
|||
totalEdges: edgeCount.c,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to get stats',
|
||||
'GET_STATS_FAILED',
|
||||
error
|
||||
|
|
@ -1779,7 +1779,7 @@ export class EngramDatabase {
|
|||
// Reindex for performance
|
||||
this.db.exec('REINDEX');
|
||||
} catch (error) {
|
||||
throw new EngramDatabaseError(
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to optimize database',
|
||||
'OPTIMIZE_FAILED',
|
||||
error
|
||||
|
|
@ -1891,8 +1891,8 @@ export class EngramDatabase {
|
|||
// Execute with IMMEDIATE mode (acquires RESERVED lock immediately)
|
||||
return transaction.immediate();
|
||||
} catch (error) {
|
||||
if (error instanceof EngramDatabaseError) throw error;
|
||||
throw new EngramDatabaseError(
|
||||
if (error instanceof VestigeDatabaseError) throw error;
|
||||
throw new VestigeDatabaseError(
|
||||
'Failed to apply decay',
|
||||
'APPLY_DECAY_FAILED'
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Embeddings Service - Semantic Understanding for Engram
|
||||
* Embeddings Service - Semantic Understanding for Vestige
|
||||
*
|
||||
* Provides vector embeddings for knowledge nodes using Ollama.
|
||||
* Embeddings enable semantic similarity search and connection discovery.
|
||||
|
|
@ -30,7 +30,7 @@ const OLLAMA_HOST = process.env['OLLAMA_HOST'] || 'http://localhost:11434';
|
|||
* - High quality embeddings for semantic search
|
||||
* - 8192 token context window
|
||||
*/
|
||||
const EMBEDDING_MODEL = process.env['ENGRAM_EMBEDDING_MODEL'] || 'nomic-embed-text';
|
||||
const EMBEDDING_MODEL = process.env['VESTIGE_EMBEDDING_MODEL'] || 'nomic-embed-text';
|
||||
|
||||
/**
|
||||
* Maximum characters to embed. nomic-embed-text supports ~8192 tokens,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Engram Error Types
|
||||
* Vestige Error Types
|
||||
*
|
||||
* A comprehensive hierarchy of errors for proper error handling and reporting.
|
||||
* Includes type guards, utilities, and a Result type for functional error handling.
|
||||
|
|
@ -31,9 +31,9 @@ export function sanitizeErrorMessage(message: string): string {
|
|||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Base error class for all Engram errors
|
||||
* Base error class for all Vestige errors
|
||||
*/
|
||||
export class EngramError extends Error {
|
||||
export class VestigeError extends Error {
|
||||
constructor(
|
||||
message: string,
|
||||
public readonly code: string,
|
||||
|
|
@ -41,7 +41,7 @@ export class EngramError extends Error {
|
|||
public readonly details?: Record<string, unknown>
|
||||
) {
|
||||
super(message);
|
||||
this.name = 'EngramError';
|
||||
this.name = 'VestigeError';
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
}
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ export class EngramError extends Error {
|
|||
/**
|
||||
* Validation errors (400)
|
||||
*/
|
||||
export class ValidationError extends EngramError {
|
||||
export class ValidationError extends VestigeError {
|
||||
constructor(message: string, details?: Record<string, unknown>) {
|
||||
super(message, 'VALIDATION_ERROR', 400, details);
|
||||
this.name = 'ValidationError';
|
||||
|
|
@ -88,7 +88,7 @@ export class ValidationError extends EngramError {
|
|||
/**
|
||||
* Resource not found (404)
|
||||
*/
|
||||
export class NotFoundError extends EngramError {
|
||||
export class NotFoundError extends VestigeError {
|
||||
constructor(resource: string, id?: string) {
|
||||
super(
|
||||
id ? `${resource} not found: ${id}` : `${resource} not found`,
|
||||
|
|
@ -103,7 +103,7 @@ export class NotFoundError extends EngramError {
|
|||
/**
|
||||
* Conflict errors (409)
|
||||
*/
|
||||
export class ConflictError extends EngramError {
|
||||
export class ConflictError extends VestigeError {
|
||||
constructor(message: string, details?: Record<string, unknown>) {
|
||||
super(message, 'CONFLICT', 409, details);
|
||||
this.name = 'ConflictError';
|
||||
|
|
@ -113,7 +113,7 @@ export class ConflictError extends EngramError {
|
|||
/**
|
||||
* Database operation errors (500)
|
||||
*/
|
||||
export class DatabaseError extends EngramError {
|
||||
export class DatabaseError extends VestigeError {
|
||||
constructor(message: string, cause?: unknown) {
|
||||
super(sanitizeErrorMessage(message), 'DATABASE_ERROR', 500, {
|
||||
cause: String(cause),
|
||||
|
|
@ -125,7 +125,7 @@ export class DatabaseError extends EngramError {
|
|||
/**
|
||||
* Security-related errors (403)
|
||||
*/
|
||||
export class SecurityError extends EngramError {
|
||||
export class SecurityError extends VestigeError {
|
||||
constructor(message: string, details?: Record<string, unknown>) {
|
||||
super(message, 'SECURITY_ERROR', 403, details);
|
||||
this.name = 'SecurityError';
|
||||
|
|
@ -135,7 +135,7 @@ export class SecurityError extends EngramError {
|
|||
/**
|
||||
* Configuration errors (500)
|
||||
*/
|
||||
export class ConfigurationError extends EngramError {
|
||||
export class ConfigurationError extends VestigeError {
|
||||
constructor(message: string, details?: Record<string, unknown>) {
|
||||
super(message, 'CONFIGURATION_ERROR', 500, details);
|
||||
this.name = 'ConfigurationError';
|
||||
|
|
@ -145,7 +145,7 @@ export class ConfigurationError extends EngramError {
|
|||
/**
|
||||
* Timeout errors (408)
|
||||
*/
|
||||
export class TimeoutError extends EngramError {
|
||||
export class TimeoutError extends VestigeError {
|
||||
constructor(operation: string, timeoutMs: number) {
|
||||
super(`Operation timed out: ${operation}`, 'TIMEOUT', 408, {
|
||||
operation,
|
||||
|
|
@ -158,7 +158,7 @@ export class TimeoutError extends EngramError {
|
|||
/**
|
||||
* Embedding service errors
|
||||
*/
|
||||
export class EmbeddingError extends EngramError {
|
||||
export class EmbeddingError extends VestigeError {
|
||||
constructor(message: string, cause?: unknown) {
|
||||
super(message, 'EMBEDDING_ERROR', 500, { cause: String(cause) });
|
||||
this.name = 'EmbeddingError';
|
||||
|
|
@ -168,7 +168,7 @@ export class EmbeddingError extends EngramError {
|
|||
/**
|
||||
* Concurrency/locking errors (409)
|
||||
*/
|
||||
export class ConcurrencyError extends EngramError {
|
||||
export class ConcurrencyError extends VestigeError {
|
||||
constructor(message: string = 'Operation failed due to concurrent access') {
|
||||
super(message, 'CONCURRENCY_ERROR', 409);
|
||||
this.name = 'ConcurrencyError';
|
||||
|
|
@ -178,7 +178,7 @@ export class ConcurrencyError extends EngramError {
|
|||
/**
|
||||
* Rate limit errors (429)
|
||||
*/
|
||||
export class RateLimitError extends EngramError {
|
||||
export class RateLimitError extends VestigeError {
|
||||
constructor(message: string, retryAfterMs?: number) {
|
||||
super(message, 'RATE_LIMIT', 429, { retryAfterMs });
|
||||
this.name = 'RateLimitError';
|
||||
|
|
@ -188,7 +188,7 @@ export class RateLimitError extends EngramError {
|
|||
/**
|
||||
* Authentication errors (401)
|
||||
*/
|
||||
export class AuthenticationError extends EngramError {
|
||||
export class AuthenticationError extends VestigeError {
|
||||
constructor(message: string = 'Authentication required') {
|
||||
super(message, 'AUTHENTICATION_ERROR', 401);
|
||||
this.name = 'AuthenticationError';
|
||||
|
|
@ -200,22 +200,22 @@ export class AuthenticationError extends EngramError {
|
|||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Type guard for EngramError
|
||||
* Type guard for VestigeError
|
||||
*/
|
||||
export function isEngramError(error: unknown): error is EngramError {
|
||||
return error instanceof EngramError;
|
||||
export function isVestigeError(error: unknown): error is VestigeError {
|
||||
return error instanceof VestigeError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert unknown error to EngramError
|
||||
* Convert unknown error to VestigeError
|
||||
*/
|
||||
export function toEngramError(error: unknown): EngramError {
|
||||
if (isEngramError(error)) {
|
||||
export function toVestigeError(error: unknown): VestigeError {
|
||||
if (isVestigeError(error)) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (error instanceof Error) {
|
||||
return new EngramError(
|
||||
return new VestigeError(
|
||||
sanitizeErrorMessage(error.message),
|
||||
'UNKNOWN_ERROR',
|
||||
500,
|
||||
|
|
@ -224,10 +224,10 @@ export function toEngramError(error: unknown): EngramError {
|
|||
}
|
||||
|
||||
if (typeof error === 'string') {
|
||||
return new EngramError(sanitizeErrorMessage(error), 'UNKNOWN_ERROR', 500);
|
||||
return new VestigeError(sanitizeErrorMessage(error), 'UNKNOWN_ERROR', 500);
|
||||
}
|
||||
|
||||
return new EngramError('An unknown error occurred', 'UNKNOWN_ERROR', 500, {
|
||||
return new VestigeError('An unknown error occurred', 'UNKNOWN_ERROR', 500, {
|
||||
errorType: typeof error,
|
||||
});
|
||||
}
|
||||
|
|
@ -237,7 +237,7 @@ export function toEngramError(error: unknown): EngramError {
|
|||
*/
|
||||
export function wrapError<T extends (...args: unknown[]) => Promise<unknown>>(
|
||||
fn: T,
|
||||
errorTransform?: (error: unknown) => EngramError
|
||||
errorTransform?: (error: unknown) => VestigeError
|
||||
): T {
|
||||
const wrapped = async (...args: Parameters<T>): Promise<ReturnType<T>> => {
|
||||
try {
|
||||
|
|
@ -246,7 +246,7 @@ export function wrapError<T extends (...args: unknown[]) => Promise<unknown>>(
|
|||
if (errorTransform) {
|
||||
throw errorTransform(error);
|
||||
}
|
||||
throw toEngramError(error);
|
||||
throw toVestigeError(error);
|
||||
}
|
||||
};
|
||||
return wrapped as T;
|
||||
|
|
@ -257,7 +257,7 @@ export function wrapError<T extends (...args: unknown[]) => Promise<unknown>>(
|
|||
*/
|
||||
export async function withErrorHandling<T>(
|
||||
fn: () => Promise<T>,
|
||||
errorTransform?: (error: unknown) => EngramError
|
||||
errorTransform?: (error: unknown) => VestigeError
|
||||
): Promise<T> {
|
||||
try {
|
||||
return await fn();
|
||||
|
|
@ -265,7 +265,7 @@ export async function withErrorHandling<T>(
|
|||
if (errorTransform) {
|
||||
throw errorTransform(error);
|
||||
}
|
||||
throw toEngramError(error);
|
||||
throw toVestigeError(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -297,7 +297,7 @@ export async function withRetry<T>(
|
|||
lastError = error;
|
||||
|
||||
if (attempt === maxRetries || !shouldRetry(error)) {
|
||||
throw toEngramError(error);
|
||||
throw toVestigeError(error);
|
||||
}
|
||||
|
||||
const delay = Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs);
|
||||
|
|
@ -305,7 +305,7 @@ export async function withRetry<T>(
|
|||
}
|
||||
}
|
||||
|
||||
throw toEngramError(lastError);
|
||||
throw toVestigeError(lastError);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -315,7 +315,7 @@ export async function withRetry<T>(
|
|||
/**
|
||||
* Result type for functional error handling
|
||||
*/
|
||||
export type Result<T, E = EngramError> =
|
||||
export type Result<T, E = VestigeError> =
|
||||
| { success: true; data: T }
|
||||
| { success: false; error: E };
|
||||
|
||||
|
|
@ -329,7 +329,7 @@ export function ok<T>(data: T): Result<T, never> {
|
|||
/**
|
||||
* Create an error result
|
||||
*/
|
||||
export function err<E = EngramError>(error: E): Result<never, E> {
|
||||
export function err<E = VestigeError>(error: E): Result<never, E> {
|
||||
return { success: false, error };
|
||||
}
|
||||
|
||||
|
|
@ -398,24 +398,24 @@ export function mapError<T, E, F>(
|
|||
*/
|
||||
export async function tryCatch<T>(
|
||||
fn: () => Promise<T>
|
||||
): Promise<Result<T, EngramError>> {
|
||||
): Promise<Result<T, VestigeError>> {
|
||||
try {
|
||||
const data = await fn();
|
||||
return ok(data);
|
||||
} catch (error) {
|
||||
return err(toEngramError(error));
|
||||
return err(toVestigeError(error));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a synchronous function and return a Result
|
||||
*/
|
||||
export function tryCatchSync<T>(fn: () => T): Result<T, EngramError> {
|
||||
export function tryCatchSync<T>(fn: () => T): Result<T, VestigeError> {
|
||||
try {
|
||||
const data = fn();
|
||||
return ok(data);
|
||||
} catch (error) {
|
||||
return err(toEngramError(error));
|
||||
return err(toVestigeError(error));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* 5. Exponential Temporal Proximity - Time-based connection strength decay
|
||||
*/
|
||||
|
||||
import { EngramDatabase } from './database.js';
|
||||
import { VestigeDatabase } from './database.js';
|
||||
import type { KnowledgeNode } from './types.js';
|
||||
import natural from 'natural';
|
||||
import {
|
||||
|
|
@ -354,7 +354,7 @@ interface SpreadingActivationResult {
|
|||
* If A -> B and B -> C exist, creates A -> C with decayed weight
|
||||
*/
|
||||
function applySpreadingActivation(
|
||||
db: EngramDatabase,
|
||||
db: VestigeDatabase,
|
||||
maxDepth: number = 2,
|
||||
minWeight: number = 0.2
|
||||
): SpreadingActivationResult {
|
||||
|
|
@ -470,7 +470,7 @@ function applySpreadingActivation(
|
|||
* Strengthen connections for recently accessed nodes
|
||||
* Implements memory reconsolidation - accessing memories makes them stronger
|
||||
*/
|
||||
function reconsolidateConnections(db: EngramDatabase, nodeId: string): number {
|
||||
function reconsolidateConnections(db: VestigeDatabase, nodeId: string): number {
|
||||
let strengthened = 0;
|
||||
|
||||
try {
|
||||
|
|
@ -508,7 +508,7 @@ function reconsolidateConnections(db: EngramDatabase, nodeId: string): number {
|
|||
/**
|
||||
* Get nodes that have few or no connections
|
||||
*/
|
||||
function getDisconnectedNodes(db: EngramDatabase, maxEdges: number = 1): KnowledgeNode[] {
|
||||
function getDisconnectedNodes(db: VestigeDatabase, maxEdges: number = 1): KnowledgeNode[] {
|
||||
// Get all nodes
|
||||
const result = db.getRecentNodes({ limit: 500 });
|
||||
const allNodes = result.items;
|
||||
|
|
@ -538,7 +538,7 @@ function getDisconnectedNodes(db: EngramDatabase, maxEdges: number = 1): Knowled
|
|||
* 6. Run spreading activation to find transitive connections
|
||||
*/
|
||||
export async function runREMCycle(
|
||||
db: EngramDatabase,
|
||||
db: VestigeDatabase,
|
||||
options: REMCycleOptions = {}
|
||||
): Promise<REMCycleResult> {
|
||||
const startTime = Date.now();
|
||||
|
|
@ -708,7 +708,7 @@ export async function runREMCycle(
|
|||
/**
|
||||
* Get a summary of potential discoveries without creating edges
|
||||
*/
|
||||
export async function previewREMCycle(db: EngramDatabase): Promise<REMCycleResult> {
|
||||
export async function previewREMCycle(db: VestigeDatabase): Promise<REMCycleResult> {
|
||||
return runREMCycle(db, { dryRun: true, maxAnalyze: 100 });
|
||||
}
|
||||
|
||||
|
|
@ -716,6 +716,6 @@ export async function previewREMCycle(db: EngramDatabase): Promise<REMCycleResul
|
|||
* Trigger reconsolidation for a specific node
|
||||
* Call this when a node is accessed to strengthen its connections
|
||||
*/
|
||||
export function triggerReconsolidation(db: EngramDatabase, nodeId: string): number {
|
||||
export function triggerReconsolidation(db: VestigeDatabase, nodeId: string): number {
|
||||
return reconsolidateConnections(db, nodeId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Security Utilities for Engram
|
||||
* Security Utilities for Vestige
|
||||
*
|
||||
* Provides comprehensive security controls including:
|
||||
* - Input validation and sanitization
|
||||
|
|
@ -917,7 +917,7 @@ export function logSecurityEvent(event: Omit<SecurityEvent, 'timestamp'>): void
|
|||
}
|
||||
|
||||
// Log to stderr in debug mode
|
||||
if (process.env['ENGRAM_DEBUG']) {
|
||||
if (process.env['VESTIGE_DEBUG']) {
|
||||
console.error(`[SECURITY:${fullEvent.severity.toUpperCase()}] ${fullEvent.type}: ${JSON.stringify(fullEvent.details)}`);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
*
|
||||
* "Your subconscious that keeps working while you're not looking."
|
||||
*
|
||||
* When you say "I don't know how to fix this," Engram logs it.
|
||||
* When you say "I don't know how to fix this," Vestige logs it.
|
||||
* The Shadow periodically re-attacks these problems with new context.
|
||||
*
|
||||
* This turns Engram from a passive memory into an active problem-solver.
|
||||
* This turns Vestige from a passive memory into an active problem-solver.
|
||||
*/
|
||||
|
||||
import Database from 'better-sqlite3';
|
||||
|
|
@ -47,7 +47,7 @@ export interface ShadowInsight {
|
|||
// DATABASE SETUP
|
||||
// ============================================================================
|
||||
|
||||
const SHADOW_DB_PATH = path.join(os.homedir(), '.engram', 'shadow.db');
|
||||
const SHADOW_DB_PATH = path.join(os.homedir(), '.vestige', 'shadow.db');
|
||||
|
||||
function initializeShadowDb(): Database.Database {
|
||||
const dir = path.dirname(SHADOW_DB_PATH);
|
||||
|
|
@ -343,12 +343,12 @@ export class ShadowSelf {
|
|||
// SHADOW WORK - Background processing
|
||||
// ============================================================================
|
||||
|
||||
import { EngramDatabase } from './database.js';
|
||||
import { VestigeDatabase } from './database.js';
|
||||
|
||||
/**
|
||||
* Run Shadow work cycle - look for new insights on unsolved problems
|
||||
*/
|
||||
export function runShadowCycle(shadow: ShadowSelf, engram: EngramDatabase): {
|
||||
export function runShadowCycle(shadow: ShadowSelf, vestige: VestigeDatabase): {
|
||||
problemsAnalyzed: number;
|
||||
insightsGenerated: number;
|
||||
insights: Array<{ problem: string; insight: string }>;
|
||||
|
|
@ -374,7 +374,7 @@ export function runShadowCycle(shadow: ShadowSelf, engram: EngramDatabase): {
|
|||
// Search knowledge base for related content
|
||||
for (const keyword of keywords.slice(0, 5)) {
|
||||
try {
|
||||
const searchResult = engram.searchNodes(keyword, { limit: 3 });
|
||||
const searchResult = vestige.searchNodes(keyword, { limit: 3 });
|
||||
|
||||
for (const node of searchResult.items) {
|
||||
// Check if this node was added after the problem
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Vector Store Integration for Engram MCP
|
||||
* Vector Store Integration for Vestige MCP
|
||||
*
|
||||
* Provides semantic search capabilities via vector embeddings.
|
||||
* Primary: ChromaDB (when available) - fast, efficient vector database
|
||||
|
|
@ -18,7 +18,7 @@ import type Database from 'better-sqlite3';
|
|||
// ============================================================================
|
||||
|
||||
const CHROMA_HOST = process.env['CHROMA_HOST'] ?? 'http://localhost:8000';
|
||||
const COLLECTION_NAME = 'engram_embeddings';
|
||||
const COLLECTION_NAME = 'vestige_embeddings';
|
||||
const DEFAULT_SIMILARITY_LIMIT = 10;
|
||||
const MAX_SIMILARITY_LIMIT = 100;
|
||||
|
||||
|
|
@ -224,7 +224,7 @@ export class ChromaVectorStore implements IVectorStore {
|
|||
name: COLLECTION_NAME,
|
||||
metadata: {
|
||||
'hnsw:space': 'cosine', // Use cosine similarity
|
||||
description: 'Engram knowledge node embeddings',
|
||||
description: 'Vestige knowledge node embeddings',
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
||||
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
||||
import { z } from 'zod';
|
||||
import { EngramDatabase, EngramDatabaseError } from './core/database.js';
|
||||
import { VestigeDatabase, VestigeDatabaseError } from './core/database.js';
|
||||
import {
|
||||
captureContext,
|
||||
formatContextForInjection,
|
||||
|
|
@ -20,7 +20,7 @@ import { FSRSScheduler, Grade, type ReviewGrade } from './core/fsrs.js';
|
|||
import { createEmbeddingService, type EmbeddingService } from './core/embeddings.js';
|
||||
import { createVectorStore, type IVectorStore } from './core/vector-store.js';
|
||||
import { runConsolidation } from './core/consolidation.js';
|
||||
import { getConfig, type EngramConfig } from './core/config.js';
|
||||
import { getConfig, type VestigeConfig } from './core/config.js';
|
||||
import { JobQueue } from './jobs/JobQueue.js';
|
||||
import { createDecayJobHandler } from './jobs/DecayJob.js';
|
||||
import { createREMCycleJobHandler } from './jobs/REMCycleJob.js';
|
||||
|
|
@ -34,11 +34,11 @@ import {
|
|||
import { logger, mcpLogger } from './utils/logger.js';
|
||||
|
||||
// ============================================================================
|
||||
// ENGRAM MCP SERVER
|
||||
// VESTIGE MCP SERVER
|
||||
// ============================================================================
|
||||
|
||||
const server = new McpServer({
|
||||
name: 'engram',
|
||||
name: 'vestige',
|
||||
version: '0.3.0',
|
||||
});
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ const server = new McpServer({
|
|||
const config = getConfig();
|
||||
|
||||
// Initialize database
|
||||
const db = new EngramDatabase();
|
||||
const db = new VestigeDatabase();
|
||||
|
||||
// Initialize FSRS scheduler
|
||||
const fsrsScheduler = new FSRSScheduler({
|
||||
|
|
@ -64,7 +64,7 @@ let jobQueue: JobQueue | null = null;
|
|||
// ============================================================================
|
||||
|
||||
async function initializeServices(): Promise<void> {
|
||||
logger.info('Initializing Engram services...');
|
||||
logger.info('Initializing Vestige services...');
|
||||
|
||||
// Initialize embedding service (with fallback)
|
||||
try {
|
||||
|
|
@ -122,7 +122,7 @@ async function initializeServices(): Promise<void> {
|
|||
logger.warn('Failed to initialize job queue', { error: String(error) });
|
||||
}
|
||||
|
||||
logger.info('Engram services initialization complete');
|
||||
logger.info('Vestige services initialization complete');
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
|
@ -139,7 +139,7 @@ function safeResponse(data: unknown): { content: Array<{ type: 'text'; text: str
|
|||
}
|
||||
|
||||
function errorResponse(error: unknown): { content: Array<{ type: 'text'; text: string }> } {
|
||||
const message = error instanceof EngramDatabaseError
|
||||
const message = error instanceof VestigeDatabaseError
|
||||
? { error: error.message, code: error.code }
|
||||
: { error: error instanceof Error ? error.message : 'Unknown error' };
|
||||
|
||||
|
|
@ -1290,7 +1290,7 @@ function getHealthRecommendations(health: ReturnType<typeof db.checkHealth>): st
|
|||
// ============================================================================
|
||||
|
||||
async function gracefulShutdown(): Promise<void> {
|
||||
logger.info('Shutting down Engram...');
|
||||
logger.info('Shutting down Vestige...');
|
||||
|
||||
// Stop job queue
|
||||
if (jobQueue) {
|
||||
|
|
@ -1320,7 +1320,7 @@ async function gracefulShutdown(): Promise<void> {
|
|||
db.close();
|
||||
logger.info('Database closed');
|
||||
|
||||
logger.info('Engram shutdown complete');
|
||||
logger.info('Vestige shutdown complete');
|
||||
}
|
||||
|
||||
process.on('SIGINT', async () => {
|
||||
|
|
@ -1343,11 +1343,11 @@ async function main() {
|
|||
|
||||
const transport = new StdioServerTransport();
|
||||
await server.connect(transport);
|
||||
logger.info('Engram MCP server v0.3.0 running');
|
||||
logger.info('Vestige MCP server v0.3.0 running');
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
logger.error('Failed to start Engram', error instanceof Error ? error : undefined);
|
||||
logger.error('Failed to start Vestige', error instanceof Error ? error : undefined);
|
||||
db.close();
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* @module jobs/ConsolidationJob
|
||||
*/
|
||||
|
||||
import type { EngramDatabase } from '../core/database.js';
|
||||
import type { VestigeDatabase } from '../core/database.js';
|
||||
import type { Job, JobHandler } from './JobQueue.js';
|
||||
|
||||
// ============================================================================
|
||||
|
|
@ -55,7 +55,7 @@ export interface ConsolidationJobResult {
|
|||
* Run knowledge consolidation on the database
|
||||
*/
|
||||
async function runConsolidation(
|
||||
db: EngramDatabase,
|
||||
db: VestigeDatabase,
|
||||
options: {
|
||||
mergeThreshold?: number;
|
||||
pruneOrphanedEdges?: boolean;
|
||||
|
|
@ -116,12 +116,12 @@ async function runConsolidation(
|
|||
/**
|
||||
* Create a consolidation job handler
|
||||
*
|
||||
* @param db - EngramDatabase instance
|
||||
* @param db - VestigeDatabase instance
|
||||
* @returns Job handler function
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const db = new EngramDatabase();
|
||||
* const db = new VestigeDatabase();
|
||||
* const queue = new JobQueue();
|
||||
*
|
||||
* queue.register('consolidation', createConsolidationJobHandler(db), {
|
||||
|
|
@ -134,7 +134,7 @@ async function runConsolidation(
|
|||
* ```
|
||||
*/
|
||||
export function createConsolidationJobHandler(
|
||||
db: EngramDatabase
|
||||
db: VestigeDatabase
|
||||
): JobHandler<ConsolidationJobData, ConsolidationJobResult> {
|
||||
return async (job: Job<ConsolidationJobData>): Promise<ConsolidationJobResult> => {
|
||||
return runConsolidation(db, {
|
||||
|
|
@ -154,7 +154,7 @@ export function createConsolidationJobHandler(
|
|||
* Preview what consolidation would do without making changes
|
||||
*/
|
||||
export async function previewConsolidation(
|
||||
db: EngramDatabase
|
||||
db: VestigeDatabase
|
||||
): Promise<ConsolidationJobResult> {
|
||||
return runConsolidation(db, { dryRun: true });
|
||||
}
|
||||
|
|
@ -162,7 +162,7 @@ export async function previewConsolidation(
|
|||
/**
|
||||
* Get database health metrics relevant to consolidation
|
||||
*/
|
||||
export function getConsolidationMetrics(db: EngramDatabase): {
|
||||
export function getConsolidationMetrics(db: VestigeDatabase): {
|
||||
totalNodes: number;
|
||||
totalEdges: number;
|
||||
databaseSizeMB: number;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
* @module jobs/DecayJob
|
||||
*/
|
||||
|
||||
import type { EngramDatabase } from '../core/database.js';
|
||||
import type { VestigeDatabase } from '../core/database.js';
|
||||
import type { Job, JobHandler } from './JobQueue.js';
|
||||
|
||||
// ============================================================================
|
||||
|
|
@ -39,12 +39,12 @@ export interface DecayJobResult {
|
|||
/**
|
||||
* Create a decay job handler
|
||||
*
|
||||
* @param db - EngramDatabase instance
|
||||
* @param db - VestigeDatabase instance
|
||||
* @returns Job handler function
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const db = new EngramDatabase();
|
||||
* const db = new VestigeDatabase();
|
||||
* const queue = new JobQueue();
|
||||
*
|
||||
* queue.register('decay', createDecayJobHandler(db), {
|
||||
|
|
@ -57,7 +57,7 @@ export interface DecayJobResult {
|
|||
* ```
|
||||
*/
|
||||
export function createDecayJobHandler(
|
||||
db: EngramDatabase
|
||||
db: VestigeDatabase
|
||||
): JobHandler<DecayJobData, DecayJobResult> {
|
||||
return async (job: Job<DecayJobData>): Promise<DecayJobResult> => {
|
||||
const startTime = Date.now();
|
||||
|
|
@ -85,7 +85,7 @@ export function createDecayJobHandler(
|
|||
* Useful for generating review notifications
|
||||
*/
|
||||
export async function getCriticallyDecayedNodes(
|
||||
db: EngramDatabase,
|
||||
db: VestigeDatabase,
|
||||
threshold: number = 0.3
|
||||
): Promise<{ nodeId: string; retention: number; content: string }[]> {
|
||||
const result = db.getDecayingNodes(threshold, { limit: 50 });
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* JobQueue - Background Job Processing for Engram MCP
|
||||
* JobQueue - Background Job Processing for Vestige MCP
|
||||
*
|
||||
* A production-ready in-memory job queue with:
|
||||
* - Priority-based job scheduling
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
* @module jobs/REMCycleJob
|
||||
*/
|
||||
|
||||
import type { EngramDatabase } from '../core/database.js';
|
||||
import type { VestigeDatabase } from '../core/database.js';
|
||||
import { runREMCycle } from '../core/rem-cycle.js';
|
||||
import type { Job, JobHandler } from './JobQueue.js';
|
||||
|
||||
|
|
@ -53,12 +53,12 @@ export interface REMCycleJobResult {
|
|||
/**
|
||||
* Create a REM cycle job handler
|
||||
*
|
||||
* @param db - EngramDatabase instance
|
||||
* @param db - VestigeDatabase instance
|
||||
* @returns Job handler function
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const db = new EngramDatabase();
|
||||
* const db = new VestigeDatabase();
|
||||
* const queue = new JobQueue();
|
||||
*
|
||||
* queue.register('rem-cycle', createREMCycleJobHandler(db), {
|
||||
|
|
@ -71,7 +71,7 @@ export interface REMCycleJobResult {
|
|||
* ```
|
||||
*/
|
||||
export function createREMCycleJobHandler(
|
||||
db: EngramDatabase
|
||||
db: VestigeDatabase
|
||||
): JobHandler<REMCycleJobData, REMCycleJobResult> {
|
||||
return async (job: Job<REMCycleJobData>): Promise<REMCycleJobResult> => {
|
||||
const options = {
|
||||
|
|
@ -109,7 +109,7 @@ export function createREMCycleJobHandler(
|
|||
* Useful for testing or showing users potential discoveries
|
||||
*/
|
||||
export async function previewREMCycleJob(
|
||||
db: EngramDatabase,
|
||||
db: VestigeDatabase,
|
||||
maxAnalyze: number = 100
|
||||
): Promise<REMCycleJobResult> {
|
||||
const cycleResult = await runREMCycle(db, {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Jobs Module - Background Job Processing for Engram MCP
|
||||
* Jobs Module - Background Job Processing for Vestige MCP
|
||||
*
|
||||
* This module provides a production-ready job queue system with:
|
||||
* - Priority-based scheduling
|
||||
|
|
@ -18,10 +18,10 @@
|
|||
* createREMCycleJobHandler,
|
||||
* createConsolidationJobHandler,
|
||||
* } from './jobs';
|
||||
* import { EngramDatabase } from './core';
|
||||
* import { VestigeDatabase } from './core';
|
||||
*
|
||||
* // Initialize
|
||||
* const db = new EngramDatabase();
|
||||
* const db = new VestigeDatabase();
|
||||
* const queue = new JobQueue();
|
||||
*
|
||||
* // Register job handlers
|
||||
|
|
|
|||
|
|
@ -423,7 +423,7 @@ export class CacheService<T = unknown> {
|
|||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Standard cache key patterns for Engram MCP.
|
||||
* Standard cache key patterns for Vestige MCP.
|
||||
* These functions generate consistent cache keys for different entity types.
|
||||
*/
|
||||
export const CACHE_KEYS = {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Centralized logging system for Engram MCP
|
||||
* Centralized logging system for Vestige MCP
|
||||
*
|
||||
* Provides structured JSON logging with:
|
||||
* - Log levels (debug, info, warn, error)
|
||||
|
|
@ -161,7 +161,7 @@ export function createLogger(name: string, minLevel: LogLevel = 'info'): Logger
|
|||
|
||||
// Get log level from environment
|
||||
function getLogLevelFromEnv(): LogLevel {
|
||||
const envLevel = process.env['ENGRAM_LOG_LEVEL']?.toLowerCase();
|
||||
const envLevel = process.env['VESTIGE_LOG_LEVEL']?.toLowerCase();
|
||||
if (envLevel && envLevel in LOG_LEVELS) {
|
||||
return envLevel as LogLevel;
|
||||
}
|
||||
|
|
@ -171,7 +171,7 @@ function getLogLevelFromEnv(): LogLevel {
|
|||
const LOG_LEVEL = getLogLevelFromEnv();
|
||||
|
||||
// Root logger
|
||||
export const logger = createLogger('engram', LOG_LEVEL);
|
||||
export const logger = createLogger('vestige', LOG_LEVEL);
|
||||
|
||||
// Pre-configured child loggers for subsystems
|
||||
export const dbLogger = logger.child('database');
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Concurrency utilities for Engram MCP
|
||||
* Concurrency utilities for Vestige MCP
|
||||
*
|
||||
* Provides synchronization primitives for managing concurrent access
|
||||
* to shared resources like database connections.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const os = require('os');
|
|||
const platform = os.platform();
|
||||
const arch = os.arch();
|
||||
|
||||
const binaryName = platform === 'win32' ? 'engram-mcp.exe' : 'engram-mcp';
|
||||
const binaryName = platform === 'win32' ? 'vestige-mcp.exe' : 'vestige-mcp';
|
||||
const binaryPath = path.join(__dirname, '..', 'bin', binaryName);
|
||||
|
||||
const child = spawn(binaryPath, process.argv.slice(2), {
|
||||
|
|
@ -27,12 +27,12 @@ if (!platformStr || !archStr) {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
const binaryName = PLATFORM === 'win32' ? 'engram-mcp.exe' : 'engram-mcp';
|
||||
const binaryName = PLATFORM === 'win32' ? 'vestige-mcp.exe' : 'vestige-mcp';
|
||||
const targetDir = path.join(__dirname, '..', 'bin');
|
||||
const targetPath = path.join(targetDir, binaryName);
|
||||
|
||||
// For now, just create a placeholder - real binaries come from GitHub releases
|
||||
console.log(`Engram MCP v${VERSION} installed for ${archStr}-${platformStr}`);
|
||||
console.log(`Vestige MCP v${VERSION} installed for ${archStr}-${platformStr}`);
|
||||
console.log(`Binary location: ${targetPath}`);
|
||||
|
||||
// Ensure bin directory exists
|
||||
|
|
|
|||
4
pnpm-lock.yaml
generated
4
pnpm-lock.yaml
generated
|
|
@ -14,7 +14,7 @@ importers:
|
|||
|
||||
apps/desktop:
|
||||
dependencies:
|
||||
'@engram/core':
|
||||
'@vestige/core':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/core
|
||||
'@react-three/drei':
|
||||
|
|
@ -167,7 +167,7 @@ importers:
|
|||
specifier: ^5.4.5
|
||||
version: 5.8.3
|
||||
|
||||
packages/engram-mcp-npm: {}
|
||||
packages/vestige-mcp-npm: {}
|
||||
|
||||
packages:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue