UNPKG

vibe-coder-mcp

Version:

Production-ready MCP server with complete agent integration, multi-transport support, and comprehensive development automation tools for AI-assisted workflows.

121 lines (120 loc) 4.08 kB
import { TieredCache } from './tieredCache.js'; import logger from '../../../logger.js'; import crypto from 'crypto'; import fs from 'fs/promises'; import path from 'path'; export class MetadataCache { cache; name; constructor(options) { this.name = options.name; this.cache = new TieredCache({ name: options.name, cacheDir: options.cacheDir, maxEntries: options.maxEntries || 10000, maxAge: options.maxAge || 24 * 60 * 60 * 1000, useMemoryCache: options.useMemoryCache !== false, memoryMaxEntries: options.memoryMaxEntries || 5000, memoryMaxAge: options.memoryMaxAge || 60 * 60 * 1000, memoryThreshold: options.memoryThreshold || 0.5, serialize: (metadata) => { if (metadata && typeof metadata === 'object' && 'content' in metadata && metadata.content) { const { content: _content, ...rest } = metadata; void _content; return JSON.stringify(rest); } return JSON.stringify(metadata); }, deserialize: (serialized) => { return JSON.parse(serialized); } }); } async init() { await this.cache.init(); logger.info(`Initialized ${this.name} metadata cache`); } async get(key) { return this.cache.get(key); } async set(key, value) { await this.cache.set(key, value); } async has(key) { return this.cache.has(key); } async delete(key) { await this.cache.delete(key); } async clear() { await this.cache.clear(); } getStats() { return this.cache.getStats(); } static async createSourceCodeMetadata(filePath, content, stats) { if (!content) { try { content = await fs.readFile(filePath, 'utf-8'); } catch (error) { logger.error({ err: error, filePath }, 'Error reading file for metadata creation'); throw error; } } if (!stats) { try { stats = await fs.stat(filePath); } catch (error) { logger.error({ err: error, filePath }, 'Error getting file stats for metadata creation'); throw error; } } const hash = crypto.createHash('md5').update(content).digest('hex'); return { filePath, hash, size: stats.size, lastModified: stats.mtimeMs, language: path.extname(filePath).toLowerCase(), processed: false, content }; } static createASTMetadata(filePath, sourceHash, rootNode) { return { filePath, sourceHash, rootType: rootNode.type, rootStartByte: rootNode.startByte, rootEndByte: rootNode.endByte, structure: MetadataCache.extractMinimalStructure(rootNode) || undefined }; } static extractMinimalStructure(node, options = {}) { const maxDepth = options.maxDepth || 3; const maxChildren = options.maxChildren || 10; function extract(node, depth) { if (!node || depth > maxDepth) { return null; } const result = { type: node.type, startByte: node.startByte, endByte: node.endByte }; if (node.children && node.children.length > 0) { result.children = node.children .slice(0, maxChildren) .map((child) => extract(child, depth + 1)) .filter((child) => child !== null); if (node.children.length > maxChildren) { result.childrenCount = node.children.length; } } return result; } return extract(node, 0); } }