/** * EnsembleManager - Implementation of IElementManager for Ensemble elements * * Handles CRUD operations and lifecycle management for ensembles implementing IElement * * ARCHITECTURE: * - Extends BaseElementManager for unified element management * - Follows template method pattern (parseMetadata, createElement hooks) * - Pure manager layer - delegates business logic to Ensemble class * - Uses DI for dependencies (PortfolioManager, FileLockManager) * * SECURITY: * - Uses FileLockManager for atomic file operations * - Path validation prevents directory traversal attacks * - Input sanitization for all user data * - Security event logging for audit trails * - SecureYamlParser for safe YAML parsing */ import { Ensemble, EnsembleMetadata } from './Ensemble.js'; import { ElementValidationResult } from '../../types/elements/IElement.js'; import { BaseElementManager } from '../base/BaseElementManager.js'; import { FileLockManager } from '../../security/fileLockManager.js'; import { PortfolioManager } from '../../portfolio/PortfolioManager.js'; import { ValidationRegistry } from '../../services/validation/ValidationRegistry.js'; import { SerializationService } from '../../services/SerializationService.js'; import { MetadataService } from '../../services/MetadataService.js'; import { FileOperationsService } from '../../services/FileOperationsService.js'; import { FileWatchService } from '../../services/FileWatchService.js'; import { resolveElementTypes } from '../../utils/elementTypeResolver.js'; export { resolveElementTypes, type ElementManagersForResolution } from '../../utils/elementTypeResolver.js'; /** @deprecated Use resolveElementTypes from '../../utils/elementTypeResolver.js' */ export declare const resolveEnsembleElementTypes: typeof resolveElementTypes; /** * EnsembleManager - Manages ensemble element lifecycle * * Extends BaseElementManager to provide ensemble-specific operations: * - YAML parsing with both snake_case and camelCase support * - Ensemble creation and validation * - Element reference management * - Import/export in multiple formats */ export declare class EnsembleManager extends BaseElementManager { private metadataService; private readonly ensemblesDir; private validationService; private serializationService; private activeEnsembleNames; private readonly legacyElementFieldWarnings; constructor(portfolioManager: PortfolioManager, fileLockManager: FileLockManager, fileOperationsService: FileOperationsService, validationRegistry: ValidationRegistry, serializationService: SerializationService, metadataService: MetadataService, fileWatchService?: FileWatchService, memoryBudget?: import('../../cache/CacheMemoryBudget.js').CacheMemoryBudget, backupService?: import('../../services/BackupService.js').BackupService); protected getElementLabel(): string; /** * Clear in-memory warn-once state for legacy ensemble element fields. * * Useful for long-lived processes or tests that intentionally want to * observe the warning path again after a maintenance boundary. */ clearLegacyElementWarningHistory(): void; dispose(): void; /** * Warn once per ensemble/index/field combination when a legacy nested field * is encountered while loading or parsing an ensemble. * * Fingerprinting keeps the warning visible for each distinct legacy field * without re-emitting the same deprecation notice on every re-parse. * * @param ensembleName - Name of the ensemble containing the legacy field * @param index - Zero-based index of the element within the ensemble * @param field - Legacy nested field name that should be migrated */ private warnOnceForLegacyElementField; private hasLegacyElementFields; /** * Rewrite legacy ensemble element field names (`name`/`type`) to the * canonical `element_name`/`element_type` form by loading and resaving * affected ensembles. */ repairLegacyElementFields(): Promise<{ scanned: number; repaired: number; errors: number; repairedEnsembles: Array<{ name: string; path: string; }>; }>; /** * Parse metadata from YAML frontmatter * * NAMING CONVENTION SUPPORT: * - TypeScript interfaces use camelCase (activationStrategy, conflictResolution) * - YAML files can use snake_case (activation_strategy, conflict_resolution) * - This method maps snake_case → camelCase for user convenience * * @param data - Raw YAML data from frontmatter * @returns Validated EnsembleMetadata */ protected parseMetadata(data: any): Promise; /** * Create an Ensemble instance from parsed metadata * * @param metadata - Validated ensemble metadata * @param content - Markdown content (ensemble instructions/documentation) * @returns New Ensemble instance */ protected createElement(metadata: EnsembleMetadata, _content: string): Ensemble; /** * Serialize an ensemble to file content * * Format: Markdown with YAML frontmatter * - Frontmatter: Ensemble metadata + element references * - Content: Instructions/documentation for the ensemble * * @param element - Ensemble to serialize * @returns File content (markdown with frontmatter) */ protected serializeElement(element: Ensemble): Promise; private buildDefaultBody; /** * Get file extension for ensemble files */ getFileExtension(): string; /** * Import an ensemble from external format * * Supports: * - YAML: Frontmatter-style metadata with optional markdown content * - JSON: Direct ensemble structure * - Markdown: YAML frontmatter + markdown content * * @param data - String containing ensemble data * @param format - Format of the data (json, yaml, markdown) * @returns Promise resolving to imported Ensemble */ importElement(data: string, format?: 'json' | 'yaml' | 'markdown'): Promise; /** * Export an ensemble to external format * * @param element - Ensemble to export * @param format - Output format (json, yaml, markdown) * @returns Promise resolving to serialized string */ exportElement(element: Ensemble, format?: 'json' | 'yaml' | 'markdown'): Promise; /** * Create a new ensemble with metadata * * @param metadata - Partial metadata for the ensemble * @returns Promise resolving to new Ensemble instance */ create(metadata: Partial & { instructions?: string; content?: string; }): Promise; /** * Validate an ensemble * Delegates to ensemble's own validate method * * @param element - Ensemble to validate * @returns Validation result */ validate(element: Ensemble): ElementValidationResult; /** * Override save to validate before persisting */ save(element: Ensemble, filePath: string): Promise; /** * Override delete to add ensemble-specific logging */ delete(filePath: string): Promise; /** * Override list to apply active status based on activeEnsembleNames set */ list(): Promise; /** * Activate an ensemble by name or identifier * * Issue #24 (LOW PRIORITY): Performance optimization using findByName() * Issue #24 (LOW PRIORITY): Consistent error messages using ElementMessages * Issue #24 (LOW PRIORITY): Cleanup trigger for memory leak prevention * * @param identifier - Ensemble name or identifier * @returns Activation result with success status and message */ activateEnsemble(identifier: string): Promise<{ success: boolean; message: string; ensemble?: Ensemble; }>; /** * Deactivate an ensemble by name or identifier * * Issue #24 (LOW PRIORITY): Performance optimization using findByName() * Issue #24 (LOW PRIORITY): Consistent error messages using ElementMessages * * @param identifier - Ensemble name or identifier * @returns Deactivation result with success status and message */ deactivateEnsemble(identifier: string): Promise<{ success: boolean; message: string; ensemble?: Ensemble; }>; /** * Get all active ensembles * * @returns List of active ensembles */ getActiveEnsembles(): Promise; /** * Check if active set cleanup is needed and perform cleanup if necessary * Issue #24 (LOW PRIORITY): Memory leak prevention * @private */ private checkAndCleanupActiveSet; /** * Clean up stale entries from active ensembles set * Issue #24 (LOW PRIORITY): Memory leak prevention * @private */ private cleanupStaleActiveEnsembles; } //# sourceMappingURL=EnsembleManager.d.ts.map