Skip to main content
Glama

Memory Bank MCP

ModeManager.ts5.48 kB
import { EventEmitter } from 'events'; import { ClineruleBase, ExternalRulesLoader } from './ExternalRulesLoader.js'; /** * Events emitted by ModeManager */ export enum ModeManagerEvent { MODE_CHANGED = 'modeChanged', MODE_TRIGGER_DETECTED = 'modeTriggerDetected', UMB_TRIGGERED = 'umbTriggered', UMB_COMPLETED = 'umbCompleted', } /** * Interface to represent the current mode state */ export interface ModeState { name: string; rules: ClineruleBase | null; isUmbActive: boolean; memoryBankStatus: 'ACTIVE' | 'INACTIVE'; } /** * Class responsible for managing modes based on loaded rules */ export class ModeManager extends EventEmitter { private rulesLoader: ExternalRulesLoader; private currentMode: string = 'code'; // Default mode private isUmbActive: boolean = false; private memoryBankStatus: 'ACTIVE' | 'INACTIVE' = 'INACTIVE'; /** * Creates a new instance of the mode manager * @param rulesLoader External rules loader */ constructor(rulesLoader: ExternalRulesLoader) { super(); this.rulesLoader = rulesLoader; // Set up listener for rule changes this.rulesLoader.on('ruleChanged', (mode, rule) => { if (mode === this.currentMode) { this.emit(ModeManagerEvent.MODE_CHANGED, this.getCurrentModeState()); } }); } /** * Initializes the mode manager * @param initialMode Initial mode (optional) */ async initialize(initialMode?: string): Promise<void> { await this.rulesLoader.detectAndLoadRules(); if (initialMode && this.rulesLoader.hasModeRules(initialMode)) { this.currentMode = initialMode; } else { // Use the first available mode or keep the default const availableModes = this.rulesLoader.getAvailableModes(); if (availableModes.length > 0) { this.currentMode = availableModes[0]; } } this.emit(ModeManagerEvent.MODE_CHANGED, this.getCurrentModeState()); } /** * Gets the current mode state * @returns Current mode state */ getCurrentModeState(): ModeState { return { name: this.currentMode, rules: this.rulesLoader.getRulesForMode(this.currentMode), isUmbActive: this.isUmbActive, memoryBankStatus: this.memoryBankStatus, }; } /** * Switches to a specific mode * @param mode Mode name * @returns true if the switch was successful, false otherwise */ switchMode(mode: string): boolean { if (!this.rulesLoader.hasModeRules(mode)) { return false; } this.currentMode = mode; this.emit(ModeManagerEvent.MODE_CHANGED, this.getCurrentModeState()); return true; } /** * Checks if a text matches the UMB trigger * @param text Text to check * @returns true if the text matches the UMB trigger, false otherwise */ checkUmbTrigger(text: string): boolean { const currentRules = this.rulesLoader.getRulesForMode(this.currentMode); if (!currentRules || !currentRules.instructions.umb || !currentRules.instructions.umb.trigger) { return false; } const triggerRegex = new RegExp(currentRules.instructions.umb.trigger, 'i'); return triggerRegex.test(text); } /** * Activates the UMB mode * @returns true if the activation was successful, false otherwise */ activateUmb(): boolean { const currentRules = this.rulesLoader.getRulesForMode(this.currentMode); if (!currentRules || !currentRules.instructions.umb) { return false; } this.isUmbActive = true; this.emit(ModeManagerEvent.UMB_TRIGGERED, this.getCurrentModeState()); return true; } /** * Deactivates the UMB mode */ deactivateUmb(): void { this.isUmbActive = false; this.emit(ModeManagerEvent.UMB_COMPLETED, this.getCurrentModeState()); } /** * Checks if a text matches any mode trigger * @param text Text to check * @returns Array with the modes corresponding to the found triggers */ checkModeTriggers(text: string): string[] { const triggeredModes: string[] = []; const currentRules = this.rulesLoader.getRulesForMode(this.currentMode); if (!currentRules || !currentRules.mode_triggers) { return triggeredModes; } // Check triggers for each mode for (const [mode, triggers] of Object.entries(currentRules.mode_triggers)) { if (this.rulesLoader.hasModeRules(mode)) { for (const trigger of triggers) { if (text.includes(trigger.condition)) { triggeredModes.push(mode); break; // One trigger is enough for each mode } } } } if (triggeredModes.length > 0) { this.emit(ModeManagerEvent.MODE_TRIGGER_DETECTED, triggeredModes); } return triggeredModes; } /** * Sets the Memory Bank status * @param status New status */ setMemoryBankStatus(status: 'ACTIVE' | 'INACTIVE'): void { this.memoryBankStatus = status; this.emit(ModeManagerEvent.MODE_CHANGED, this.getCurrentModeState()); } /** * Gets the status prefix for responses * @returns Status prefix */ getStatusPrefix(): string { return `[MEMORY BANK: ${this.memoryBankStatus}]`; } /** * Checks if the UMB mode is active * @returns true if the UMB mode is active, false otherwise */ isUmbModeActive(): boolean { return this.isUmbActive; } /** * Cleans up all resources */ dispose(): void { this.removeAllListeners(); } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/movibe/memory-bank-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server