UNPKG

mongodb-memory-bank-mcp

Version:

FIXED: MongoDB Memory Bank MCP with bulletproof error handling, smart operations, and session state management. Eliminates [object Object] errors and user confusion.

155 lines (154 loc) 6.62 kB
import { getTemplate, TEMPLATE_HIERARCHY } from '../../../domain/entities/memory-templates.js'; /** * Implementation of structured memory storage use case * Combines universal project detection with structured template validation * Perfect harmony with existing MongoDB memory system */ export class MemoryStoreStructuredImpl { memoryRepository; projectContextDetection; constructor(memoryRepository, projectContextDetection) { this.memoryRepository = memoryRepository; this.projectContextDetection = projectContextDetection; } async execute(params) { // 1. Detect project context using existing universal detection const projectContext = await this.projectContextDetection.detectProjectContext({ forceDetection: params.forceDetection, validateIsolation: params.validateIsolation, workingDirectory: params.workingDirectory, preferredProjectName: params.preferredProjectName }); const projectName = params.projectName || projectContext.result?.projectName || 'unknown-project'; // 2. Validate content against template const validation = await this.memoryRepository.validateTemplate(params.content, params.memoryType, params.fileName); // 3. Generate relationships based on template dependencies const relationships = await this.generateRelationships(params.memoryType, projectName, params.fileName); // 4. Create structured memory object const template = getTemplate(params.memoryType); const structuredMemory = { projectName, fileName: params.fileName, content: params.content, tags: this.generateTags(params.content, params.memoryType), lastModified: new Date(), wordCount: this.countWords(params.content), memoryType: params.memoryType, templateVersion: template.version, relationships, structuredData: {} }; // 5. Store the structured memory const storedMemory = await this.memoryRepository.storeStructured(structuredMemory); return { memory: storedMemory, validation, projectContext: { projectName: projectContext.result?.projectName || 'unknown-project', detectionMethod: projectContext.result?.detectionMethod || 'hybrid', confidence: projectContext.result?.confidence || 0.5, isNewProject: !projectContext.result?.existsInMemoryBank } }; } /** * Generate relationships based on template dependencies and existing memories */ async generateRelationships(memoryType, projectName, fileName) { const template = getTemplate(memoryType); const hierarchyLevel = TEMPLATE_HIERARCHY[memoryType]; // Get existing memories to establish relationships const existingMemories = await this.memoryRepository.listByProject(projectName); const dependsOn = []; const influences = []; const relatedTo = []; // Add template-defined dependencies for (const depType of template.relationships.requiredDependencies) { const depMemory = existingMemories.find(m => m.memoryType === depType || m.fileName === `${depType}.md`); if (depMemory) { dependsOn.push(depMemory.fileName); } } // Add optional dependencies if they exist for (const depType of template.relationships.optionalDependencies) { const depMemory = existingMemories.find(m => m.memoryType === depType || m.fileName === `${depType}.md`); if (depMemory) { relatedTo.push(depMemory.fileName); } } // Add influences based on template relationships for (const influenceType of template.relationships.influences) { const influenceMemory = existingMemories.find(m => m.memoryType === influenceType || m.fileName === `${influenceType}.md`); if (influenceMemory) { influences.push(influenceMemory.fileName); } } // Add hierarchical relationships const lowerLevelMemories = existingMemories.filter(m => { const memoryLevel = m.memoryType ? TEMPLATE_HIERARCHY[m.memoryType] : 1; return memoryLevel > hierarchyLevel; }); for (const memory of lowerLevelMemories) { if (!influences.includes(memory.fileName)) { influences.push(memory.fileName); } } return { dependsOn, influences, relatedTo, hierarchyLevel }; } /** * Generate tags for structured memory */ generateTags(content, memoryType) { const template = getTemplate(memoryType); const baseTags = [ memoryType, 'structured', `template-v${template.version}`, `hierarchy-${TEMPLATE_HIERARCHY[memoryType]}` ]; // Extract content-based tags const contentTags = this.extractContentTags(content); // Combine and deduplicate const allTags = [...baseTags, ...contentTags]; return [...new Set(allTags)].slice(0, 12); // Limit to 12 tags } /** * Extract tags from content */ extractContentTags(content) { const tags = []; const words = content.toLowerCase().match(/\b\w{3,}\b/g) || []; // Common technical terms const techTerms = [ 'api', 'database', 'mongodb', 'react', 'node', 'typescript', 'javascript', 'architecture', 'pattern', 'design', 'implementation', 'testing', 'deployment', 'security', 'performance', 'scalability', 'microservice', 'frontend', 'backend' ]; for (const term of techTerms) { if (words.includes(term)) { tags.push(term); } } // Extract section-based tags const sections = content.match(/^#+\s+(.+)$/gm) || []; for (const section of sections) { const sectionName = section.replace(/^#+\s+/, '').toLowerCase(); const tag = sectionName.replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, ''); if (tag.length > 2) { tags.push(tag); } } return tags.slice(0, 8); // Limit content tags } /** * Count words in content */ countWords(content) { return content.trim().split(/\s+/).length; } }