memory-engineering-mcp
Version:
🧠AI Memory System powered by MongoDB Atlas & Voyage AI - Autonomous memory management with zero manual work
117 lines • 4.26 kB
JavaScript
/**
* Auto-initialization utility
* Silently initializes projects on first use - no blocking, no health checks
* Inspired by Cipher MCP's seamless approach
*/
import { join, basename } from 'path';
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
import { createHash } from 'crypto';
import { logger } from './logger.js';
import { getMemoryCollection, getDb } from '../db/connection.js';
import { ensureAllIndexes } from './auto-index-manager.js';
const MEMORY_ENGINEERING_DIR = '.memory-engineering';
const CONFIG_FILE = 'config.json';
function generateProjectId(projectPath) {
return createHash('md5').update(projectPath).digest('hex').substring(0, 8) +
'-' +
createHash('md5').update(projectPath).digest('hex').substring(8, 12) +
'-' +
createHash('md5').update(projectPath).digest('hex').substring(12, 16) +
'-' +
createHash('md5').update(projectPath).digest('hex').substring(16, 20) +
'-' +
createHash('md5').update(projectPath).digest('hex').substring(20, 32);
}
function detectProjectName(projectPath) {
// Try package.json first
try {
const packageJsonPath = join(projectPath, 'package.json');
if (existsSync(packageJsonPath)) {
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
if (pkg.name) {
return pkg.name;
}
}
}
catch (e) {
// Silent fail, use directory name
}
// Fallback to directory name
const dirName = basename(projectPath);
return dirName || 'Project';
}
/**
* Silently ensures project is initialized
* Called automatically before any operation that needs project context
* NO health checks, NO blocking - just creates config if needed
*/
export async function ensureProjectInitialized(projectPath) {
const memoryDir = join(projectPath, MEMORY_ENGINEERING_DIR);
const configPath = join(memoryDir, CONFIG_FILE);
// Check if already initialized
if (existsSync(configPath)) {
try {
const existingConfig = JSON.parse(readFileSync(configPath, 'utf-8'));
logger.debug('Project already initialized', { projectId: existingConfig.projectId });
return {
success: true,
projectId: existingConfig.projectId,
isNewProject: false,
config: existingConfig
};
}
catch (e) {
logger.warn('Config file corrupted, recreating...', { error: e });
}
}
// Auto-initialize (silent, fast)
logger.info('Auto-initializing project...', { projectPath });
// Create directory
if (!existsSync(memoryDir)) {
mkdirSync(memoryDir, { recursive: true });
}
// Generate project ID and config
const projectId = generateProjectId(projectPath);
const projectName = detectProjectName(projectPath);
const config = {
projectId,
projectPath,
name: projectName,
createdAt: new Date(),
memoryVersion: '5.0'
};
// Write config
writeFileSync(configPath, JSON.stringify(config, null, 2));
// Try to create indexes in background (don't block if it fails)
try {
const memoryCollection = getMemoryCollection();
const codeCollection = getDb().collection('memory_engineering_code');
await ensureAllIndexes(memoryCollection, codeCollection);
}
catch (e) {
logger.warn('Index creation failed (non-blocking)', { error: e });
// Don't fail initialization if indexes fail
}
logger.info('✅ Project auto-initialized', { projectId, projectName });
return {
success: true,
projectId,
isNewProject: true,
config
};
}
/**
* Get project config (auto-initializes if needed)
*/
export async function getProjectConfig(projectPath) {
const result = await ensureProjectInitialized(projectPath);
return result.config;
}
/**
* Check if project is initialized (without auto-initializing)
*/
export function isProjectInitialized(projectPath) {
const configPath = join(projectPath, MEMORY_ENGINEERING_DIR, CONFIG_FILE);
return existsSync(configPath);
}
//# sourceMappingURL=auto-init.js.map