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:
Sam Valladares 2026-01-25 01:44:11 -06:00
parent d9b762030e
commit 449d60754a
27 changed files with 277 additions and 277 deletions

View file

@ -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', () => {

View file

@ -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', () => {

View file

@ -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(() => {

View file

@ -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

View file

@ -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.
`);
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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

View file

@ -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'
);

View file

@ -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,

View file

@ -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));
}
}

View file

@ -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);
}

View file

@ -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)}`);
}

View file

@ -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

View file

@ -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',
},
});

View file

@ -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);
});

View file

@ -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;

View file

@ -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 });

View file

@ -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

View file

@ -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, {

View file

@ -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

View file

@ -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 = {

View file

@ -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');

View file

@ -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.

View file

@ -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), {

View file

@ -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
View file

@ -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: