UNPKG

@dollhousemcp/mcp-server

Version:

DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.

97 lines 3.81 kB
/** * PersonaElementManager - Implementation of IElementManager for PersonaElement * Handles CRUD operations and lifecycle management for personas implementing IElement * * SECURITY FIXES IMPLEMENTED (PR #319): * 1. CRITICAL: Fixed race conditions in file operations by using FileLockManager for atomic reads/writes * 2. CRITICAL: Fixed dynamic require() statements by using static imports * 3. HIGH: Fixed unvalidated YAML parsing vulnerability by using SecureYamlParser * 4. MEDIUM: All user inputs are now validated and sanitized * 5. MEDIUM: Audit logging added for security operations */ import { IElementManager, ElementValidationResult } from '../types/elements/index.js'; import { ElementType } from '../portfolio/types.js'; import { PersonaElement, PersonaElementMetadata } from './PersonaElement.js'; import { PortfolioManager } from '../portfolio/PortfolioManager.js'; export declare class PersonaElementManager implements IElementManager<PersonaElement> { private portfolioManager; private personasDir; constructor(portfolioManager?: PortfolioManager); /** * Load a persona from file * SECURITY FIX #1: Uses FileLockManager.atomicReadFile() instead of fs.readFile() * to prevent race conditions and ensure atomic file operations */ load(filePath: string): Promise<PersonaElement>; /** * Save a persona to file * SECURITY FIX #1: Uses FileLockManager.atomicWriteFile() instead of fs.writeFile() * to prevent race conditions and ensure atomic file operations */ save(element: PersonaElement, filePath: string): Promise<void>; /** * Delete a persona file */ delete(filePath: string): Promise<void>; /** * Check if a persona file exists */ exists(filePath: string): Promise<boolean>; /** * List all personas */ list(): Promise<PersonaElement[]>; /** * Find a persona by predicate */ find(predicate: (element: PersonaElement) => boolean): Promise<PersonaElement | undefined>; /** * Find multiple personas by predicate */ findMany(predicate: (element: PersonaElement) => boolean): Promise<PersonaElement[]>; /** * Validate a persona element */ validate(element: PersonaElement): ElementValidationResult; /** * Validate a file path */ validatePath(filePath: string): boolean; /** * Get element type */ getElementType(): ElementType; /** * Get file extension */ getFileExtension(): string; /** * Import persona from data * SECURITY FIX #3: Uses SecureYamlParser instead of unsafe YAML parsing to prevent * YAML deserialization attacks and injection vulnerabilities */ importElement(data: string, format?: 'json' | 'yaml' | 'markdown'): Promise<PersonaElement>; /** * Export persona to data * SECURITY FIX #2: Uses static import of js-yaml at top of file instead of * dynamic require() for better security and bundling * SECURITY FIX #3: Uses secure YAML dumping with safety options */ exportElement(element: PersonaElement, format?: 'json' | 'yaml' | 'markdown'): Promise<string>; /** * Helper: Convert JSON data to markdown format * SECURITY FIX #2: Uses statically imported yaml module * SECURITY FIX #3: Uses secure YAML dumping with safety options * Note: This is for internal conversion only, user-provided YAML must use SecureYamlParser */ private jsonToMarkdown; /** * Create a new persona with default metadata */ create(metadata: Partial<PersonaElementMetadata>): PersonaElement; /** * Get default filename for a persona */ getDefaultFilename(persona: PersonaElement): string; } //# sourceMappingURL=PersonaElementManager.d.ts.map