@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.
282 lines • 10.5 kB
TypeScript
/**
* Enhanced Index Manager - Persistent YAML index with extensible schema
*
* Features:
* - Extensible schema supporting arbitrary element types and metadata
* - Persistent YAML storage for human readability
* - Incremental updates without full regeneration
* - Backward compatible with schema evolution
* - Server-side semantic intelligence
*
* This manager creates and maintains a capability index that enables:
* - Verb-based action triggers
* - Cross-element relationships
* - Semantic scoring with Jaccard/entropy
* - Context-aware element discovery
*
* FIXES IMPLEMENTED (Issue #1099):
* - Uses centralized element ID parsing utilities
* - Consistent ID format handling throughout
*/
import { PortfolioIndexManager } from './PortfolioIndexManager.js';
import { NLPScoringManager } from './NLPScoringManager.js';
import { VerbTriggerManager } from './VerbTriggerManager.js';
import { ConfigManager } from '../config/ConfigManager.js';
import { IndexConfigManager } from './config/IndexConfig.js';
import { RelationshipManager } from './RelationshipManager.js';
import { FileOperationsService } from '../services/FileOperationsService.js';
import { EnhancedIndexHelpers } from './enhanced-index/EnhancedIndexHelpers.js';
import { EnhancedIndex, IndexMetadata, ElementDefinition, UseWhenPattern, Relationship, SemanticData, ContextTracking, KeywordTracking, RelationshipTracking, ScoringConfig, IndexOptions, ElementPath } from './types/IndexTypes.js';
export type { EnhancedIndex, IndexMetadata, ElementDefinition, UseWhenPattern, Relationship, SemanticData, ContextTracking, KeywordTracking, RelationshipTracking, ScoringConfig, IndexOptions, ElementPath };
export declare class EnhancedIndexManager {
private index;
private indexPath;
private lastLoaded;
private TTL_MS;
private isBuilding;
private nlpScoring;
private verbTriggers;
private relationshipManager;
private config;
private readonly configManager;
private readonly portfolioIndexManager;
private fileLock;
private memoryCleanupInterval;
private lastMemoryCleanup;
private readonly elementDefinitionBuilder;
private readonly actionTriggerExtractor;
private readonly metricsTracker;
private readonly semanticRelationshipService;
private readonly fileOperations;
private readonly METRICS_BATCH_SIZE;
private readonly METRICS_FLUSH_INTERVAL;
private static readonly MAX_METRICS_CACHE_SIZE;
private static readonly MAX_METRICS_CACHE_MEMORY_MB;
constructor(indexConfigManager: IndexConfigManager, configManager: ConfigManager, portfolioIndexManager: PortfolioIndexManager, nlpScoringManager: NLPScoringManager, verbTriggerManager: VerbTriggerManager, relationshipManager: RelationshipManager, helpers: EnhancedIndexHelpers, fileOperations: FileOperationsService);
dispose(): Promise<void>;
/**
* Get the current index, loading or building as needed
*/
getIndex(options?: IndexOptions): Promise<EnhancedIndex>;
/**
* Load index from YAML file
*/
private loadIndex;
/**
* Build or rebuild the index from portfolio
*/
private buildIndex;
private static VERB_EXTRACTION_CONFIG;
private static VERB_PREFIX_PATTERN;
private static VERB_SUFFIX_PATTERN;
private static NOUN_SUFFIX_PATTERN;
private getTriggerPatterns;
/**
* Extract action triggers from element definition
*
* FIX: Enhanced verb extraction from multiple sources
* Previously: Only checked elementDef.actions which personas don't have
* Now: Checks search.triggers (personas), actions field, and keywords
*
* Security improvements:
* - Added trigger count limits
* - Added trigger length validation
* - Using Sets for O(1) duplicate checking
* - Pre-compiled regex patterns
*
* Future enhancements:
* - Background deep content analysis for dynamic verb extraction
* - This could scan element descriptions and content to find action words
* - Would run asynchronously to avoid blocking main operations
* - Results would progressively enhance the index over time
*/
private extractActionTriggers;
/**
* Add a trigger to element mapping
* Preserves original element name casing for proper resolution
*
* Note: Triggers are persisted in the index file under action_triggers
* Usage metrics are tracked via trackTriggerUsage() and can be retrieved with getTriggerMetrics()
*/
private addTriggerMapping;
/**
* Load enhanced index configuration from ConfigManager
*/
private loadEnhancedIndexConfig;
/**
* Compile and validate a regex pattern
* Provides clear error messages if pattern is invalid
*/
private compileAndValidateRegex;
/**
* Validate all regex patterns at startup
* Ensures patterns are valid and can handle expected input
*/
private validateRegexPatterns;
/**
* Telemetry tracking infrastructure
*/
private telemetryMetrics;
private telemetryTimer;
/**
* Start telemetry tracking for an operation
*/
private startTelemetry;
/**
* Record telemetry metrics for an operation
*/
private recordTelemetry;
/**
* Check if telemetry is enabled
*/
private isTelemetryEnabled;
/**
* Schedule periodic telemetry reporting
*/
private scheduleTelemetryReport;
/**
* Report aggregated telemetry metrics
*/
private reportTelemetry;
/**
* Write index data to YAML file on disk
* Private implementation detail
*/
private writeToFile;
/**
* Check if index needs rebuilding
*/
private needsRebuild;
/**
* Update specific elements in the index
*/
updateElements(elementNames: string[], options?: IndexOptions): Promise<void>;
/**
* Add or update a relationship between elements
*/
addRelationship(fromElement: string, toElement: string, relationship: Relationship): Promise<void>;
/**
* Add custom extension data
*/
addExtension(key: string, data: any): Promise<void>;
/**
* Persist the current in-memory index to disk
* Public method for tests and external callers to save current state
*/
persist(): Promise<void>;
/**
* Get elements by action verb
* Tracks usage metrics for trigger optimization
*/
getElementsByAction(verb: string): Promise<string[]>;
/**
* Track trigger usage for optimization metrics
* Supports batching for high-volume scenarios to reduce disk writes
*
* @param trigger - The trigger verb to track
* @param immediate - Force immediate write (bypass batching)
*/
private trackTriggerUsage;
/**
* Flush batched metrics to disk
* Combines multiple metric updates into a single disk write for efficiency
*/
private flushMetricsBatch;
/**
* Get comprehensive trigger usage metrics for optimization analysis
*
* @returns Promise resolving to sorted array of trigger metrics
* @returns {Array<Object>} metrics - Array of trigger metric objects sorted by usage frequency (descending)
* @returns {string} metrics[].trigger - The trigger word/verb
* @returns {number} metrics[].usage_count - Total number of times this trigger has been used
* @returns {string} metrics[].last_used - ISO timestamp of most recent usage
* @returns {string} metrics[].first_used - ISO timestamp of first recorded usage
* @returns {number} metrics[].daily_average - Average daily usage based on historical data
* @returns {'increasing'|'stable'|'decreasing'} metrics[].trend - Usage trend based on last 7 days
*
* @example
* const metrics = await indexManager.getTriggerMetrics();
* // Returns: [
* // { trigger: 'debug', usage_count: 45, trend: 'increasing', ... },
* // { trigger: 'analyze', usage_count: 32, trend: 'stable', ... }
* // ]
*
* @public
* @since 1.9.9
*/
getTriggerMetrics(): Promise<{
trigger: string;
usage_count: number;
last_used: string;
first_used: string;
daily_average: number;
trend: 'increasing' | 'stable' | 'decreasing';
}[]>;
/**
* Export trigger metrics for external analytics systems
* Provides data in a format suitable for analytics platforms
*
* @param format - Export format ('json' | 'csv' | 'prometheus')
* @returns Formatted metrics data
*
* @example
* // Export for Prometheus monitoring
* const prometheusMetrics = await indexManager.exportMetrics('prometheus');
*
* // Export as CSV for data analysis
* const csvData = await indexManager.exportMetrics('csv');
*/
exportMetrics(format?: 'json' | 'csv' | 'prometheus'): Promise<string>;
/**
* Search for elements using enhanced criteria
*/
searchEnhanced(criteria: {
verbs?: string[];
keywords?: string[];
type?: string;
hasRelationships?: boolean;
}): Promise<ElementDefinition[]>;
private calculateSemanticRelationships;
/**
* Find shortest path between two elements
*/
findElementPath(fromElement: string, toElement: string, options?: {
relationshipTypes?: string[];
minStrength?: number;
maxDepth?: number;
}): Promise<ElementPath | null>;
/**
* Get all elements connected to a given element
*/
getConnectedElements(element: string, options?: {
maxDepth?: number;
relationshipTypes?: string[];
minStrength?: number;
}): Promise<Map<string, ElementPath>>;
/**
* Get relationship statistics
*/
getRelationshipStats(): Promise<Record<string, number>>;
/**
* Get all relationships for an element
*/
getElementRelationships(elementId: string): Promise<Record<string, Relationship[]>>;
/**
* Clean up memory by clearing caches and old data
* FIX: Added to prevent memory leaks as identified in PR review
*/
clearMemoryCache(): void;
/**
* Start automatic memory cleanup
*/
startMemoryCleanup(intervalMs?: number): void;
/**
* Stop automatic memory cleanup
*/
stopMemoryCleanup(): void;
/**
* Clean up all resources (for testing and shutdown)
*/
cleanup(): Promise<void>;
}
//# sourceMappingURL=EnhancedIndexManager.d.ts.map