UNPKG

@andrebuzeli/advanced-memory-markdown-mcp

Version:

Advanced Memory Bank MCP v3.1.5 - Sistema avançado de gerenciamento de memória com isolamento de projetos por IDE, sincronização sob demanda, backup a cada 30min, apenas arquivos .md principais sincronizados, pasta reasoning temporária com limpeza automát

291 lines 11.3 kB
/** * Plan Manager v2.0 - Gerencia planejamentos estratégicos em arquivos markdown * * IMPORTANTE - NOME DO PROJETO: * - O projectName DEVE ser exatamente o nome da pasta RAIZ do projeto aberto no IDE * - NÃO é uma subpasta, NÃO é um subprojeto - é a pasta raiz que foi aberta no IDE * - O nome deve ser uma cópia EXATA sem adicionar ou remover nada * * RESPONSABILIDADE - PLANEJAMENTO ESTRATÉGICO: * - Roadmaps de projeto e releases * - Planejamento de sprints e milestones * - Objetivos estratégicos e metas * - Cronogramas e deadlines * - Planejamento de recursos e capacidade * - Visão de alto nível do projeto * * Funcionalidades v2.0: * - Operações individuais e múltiplas em planos * - Criação e gerenciamento de planos estratégicos * - Sistema de prioridades e status temporal * - Armazenamento em plan.md no MEMORY_BANK_ROOT * - Tags e categorização por objetivos * - Sincronização automática com pasta .memory-bank local */ import * as fs from 'fs/promises'; import { SyncManager } from './sync-manager.js'; export class PlanManager { syncManager; constructor() { this.syncManager = new SyncManager(); } /** * Creates a new plan */ async create(projectName, name, description, priority = 5, tags = []) { // Ensure project structure exists await this.syncManager.ensureProjectStructure(projectName); const planFile = this.syncManager.getProjectFilePath(projectName, 'plan.md'); const plan = { id: this.generatePlanId(), name, description, priority: Math.max(1, Math.min(10, priority)), status: 'pending', tags, created: Date.now(), modified: Date.now() }; await this.addPlanToFile(planFile, plan); return plan; } /** * Reads a specific plan */ async read(projectName, planId) { const plans = await this.list(projectName); return plans.find(plan => plan.id === planId) || null; } /** * Updates a plan */ async update(projectName, planId, updates) { const planFile = this.syncManager.getProjectFilePath(projectName, 'plan.md'); const plans = await this.loadPlansFromFile(planFile); const planIndex = plans.findIndex(plan => plan.id === planId); if (planIndex === -1) return null; const updatedPlan = { ...plans[planIndex], ...updates, modified: Date.now() }; plans[planIndex] = updatedPlan; await this.savePlansToFile(planFile, plans); return updatedPlan; } /** * Deletes a plan */ async delete(projectName, planId) { const planFile = this.syncManager.getProjectFilePath(projectName, 'plan.md'); const plans = await this.loadPlansFromFile(planFile); const filteredPlans = plans.filter(plan => plan.id !== planId); if (filteredPlans.length === plans.length) return false; await this.savePlansToFile(planFile, filteredPlans); return true; } /** * Lists all plans for a project */ async list(projectName) { const planFile = this.syncManager.getProjectFilePath(projectName, 'plan.md'); return await this.loadPlansFromFile(planFile); } // ========== OPERAÇÕES MÚLTIPLAS v2.0 ========== /** * Creates multiple plans at once */ async createMultiple(projectName, plans) { await this.syncManager.ensureProjectStructure(projectName); const planFile = this.syncManager.getProjectFilePath(projectName, 'plan.md'); const existingPlans = await this.loadPlansFromFile(planFile); const createdPlans = []; for (const planData of plans) { const plan = { id: this.generatePlanId(), name: planData.name, description: planData.description, created: Date.now(), modified: Date.now(), status: 'pending', priority: planData.priority || 5, tags: planData.tags || [] }; existingPlans.push(plan); createdPlans.push(plan); } await this.savePlansToFile(planFile, existingPlans); return createdPlans; } /** * Reads multiple plans at once */ async readMultiple(projectName, planIds) { const planFile = this.syncManager.getProjectFilePath(projectName, 'plan.md'); const plans = await this.loadPlansFromFile(planFile); return planIds.map(planId => plans.find(plan => plan.id === planId) || null); } /** * Updates multiple plans at once */ async updateMultiple(projectName, updates) { const planFile = this.syncManager.getProjectFilePath(projectName, 'plan.md'); const plans = await this.loadPlansFromFile(planFile); const updatedPlans = []; for (const updateData of updates) { const planIndex = plans.findIndex(plan => plan.id === updateData.planId); if (planIndex !== -1) { const updatedPlan = { ...plans[planIndex], ...updateData.updates, modified: Date.now() }; plans[planIndex] = updatedPlan; updatedPlans.push(updatedPlan); } else { updatedPlans.push(null); } } await this.savePlansToFile(planFile, plans); return updatedPlans; } /** * Deletes multiple plans at once */ async deleteMultiple(projectName, planIds) { const planFile = this.syncManager.getProjectFilePath(projectName, 'plan.md'); const plans = await this.loadPlansFromFile(planFile); const results = []; for (const planId of planIds) { const initialLength = plans.length; const filteredPlans = plans.filter(plan => plan.id !== planId); if (filteredPlans.length < initialLength) { results.push(true); // Update the plans array for next iteration plans.splice(0, plans.length, ...filteredPlans); } else { results.push(false); } } await this.savePlansToFile(planFile, plans); return results; } /** * Generates a unique plan ID */ generatePlanId() { return `PLAN-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; } /** * Adds a plan to the planning.md file */ async addPlanToFile(filePath, plan) { const plans = await this.loadPlansFromFile(filePath); plans.push(plan); await this.savePlansToFile(filePath, plans); } /** * Loads plans from planning.md file */ async loadPlansFromFile(filePath) { try { const content = await fs.readFile(filePath, 'utf8'); const plans = []; // Parse markdown content to extract plans const lines = content.split('\n'); let currentPlan = null; let inPlanSection = false; for (const line of lines) { if (line.startsWith('## Planos') || line.startsWith('## Planejamentos')) { inPlanSection = true; continue; } if (inPlanSection && line.startsWith('---')) { break; } if (inPlanSection && line.startsWith('### ')) { // Save previous plan if exists if (currentPlan && currentPlan.id) { plans.push(currentPlan); } // Start new plan const planMatch = line.match(/### (.+) \(ID: (.+)\)/); if (planMatch && planMatch[1] && planMatch[2]) { currentPlan = { id: planMatch[2], name: planMatch[1] }; } } if (currentPlan && inPlanSection) { if (line.startsWith('**Descrição:**')) { currentPlan.description = line.replace('**Descrição:**', '').trim(); } else if (line.startsWith('**Status:**')) { currentPlan.status = line.replace('**Status:**', '').trim(); } else if (line.startsWith('**Prioridade:**')) { currentPlan.priority = parseInt(line.replace('**Prioridade:**', '').trim()); } else if (line.startsWith('**Tags:**')) { const tagsStr = line.replace('**Tags:**', '').trim(); currentPlan.tags = tagsStr ? tagsStr.split(', ') : []; } else if (line.startsWith('**Criado:**')) { currentPlan.created = parseInt(line.replace('**Criado:**', '').trim()); } else if (line.startsWith('**Modificado:**')) { currentPlan.modified = parseInt(line.replace('**Modificado:**', '').trim()); } } } // Save last plan if exists if (currentPlan && currentPlan.id) { plans.push(currentPlan); } return plans; } catch { return []; } } /** * Saves plans to planning.md file */ async savePlansToFile(filePath, plans) { try { const content = await fs.readFile(filePath, 'utf8'); const lines = content.split('\n'); // Find the plans section const plansIndex = lines.findIndex(line => line.startsWith('## Planos') || line.startsWith('## Planejamentos')); const endIndex = lines.findIndex((line, index) => index > plansIndex && line.startsWith('---')); if (plansIndex === -1) return; // Build new plans section const newPlansSection = ['## Planos', '']; if (plans.length === 0) { newPlansSection.push('<!-- Nenhum plano criado ainda -->', ''); } else { for (const plan of plans) { newPlansSection.push(`### ${plan.name} (ID: ${plan.id})`, `**Descrição:** ${plan.description}`, `**Status:** ${plan.status}`, `**Prioridade:** ${plan.priority}`, `**Tags:** ${plan.tags.join(', ')}`, `**Criado:** ${plan.created}`, `**Modificado:** ${plan.modified}`, ''); } } // Replace the plans section const newLines = [ ...lines.slice(0, plansIndex), ...newPlansSection, ...lines.slice(endIndex) ]; await fs.writeFile(filePath, newLines.join('\n'), 'utf8'); } catch (error) { console.error('Error saving plans to file:', error); } } } //# sourceMappingURL=plan-manager.js.map