#
tokens: 45167/50000 9/252 files (page 9/18)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 9 of 18. Use http://codebase.md/minipuft/claude-prompts-mcp?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .actrc
├── .gitattributes
├── .github
│   └── workflows
│       ├── ci.yml
│       ├── mcp-compliance.yml
│       └── pr-validation.yml
├── .gitignore
├── agent.md
├── assets
│   └── logo.png
├── CLAUDE.md
├── config
│   └── framework-state.json
├── docs
│   ├── architecture.md
│   ├── chain-modification-examples.md
│   ├── contributing.md
│   ├── enhanced-gate-system.md
│   ├── execution-architecture-guide.md
│   ├── installation-guide.md
│   ├── mcp-tool-usage-guide.md
│   ├── mcp-tools-reference.md
│   ├── prompt-format-guide.md
│   ├── prompt-management.md
│   ├── prompt-vs-template-guide.md
│   ├── README.md
│   ├── template-development-guide.md
│   ├── TODO.md
│   ├── troubleshooting.md
│   └── version-history.md
├── LICENSE
├── local-test.sh
├── plans
│   ├── nunjucks-dynamic-chain-orchestration.md
│   ├── outputschema-realtime-progress-and-validation.md
│   ├── parallel-conditional-execution-analysis.md
│   ├── sqlite-storage-migration.md
│   └── symbolic-command-language-implementation.md
├── README.md
├── scripts
│   ├── setup-windows-testing.sh
│   ├── test_server.js
│   ├── test-all-platforms.sh
│   └── windows-tests
│       ├── test-windows-paths.js
│       ├── test-windows-startup.sh
│       └── windows-env.sh
└── server
    ├── config
    │   ├── framework-state.json
    │   └── tool-descriptions.json
    ├── config.json
    ├── jest.config.cjs
    ├── LICENSE
    ├── package-lock.json
    ├── package.json
    ├── prompts
    │   ├── analysis
    │   │   ├── advanced_analysis_engine.md
    │   │   ├── content_analysis.md
    │   │   ├── deep_analysis.md
    │   │   ├── deep_research.md
    │   │   ├── markdown_notebook.md
    │   │   ├── note_integration.md
    │   │   ├── note_refinement.md
    │   │   ├── notes.md
    │   │   ├── progressive_research.md
    │   │   ├── prompts.json
    │   │   ├── query_refinement.md
    │   │   └── review.md
    │   ├── architecture
    │   │   ├── prompts.json
    │   │   └── strategic-system-alignment.md
    │   ├── content_processing
    │   │   ├── format_enhancement.md
    │   │   ├── noteIntegration.md
    │   │   ├── obsidian_metadata_optimizer.md
    │   │   ├── prompts.json
    │   │   ├── vault_related_notes_finder.md
    │   │   └── video_notes_enhanced.md
    │   ├── debugging
    │   │   ├── analyze_logs.md
    │   │   └── prompts.json
    │   ├── development
    │   │   ├── analyze_code_structure.md
    │   │   ├── analyze_file_structure.md
    │   │   ├── code_review_optimization_chain.md
    │   │   ├── component_flow_analysis.md
    │   │   ├── create_modularization_plan.md
    │   │   ├── detect_code_issues.md
    │   │   ├── detect_project_commands.md
    │   │   ├── expert_code_implementation.md
    │   │   ├── generate_comprehensive_claude_md.md
    │   │   ├── prompts.json
    │   │   ├── strategicImplement.md
    │   │   ├── suggest_code_improvements.md
    │   │   └── transform_code_to_modules.md
    │   ├── documentation
    │   │   ├── create_docs_chain.md
    │   │   ├── docs-content-creation.md
    │   │   ├── docs-content-planning.md
    │   │   ├── docs-final-assembly.md
    │   │   ├── docs-project-analysis.md
    │   │   ├── docs-review-refinement.md
    │   │   └── prompts.json
    │   ├── education
    │   │   ├── prompts.json
    │   │   └── vault_integrated_notes.md
    │   ├── general
    │   │   ├── diagnose.md
    │   │   └── prompts.json
    │   ├── promptsConfig.json
    │   └── testing
    │       ├── final_verification_test.md
    │       └── prompts.json
    ├── README.md
    ├── scripts
    │   └── validate-dependencies.js
    ├── src
    │   ├── api
    │   │   └── index.ts
    │   ├── chain-session
    │   │   └── manager.ts
    │   ├── config
    │   │   └── index.ts
    │   ├── Dockerfile
    │   ├── execution
    │   │   ├── context
    │   │   │   ├── context-resolver.ts
    │   │   │   ├── framework-injector.ts
    │   │   │   └── index.ts
    │   │   ├── index.ts
    │   │   ├── parsers
    │   │   │   ├── argument-parser.ts
    │   │   │   ├── index.ts
    │   │   │   └── unified-command-parser.ts
    │   │   └── types.ts
    │   ├── frameworks
    │   │   ├── framework-manager.ts
    │   │   ├── framework-state-manager.ts
    │   │   ├── index.ts
    │   │   ├── integration
    │   │   │   ├── framework-semantic-integration.ts
    │   │   │   └── index.ts
    │   │   ├── methodology
    │   │   │   ├── guides
    │   │   │   │   ├── 5w1h-guide.ts
    │   │   │   │   ├── cageerf-guide.ts
    │   │   │   │   ├── react-guide.ts
    │   │   │   │   └── scamper-guide.ts
    │   │   │   ├── index.ts
    │   │   │   ├── interfaces.ts
    │   │   │   └── registry.ts
    │   │   ├── prompt-guidance
    │   │   │   ├── index.ts
    │   │   │   ├── methodology-tracker.ts
    │   │   │   ├── service.ts
    │   │   │   ├── system-prompt-injector.ts
    │   │   │   └── template-enhancer.ts
    │   │   └── types
    │   │       ├── index.ts
    │   │       ├── integration-types.ts
    │   │       ├── methodology-types.ts
    │   │       └── prompt-guidance-types.ts
    │   ├── gates
    │   │   ├── constants.ts
    │   │   ├── core
    │   │   │   ├── gate-definitions.ts
    │   │   │   ├── gate-loader.ts
    │   │   │   ├── gate-validator.ts
    │   │   │   ├── index.ts
    │   │   │   └── temporary-gate-registry.ts
    │   │   ├── definitions
    │   │   │   ├── code-quality.json
    │   │   │   ├── content-structure.json
    │   │   │   ├── educational-clarity.json
    │   │   │   ├── framework-compliance.json
    │   │   │   ├── research-quality.json
    │   │   │   ├── security-awareness.json
    │   │   │   └── technical-accuracy.json
    │   │   ├── gate-state-manager.ts
    │   │   ├── guidance
    │   │   │   ├── FrameworkGuidanceFilter.ts
    │   │   │   └── GateGuidanceRenderer.ts
    │   │   ├── index.ts
    │   │   ├── intelligence
    │   │   │   ├── GatePerformanceAnalyzer.ts
    │   │   │   └── GateSelectionEngine.ts
    │   │   ├── templates
    │   │   │   ├── code_quality_validation.md
    │   │   │   ├── educational_clarity_validation.md
    │   │   │   ├── framework_compliance_validation.md
    │   │   │   ├── research_self_validation.md
    │   │   │   ├── security_validation.md
    │   │   │   ├── structure_validation.md
    │   │   │   └── technical_accuracy_validation.md
    │   │   └── types.ts
    │   ├── index.ts
    │   ├── logging
    │   │   └── index.ts
    │   ├── mcp-tools
    │   │   ├── config-utils.ts
    │   │   ├── constants.ts
    │   │   ├── index.ts
    │   │   ├── prompt-engine
    │   │   │   ├── core
    │   │   │   │   ├── engine.ts
    │   │   │   │   ├── executor.ts
    │   │   │   │   ├── index.ts
    │   │   │   │   └── types.ts
    │   │   │   ├── index.ts
    │   │   │   ├── processors
    │   │   │   │   ├── response-formatter.ts
    │   │   │   │   └── template-processor.ts
    │   │   │   └── utils
    │   │   │       ├── category-extractor.ts
    │   │   │       ├── classification.ts
    │   │   │       ├── context-builder.ts
    │   │   │       └── validation.ts
    │   │   ├── prompt-manager
    │   │   │   ├── analysis
    │   │   │   │   ├── comparison-engine.ts
    │   │   │   │   ├── gate-analyzer.ts
    │   │   │   │   └── prompt-analyzer.ts
    │   │   │   ├── core
    │   │   │   │   ├── index.ts
    │   │   │   │   ├── manager.ts
    │   │   │   │   └── types.ts
    │   │   │   ├── index.ts
    │   │   │   ├── operations
    │   │   │   │   └── file-operations.ts
    │   │   │   ├── search
    │   │   │   │   ├── filter-parser.ts
    │   │   │   │   └── prompt-matcher.ts
    │   │   │   └── utils
    │   │   │       ├── category-manager.ts
    │   │   │       └── validation.ts
    │   │   ├── shared
    │   │   │   └── structured-response-builder.ts
    │   │   ├── system-control.ts
    │   │   ├── tool-description-manager.ts
    │   │   └── types
    │   │       └── shared-types.ts
    │   ├── metrics
    │   │   ├── analytics-service.ts
    │   │   ├── index.ts
    │   │   └── types.ts
    │   ├── performance
    │   │   ├── index.ts
    │   │   └── monitor.ts
    │   ├── prompts
    │   │   ├── category-manager.ts
    │   │   ├── converter.ts
    │   │   ├── file-observer.ts
    │   │   ├── hot-reload-manager.ts
    │   │   ├── index.ts
    │   │   ├── loader.ts
    │   │   ├── promptUtils.ts
    │   │   ├── registry.ts
    │   │   └── types.ts
    │   ├── runtime
    │   │   ├── application.ts
    │   │   └── startup.ts
    │   ├── semantic
    │   │   ├── configurable-semantic-analyzer.ts
    │   │   └── integrations
    │   │       ├── index.ts
    │   │       └── llm-clients.ts
    │   ├── server
    │   │   ├── index.ts
    │   │   └── transport
    │   │       └── index.ts
    │   ├── smithery.yaml
    │   ├── text-references
    │   │   ├── conversation.ts
    │   │   └── index.ts
    │   ├── types
    │   │   └── index.ts
    │   ├── types.ts
    │   └── utils
    │       ├── chainUtils.ts
    │       ├── errorHandling.ts
    │       ├── global-resource-tracker.ts
    │       ├── index.ts
    │       └── jsonUtils.ts
    ├── tests
    │   ├── ci-startup-validation.js
    │   ├── enhanced-validation
    │   │   ├── contract-validation
    │   │   │   ├── contract-test-suite.js
    │   │   │   ├── interface-contracts.js
    │   │   │   └── interface-contracts.ts
    │   │   ├── environment-validation
    │   │   │   ├── environment-parity-checker.js
    │   │   │   └── environment-test-suite.js
    │   │   ├── lifecycle-validation
    │   │   │   ├── lifecycle-test-suite.js
    │   │   │   └── process-lifecycle-validator.js
    │   │   └── validation-orchestrator.js
    │   ├── helpers
    │   │   └── test-helpers.js
    │   ├── integration
    │   │   ├── mcp-tools.test.ts
    │   │   ├── server-startup.test.ts
    │   │   └── unified-parsing-integration.test.ts
    │   ├── performance
    │   │   ├── parsing-system-benchmark.test.ts
    │   │   └── server-performance.test.ts
    │   ├── scripts
    │   │   ├── consolidated-tools.js
    │   │   ├── establish-performance-baselines.js
    │   │   ├── functional-mcp-validation.js
    │   │   ├── integration-mcp-tools.js
    │   │   ├── integration-routing-system.js
    │   │   ├── integration-server-startup.js
    │   │   ├── integration-unified-parsing.js
    │   │   ├── methodology-guides.js
    │   │   ├── performance-memory.js
    │   │   ├── runtime-integration.js
    │   │   ├── unit-conversation-manager.js
    │   │   ├── unit-semantic-analyzer.js
    │   │   └── unit-unified-parsing.js
    │   ├── setup.ts
    │   ├── test-enhanced-parsing.js
    │   └── unit
    │       ├── conversation-manager.test.ts
    │       ├── semantic-analyzer-three-tier.test.ts
    │       └── unified-parsing-system.test.ts
    ├── tsconfig.json
    └── tsconfig.test.json
```

# Files

--------------------------------------------------------------------------------
/server/src/mcp-tools/tool-description-manager.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Tool Description Manager
  3 |  *
  4 |  * Manages externalized tool descriptions with graceful fallback to defaults.
  5 |  * Follows established ConfigManager pattern for consistency with existing architecture.
  6 |  */
  7 | 
  8 | import { Logger } from '../logging/index.js';
  9 | import { ConfigManager } from '../config/index.js';
 10 | import { ToolDescription, ToolDescriptionsConfig } from '../types/index.js';
 11 | import * as fs from 'fs/promises';
 12 | import * as path from 'path';
 13 | import { watch, FSWatcher } from 'fs';
 14 | import { EventEmitter } from 'events';
 15 | import {
 16 |   CAGEERFMethodologyGuide,
 17 |   ReACTMethodologyGuide,
 18 |   FiveW1HMethodologyGuide,
 19 |   SCAMPERMethodologyGuide
 20 | } from '../frameworks/methodology/index.js';
 21 | import { MethodologyToolDescriptions } from '../frameworks/types/index.js';
 22 | 
 23 | /**
 24 |  * Manages tool descriptions loaded from external configuration with hot-reload support
 25 |  */
 26 | export class ToolDescriptionManager extends EventEmitter {
 27 |   private logger: Logger;
 28 |   private configPath: string;
 29 |   private descriptions: Map<string, ToolDescription>;
 30 |   private defaults: Map<string, ToolDescription>;
 31 |   private methodologyDescriptions: Map<string, MethodologyToolDescriptions>;
 32 |   private isInitialized: boolean = false;
 33 |   private fileWatcher?: FSWatcher;
 34 |   private isWatching: boolean = false;
 35 |   private reloadDebounceTimer?: NodeJS.Timeout;
 36 | 
 37 |   constructor(logger: Logger, configManager: ConfigManager) {
 38 |     super();
 39 |     this.logger = logger;
 40 |     this.configPath = path.join(configManager.getServerRoot(), 'config', 'tool-descriptions.json');
 41 |     this.descriptions = new Map();
 42 |     this.defaults = this.createDefaults();
 43 |     this.methodologyDescriptions = new Map();
 44 |   }
 45 | 
 46 |   /**
 47 |    * Normalize methodology keys for consistent lookup (case-insensitive)
 48 |    */
 49 |   private normalizeMethodologyKey(methodology?: string): string | undefined {
 50 |     if (!methodology) return undefined;
 51 |     return methodology.trim().toUpperCase();
 52 |   }
 53 | 
 54 |   /**
 55 |    * Create default descriptions as fallback
 56 |    */
 57 |   private createDefaults(): Map<string, ToolDescription> {
 58 |     return new Map([
 59 |       ['prompt_engine', {
 60 |         description: '🚀 PROMPT ENGINE [HOT-RELOAD]: Processes Nunjucks templates, returns executable instructions. WARNING: Output contains instructions YOU must execute (code gen, analysis, multi-step tasks) - not just information. IMPORTANT: Prompt names are case-insensitive and hyphens are converted to underscores. When your arguments include newlines or multi-line payloads, wrap the call in JSON so the parser receives a single-line command shell.',
 61 |         shortDescription: 'Execute prompts, templates, and chains',
 62 |         category: 'execution'
 63 |       }],
 64 |       ['prompt_manager', {
 65 |         description: '🧰 PROMPT MANAGER: Create, update, delete, list, and analyze prompts. Supports gate configuration, temporary gates, and prompt-type migration for full lifecycle control.',
 66 |         shortDescription: 'Manage prompt lifecycle, gates, and discovery',
 67 |         category: 'management'
 68 |       }],
 69 |       ['system_control', {
 70 |         description: '⚙️ SYSTEM CONTROL: Unified interface for status reporting, framework and gate controls, analytics, configuration management, and maintenance operations.',
 71 |         shortDescription: 'Manage framework state, metrics, and maintenance',
 72 |         category: 'system'
 73 |       }]
 74 |     ]);
 75 |   }
 76 | 
 77 |   /**
 78 |    * Pre-load all methodology descriptions for dynamic switching
 79 |    */
 80 |   private preloadMethodologyDescriptions(): void {
 81 |     try {
 82 |       // Initialize all methodology guides
 83 |       const guides = [
 84 |         new CAGEERFMethodologyGuide(),
 85 |         new ReACTMethodologyGuide(),
 86 |         new FiveW1HMethodologyGuide(),
 87 |         new SCAMPERMethodologyGuide()
 88 |       ];
 89 | 
 90 |       // Pre-load tool descriptions for each methodology using normalized keys
 91 |       for (const guide of guides) {
 92 |         const descriptions = guide.getToolDescriptions?.() || {};
 93 |         const methodologyKey = this.normalizeMethodologyKey(guide.methodology);
 94 |         const frameworkKey = this.normalizeMethodologyKey(guide.frameworkId);
 95 | 
 96 |         if (methodologyKey) {
 97 |           this.methodologyDescriptions.set(methodologyKey, descriptions);
 98 |         }
 99 | 
100 |         if (frameworkKey) {
101 |           this.methodologyDescriptions.set(frameworkKey, descriptions);
102 |         }
103 |       }
104 | 
105 |       this.logger.info(`✅ Pre-loaded tool descriptions for ${this.methodologyDescriptions.size} methodologies`);
106 |     } catch (error) {
107 |       this.logger.error(`Failed to pre-load methodology descriptions: ${error instanceof Error ? error.message : String(error)}`);
108 |     }
109 |   }
110 | 
111 |   /**
112 |    * Initialize by loading descriptions from external config file
113 |    */
114 |   async initialize(): Promise<void> {
115 |     try {
116 |       this.logger.info(`Loading tool descriptions from ${this.configPath}...`);
117 |       const content = await fs.readFile(this.configPath, 'utf-8');
118 |       const config: ToolDescriptionsConfig = JSON.parse(content);
119 | 
120 |       // Validate config structure
121 |       if (!config.tools || typeof config.tools !== 'object') {
122 |         throw new Error('Invalid tool descriptions config: missing or invalid tools section');
123 |       }
124 | 
125 |       // Load descriptions
126 |       this.descriptions.clear();
127 |       for (const [name, description] of Object.entries(config.tools)) {
128 |         this.descriptions.set(name, description);
129 |       }
130 | 
131 |       this.isInitialized = true;
132 |       this.logger.info(`✅ Loaded ${this.descriptions.size} tool descriptions from external config (version: ${config.version})`);
133 | 
134 |       // Pre-load methodology descriptions for dynamic switching
135 |       this.preloadMethodologyDescriptions();
136 | 
137 |     } catch (error) {
138 |       this.logger.warn(`⚠️ Failed to load tool descriptions from ${this.configPath}: ${error instanceof Error ? error.message : String(error)}`);
139 |       this.logger.info('🔄 Using hardcoded default descriptions as fallback');
140 | 
141 |       // Use defaults as fallback
142 |       this.descriptions = new Map(this.defaults);
143 |       this.isInitialized = true;
144 | 
145 |       // Pre-load methodology descriptions for dynamic switching
146 |       this.preloadMethodologyDescriptions();
147 |     }
148 |   }
149 | 
150 |   /**
151 |    * Get description for a specific tool with corrected priority hierarchy
152 |    */
153 |   getDescription(
154 |     toolName: string,
155 |     frameworkEnabled?: boolean,
156 |     activeMethodology?: string,
157 |     options?: { applyMethodologyOverride?: boolean }
158 |   ): string {
159 |     const applyMethodologyOverride = options?.applyMethodologyOverride ?? true;
160 |     this.logger.debug(`Getting description for ${toolName} (framework: ${frameworkEnabled}, methodology: ${activeMethodology})`);
161 |     const methodologyKey = this.normalizeMethodologyKey(activeMethodology);
162 |     const methodologyLogName = activeMethodology ?? methodologyKey;
163 | 
164 |     // PRIORITY 1: Methodology-specific descriptions from guides (HIGHEST PRIORITY)
165 |     if (applyMethodologyOverride && methodologyKey) {
166 |       const methodologyDescs = this.methodologyDescriptions.get(methodologyKey);
167 |       if (methodologyDescs?.[toolName as keyof MethodologyToolDescriptions]?.description) {
168 |         const methodologyDesc = methodologyDescs[toolName as keyof MethodologyToolDescriptions]!.description!;
169 |         this.logger.debug(`✅ Using methodology-specific description from ${methodologyLogName} guide for ${toolName}`);
170 |         return methodologyDesc;
171 |       }
172 |       this.logger.debug(`⚠️ No methodology-specific description found for ${toolName} in ${methodologyLogName} guide`);
173 |     }
174 | 
175 |     // Get config/default descriptions for fallback priority checks
176 |     const toolDesc = this.descriptions.get(toolName) || this.defaults.get(toolName);
177 | 
178 |     if (!toolDesc) {
179 |       this.logger.warn(`No description found for tool: ${toolName}`);
180 |       return `Tool: ${toolName}`;
181 |     }
182 | 
183 |     // PRIORITY 2: Framework-aware descriptions from config (if methodology desc not available)
184 |     if (frameworkEnabled !== undefined && toolDesc.frameworkAware) {
185 |       if (frameworkEnabled && toolDesc.frameworkAware.enabled) {
186 |         this.logger.debug(`✅ Using framework-aware enabled description from config for ${toolName}`);
187 |         return toolDesc.frameworkAware.enabled;
188 |       } else if (!frameworkEnabled && toolDesc.frameworkAware.disabled) {
189 |         this.logger.debug(`✅ Using framework-aware disabled description from config for ${toolName}`);
190 |         return toolDesc.frameworkAware.disabled;
191 |       }
192 | 
193 |       // Check for static methodology descriptions in config as fallback
194 |       if (frameworkEnabled && methodologyKey && toolDesc.frameworkAware?.methodologies) {
195 |         const configMethodologyDescription =
196 |           toolDesc.frameworkAware.methodologies[methodologyKey] ??
197 |           (activeMethodology
198 |             ? toolDesc.frameworkAware.methodologies[activeMethodology]
199 |             : undefined);
200 |         if (configMethodologyDescription) {
201 |           this.logger.debug(
202 |             `✅ Using static methodology description from config for ${toolName} (${methodologyLogName})`
203 |           );
204 |           return configMethodologyDescription;
205 |         }
206 |       }
207 |     }
208 | 
209 |     // PRIORITY 3: Basic config file descriptions (LOWER PRIORITY)
210 |     this.logger.debug(`✅ Using basic config/default description for ${toolName}`);
211 |     return toolDesc.description;
212 |   }
213 | 
214 |   /**
215 |    * Get parameter description for a specific tool parameter
216 |    */
217 |   getParameterDescription(
218 |     toolName: string,
219 |     paramName: string,
220 |     frameworkEnabled?: boolean,
221 |     activeMethodology?: string,
222 |     options?: { applyMethodologyOverride?: boolean }
223 |   ): string | undefined {
224 |     const applyMethodologyOverride = options?.applyMethodologyOverride ?? true;
225 |     const toolDesc = this.descriptions.get(toolName) || this.defaults.get(toolName);
226 |     if (!toolDesc?.parameters) return undefined;
227 |     const methodologyKey = this.normalizeMethodologyKey(activeMethodology);
228 | 
229 |     // Check for methodology-specific parameter descriptions first (from pre-loaded cache)
230 |     if (applyMethodologyOverride && methodologyKey) {
231 |       const methodologyDescs = this.methodologyDescriptions.get(methodologyKey);
232 |       const methodologyTool = methodologyDescs?.[toolName as keyof MethodologyToolDescriptions];
233 |       if (methodologyTool?.parameters?.[paramName]) {
234 |         return methodologyTool.parameters[paramName];
235 |       }
236 |       // Fallback to static config if available
237 |       const methodologyParameters = toolDesc.frameworkAware?.methodologyParameters;
238 |       const methodologyParamConfig = methodologyParameters?.[methodologyKey] ??
239 |         (activeMethodology ? methodologyParameters?.[activeMethodology] : undefined);
240 |       if (methodologyParamConfig?.[paramName]) {
241 |         const param = methodologyParamConfig[paramName];
242 |         return typeof param === 'string' ? param : param?.description;
243 |       }
244 |     }
245 | 
246 |     // Check for framework-aware parameter descriptions
247 |     if (frameworkEnabled !== undefined && toolDesc.frameworkAware) {
248 |       const frameworkParams = frameworkEnabled
249 |         ? toolDesc.frameworkAware.parametersEnabled
250 |         : toolDesc.frameworkAware.parametersDisabled;
251 | 
252 |       if (frameworkParams?.[paramName]) {
253 |         const param = frameworkParams[paramName];
254 |         return typeof param === 'string' ? param : param?.description;
255 |       }
256 |     }
257 | 
258 |     // Fall back to default parameters
259 |     const param = toolDesc.parameters[paramName];
260 |     return typeof param === 'string' ? param : param?.description;
261 |   }
262 | 
263 |   /**
264 |    * Get all available tool names
265 |    */
266 |   getAvailableTools(): string[] {
267 |     return Array.from(this.descriptions.keys());
268 |   }
269 | 
270 |   /**
271 |    * Check if manager is properly initialized
272 |    */
273 |   isReady(): boolean {
274 |     return this.isInitialized;
275 |   }
276 | 
277 |   /**
278 |    * Get configuration path for debugging
279 |    */
280 |   getConfigPath(): string {
281 |     return this.configPath;
282 |   }
283 | 
284 |   /**
285 |    * Get statistics about loaded descriptions
286 |    */
287 |   getStats(): {
288 |     totalDescriptions: number;
289 |     loadedFromFile: number;
290 |     usingDefaults: number;
291 |     configPath: string;
292 |     isInitialized: boolean;
293 |   } {
294 |     const loadedFromFile = this.descriptions.size;
295 |     const defaultCount = this.defaults.size;
296 | 
297 |     return {
298 |       totalDescriptions: this.descriptions.size,
299 |       loadedFromFile: loadedFromFile > defaultCount ? loadedFromFile : 0,
300 |       usingDefaults: loadedFromFile <= defaultCount ? defaultCount : 0,
301 |       configPath: this.configPath,
302 |       isInitialized: this.isInitialized
303 |     };
304 |   }
305 | 
306 |   /**
307 |    * Start watching the tool descriptions file for changes
308 |    */
309 |   startWatching(): void {
310 |     if (this.isWatching) {
311 |       this.logger.debug('Tool description file watcher already active');
312 |       return;
313 |     }
314 | 
315 |     try {
316 |       this.logger.info(`🔍 Starting file watcher for tool descriptions: ${this.configPath}`);
317 | 
318 |       this.fileWatcher = watch(this.configPath, (eventType) => {
319 |         if (eventType === 'change') {
320 |           this.handleFileChange();
321 |         }
322 |       });
323 | 
324 |       this.fileWatcher.on('error', (error) => {
325 |         this.logger.error(`Tool description file watcher error: ${error.message}`);
326 |         this.isWatching = false;
327 |       });
328 | 
329 |       this.isWatching = true;
330 |       this.logger.info('✅ Tool description hot-reload watcher started successfully');
331 |     } catch (error) {
332 |       this.logger.error(`Failed to start tool description file watcher: ${error instanceof Error ? error.message : String(error)}`);
333 |     }
334 |   }
335 | 
336 |   /**
337 |    * Stop watching the tool descriptions file
338 |    */
339 |   stopWatching(): void {
340 |     if (this.fileWatcher) {
341 |       this.logger.info('🛑 Stopping tool description file watcher...');
342 |       this.fileWatcher.close();
343 |       this.fileWatcher = undefined;
344 |     }
345 | 
346 |     if (this.reloadDebounceTimer) {
347 |       clearTimeout(this.reloadDebounceTimer);
348 |       this.reloadDebounceTimer = undefined;
349 |     }
350 | 
351 |     this.isWatching = false;
352 |     this.logger.info('✅ Tool description file watcher stopped');
353 |   }
354 | 
355 |   /**
356 |    * Handle file change event with debouncing
357 |    */
358 |   private handleFileChange(): void {
359 |     // Clear existing timer to debounce rapid file changes
360 |     if (this.reloadDebounceTimer) {
361 |       clearTimeout(this.reloadDebounceTimer);
362 |     }
363 | 
364 |     // Debounce file changes (wait 500ms after last change)
365 |     this.reloadDebounceTimer = setTimeout(async () => {
366 |       try {
367 |         this.logger.info('📝 Tool descriptions file changed, reloading...');
368 |         await this.reload();
369 |         this.emit('descriptions-changed', this.getStats());
370 |         this.logger.info('✅ Tool descriptions reloaded successfully');
371 |       } catch (error) {
372 |         this.logger.error(`Failed to reload tool descriptions: ${error instanceof Error ? error.message : String(error)}`);
373 |         this.emit('descriptions-error', error);
374 |       }
375 |     }, 500);
376 |   }
377 | 
378 |   /**
379 |    * Reload descriptions from file
380 |    */
381 |   async reload(): Promise<void> {
382 |     await this.initialize();
383 |   }
384 | 
385 |   /**
386 |    * Check if file watching is active
387 |    */
388 |   isWatchingFile(): boolean {
389 |     return this.isWatching;
390 |   }
391 | 
392 |   /**
393 |    * Cleanup resources on shutdown
394 |    */
395 |   shutdown(): void {
396 |     this.stopWatching();
397 |     this.removeAllListeners();
398 |   }
399 | }
400 | 
401 | /**
402 |  * Factory function following established pattern
403 |  */
404 | export function createToolDescriptionManager(
405 |   logger: Logger,
406 |   configManager: ConfigManager
407 | ): ToolDescriptionManager {
408 |   return new ToolDescriptionManager(logger, configManager);
409 | }
410 | 
```

--------------------------------------------------------------------------------
/server/src/gates/core/gate-validator.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Core Gate Validator
  3 |  * Provides validation capabilities with practical checks for prompt execution
  4 |  */
  5 | 
  6 | import { Logger } from '../../logging/index.js';
  7 | import type { GateLoader } from './gate-loader.js';
  8 | import type {
  9 |   LightweightGateDefinition,
 10 |   ValidationCheck,
 11 |   ValidationContext,
 12 |   GatePassCriteria
 13 | } from '../types.js';
 14 | import type { ValidationResult } from '../../execution/types.js';
 15 | import type { LLMIntegrationConfig } from '../../types.js';
 16 | 
 17 | /**
 18 |  * Gate validation statistics
 19 |  */
 20 | export interface GateValidationStatistics {
 21 |   totalValidations: number;
 22 |   successfulValidations: number;
 23 |   failedValidations: number;
 24 |   averageValidationTime: number;
 25 |   retryRequests: number;
 26 | }
 27 | 
 28 | /**
 29 |  * Core gate validator with pass/fail logic
 30 |  */
 31 | export class GateValidator {
 32 |   private logger: Logger;
 33 |   private gateLoader: GateLoader;
 34 |   private llmConfig?: LLMIntegrationConfig;
 35 |   private validationStats: GateValidationStatistics = {
 36 |     totalValidations: 0,
 37 |     successfulValidations: 0,
 38 |     failedValidations: 0,
 39 |     averageValidationTime: 0,
 40 |     retryRequests: 0
 41 |   };
 42 |   private validationTimes: number[] = [];
 43 | 
 44 |   constructor(logger: Logger, gateLoader: GateLoader, llmConfig?: LLMIntegrationConfig) {
 45 |     this.logger = logger;
 46 |     this.gateLoader = gateLoader;
 47 |     this.llmConfig = llmConfig;
 48 |   }
 49 | 
 50 |   /**
 51 |    * Validate content against a gate
 52 |    */
 53 |   async validateGate(
 54 |     gateId: string,
 55 |     context: ValidationContext
 56 |   ): Promise<ValidationResult | null> {
 57 |     const startTime = Date.now();
 58 | 
 59 |     try {
 60 |       const gate = await this.gateLoader.loadGate(gateId);
 61 |       if (!gate) {
 62 |         this.logger.warn(`Gate not found for validation: ${gateId}`);
 63 |         return null;
 64 |       }
 65 | 
 66 |       if (gate.type !== 'validation') {
 67 |         this.logger.debug(`Gate ${gateId} is guidance-only, skipping validation`);
 68 |         return {
 69 |           valid: true,
 70 |           passed: true,
 71 |           gateId,
 72 |           checks: [],
 73 |           retryHints: [],
 74 |           metadata: {
 75 |             validationTime: Date.now() - startTime,
 76 |             checksPerformed: 0,
 77 |             llmValidationUsed: false
 78 |           }
 79 |         };
 80 |       }
 81 | 
 82 |       this.logger.debug(`Validating content against gate: ${gateId}`);
 83 | 
 84 |       // Run validation checks
 85 |       const checks: ValidationCheck[] = [];
 86 |       let llmValidationUsed = false;
 87 | 
 88 |       if (gate.pass_criteria) {
 89 |         for (const criteria of gate.pass_criteria) {
 90 |           const check = await this.runValidationCheck(criteria, context);
 91 |           checks.push(check);
 92 | 
 93 |           if (criteria.type === 'llm_self_check') {
 94 |             llmValidationUsed = true;
 95 |           }
 96 |         }
 97 |       }
 98 | 
 99 |       // Determine overall pass/fail
100 |       const passed = checks.length === 0 || checks.every(check => check.passed);
101 | 
102 |       // Generate retry hints for failures
103 |       const retryHints = passed ? [] : this.generateRetryHints(gate, checks);
104 | 
105 |       const result: ValidationResult = {
106 |         valid: passed,
107 |         passed,
108 |         gateId,
109 |         checks,
110 |         retryHints,
111 |         metadata: {
112 |           validationTime: Date.now() - startTime,
113 |           checksPerformed: checks.length,
114 |           llmValidationUsed
115 |         }
116 |       };
117 | 
118 |       this.logger.debug(
119 |         `Gate validation complete: ${gateId} - ${passed ? 'PASSED' : 'FAILED'} (${checks.length} checks)`
120 |       );
121 | 
122 |       return result;
123 |     } catch (error) {
124 |       this.logger.error(`Gate validation failed for ${gateId}:`, error);
125 |       return {
126 |         valid: false,
127 |         passed: false,
128 |         gateId,
129 |         checks: [{
130 |           type: 'system_error',
131 |           passed: false,
132 |           message: `Validation error: ${error instanceof Error ? error.message : String(error)}`
133 |         }],
134 |         retryHints: [`Gate validation encountered an error. Please try again.`],
135 |         metadata: {
136 |           validationTime: Date.now() - startTime,
137 |           checksPerformed: 0,
138 |           llmValidationUsed: false
139 |         }
140 |       };
141 |     }
142 |   }
143 | 
144 |   /**
145 |    * Validate content against multiple gates
146 |    */
147 |   async validateGates(
148 |     gateIds: string[],
149 |     context: ValidationContext
150 |   ): Promise<ValidationResult[]> {
151 |     const startTime = Date.now();
152 |     const results: ValidationResult[] = [];
153 | 
154 |     for (const gateId of gateIds) {
155 |       const result = await this.validateGate(gateId, context);
156 |       if (result) {
157 |         results.push(result);
158 | 
159 |         // Update statistics based on result
160 |         if (result.passed) {
161 |           this.validationStats.successfulValidations++;
162 |         } else {
163 |           this.validationStats.failedValidations++;
164 |         }
165 |       }
166 |     }
167 | 
168 |     // Update overall statistics
169 |     const executionTime = Date.now() - startTime;
170 |     this.validationTimes.push(executionTime);
171 |     this.validationStats.totalValidations++;
172 |     this.updateAverageValidationTime();
173 | 
174 |     return results;
175 |   }
176 | 
177 |   /**
178 |    * Run a single validation check
179 |    */
180 |   private async runValidationCheck(
181 |     criteria: GatePassCriteria,
182 |     context: ValidationContext
183 |   ): Promise<ValidationCheck> {
184 |     try {
185 |       switch (criteria.type) {
186 |         case 'content_check':
187 |           return await this.runContentCheck(criteria, context);
188 |         case 'pattern_check':
189 |           return await this.runPatternCheck(criteria, context);
190 |         case 'llm_self_check':
191 |           return await this.runLLMSelfCheck(criteria, context);
192 |         default:
193 |           return {
194 |             type: criteria.type,
195 |             passed: false,
196 |             message: `Unknown validation type: ${criteria.type}`
197 |           };
198 |       }
199 |     } catch (error) {
200 |       this.logger.error(`Validation check failed for ${criteria.type}:`, error);
201 |       return {
202 |         type: criteria.type,
203 |         passed: false,
204 |         message: `Check failed: ${error instanceof Error ? error.message : String(error)}`
205 |       };
206 |     }
207 |   }
208 | 
209 |   /**
210 |    * Run basic content checks (length, basic requirements)
211 |    */
212 |   private async runContentCheck(
213 |     criteria: GatePassCriteria,
214 |     context: ValidationContext
215 |   ): Promise<ValidationCheck> {
216 |     const content = context.content;
217 |     const issues: string[] = [];
218 | 
219 |     // Length checks
220 |     if (criteria.min_length && content.length < criteria.min_length) {
221 |       issues.push(`Content too short: ${content.length} < ${criteria.min_length} characters`);
222 |     }
223 | 
224 |     if (criteria.max_length && content.length > criteria.max_length) {
225 |       issues.push(`Content too long: ${content.length} > ${criteria.max_length} characters`);
226 |     }
227 | 
228 |     // Required patterns (simple string matching)
229 |     if (criteria.required_patterns) {
230 |       for (const pattern of criteria.required_patterns) {
231 |         if (!content.toLowerCase().includes(pattern.toLowerCase())) {
232 |           issues.push(`Missing required content: "${pattern}"`);
233 |         }
234 |       }
235 |     }
236 | 
237 |     // Forbidden patterns
238 |     if (criteria.forbidden_patterns) {
239 |       for (const pattern of criteria.forbidden_patterns) {
240 |         if (content.toLowerCase().includes(pattern.toLowerCase())) {
241 |           issues.push(`Contains forbidden content: "${pattern}"`);
242 |         }
243 |       }
244 |     }
245 | 
246 |     const passed = issues.length === 0;
247 | 
248 |     return {
249 |       type: 'content_check',
250 |       passed,
251 |       score: passed ? 1.0 : Math.max(0, 1 - (issues.length * 0.25)),
252 |       message: passed ? 'Content checks passed' : issues.join('; '),
253 |       details: {
254 |         contentLength: content.length,
255 |         issuesFound: issues.length
256 |       }
257 |     };
258 |   }
259 | 
260 |   /**
261 |    * Run pattern matching checks
262 |    */
263 |   private async runPatternCheck(
264 |     criteria: GatePassCriteria,
265 |     context: ValidationContext
266 |   ): Promise<ValidationCheck> {
267 |     const content = context.content;
268 |     const issues: string[] = [];
269 | 
270 |     // Regex pattern matching
271 |     if (criteria.regex_patterns) {
272 |       for (const pattern of criteria.regex_patterns) {
273 |         try {
274 |           const regex = new RegExp(pattern, 'i');
275 |           if (!regex.test(content)) {
276 |             issues.push(`Content doesn't match pattern: ${pattern}`);
277 |           }
278 |         } catch (error) {
279 |           issues.push(`Invalid regex pattern: ${pattern}`);
280 |         }
281 |       }
282 |     }
283 | 
284 |     // Keyword count checking
285 |     if (criteria.keyword_count) {
286 |       for (const [keyword, requiredCount] of Object.entries(criteria.keyword_count)) {
287 |         const matches = (content.toLowerCase().match(new RegExp(keyword.toLowerCase(), 'g')) || []).length;
288 |         if (matches < requiredCount) {
289 |           issues.push(`Insufficient keyword "${keyword}": found ${matches}, required ${requiredCount}`);
290 |         }
291 |       }
292 |     }
293 | 
294 |     const passed = issues.length === 0;
295 | 
296 |     return {
297 |       type: 'pattern_check',
298 |       passed,
299 |       score: passed ? 1.0 : Math.max(0, 1 - (issues.length * 0.3)),
300 |       message: passed ? 'Pattern checks passed' : issues.join('; '),
301 |       details: { issuesFound: issues.length }
302 |     };
303 |   }
304 | 
305 |   /**
306 |    * Run LLM self-check validation
307 |    *
308 |    * TODO: IMPLEMENT LLM API INTEGRATION
309 |    * This requires connecting to the LLM client configured at:
310 |    * config.analysis.semanticAnalysis.llmIntegration
311 |    *
312 |    * Requirements for implementation:
313 |    * - LLM client instance (from semantic analyzer)
314 |    * - Validation prompt templates
315 |    * - Quality assessment criteria
316 |    * - Confidence threshold enforcement
317 |    *
318 |    * Current behavior: Gracefully skips when LLM not configured
319 |    */
320 |   private async runLLMSelfCheck(
321 |     criteria: GatePassCriteria,
322 |     context: ValidationContext
323 |   ): Promise<ValidationCheck> {
324 |     // Check if LLM integration is configured and enabled
325 |     if (!this.llmConfig?.enabled) {
326 |       this.logger.debug('[LLM GATE] LLM self-check skipped - LLM integration disabled in config');
327 |       return {
328 |         type: 'llm_self_check',
329 |         passed: true, // Auto-pass when not configured
330 |         score: 1.0,
331 |         message: 'LLM validation skipped (not configured - set analysis.semanticAnalysis.llmIntegration.enabled=true)',
332 |         details: {
333 |           skipped: true,
334 |           reason: 'LLM integration disabled in config',
335 |           configPath: 'config.analysis.semanticAnalysis.llmIntegration.enabled'
336 |         }
337 |       };
338 |     }
339 | 
340 |     if (!this.llmConfig.endpoint) {
341 |       this.logger.warn('[LLM GATE] LLM self-check skipped - no endpoint configured');
342 |       return {
343 |         type: 'llm_self_check',
344 |         passed: true,
345 |         score: 1.0,
346 |         message: 'LLM validation skipped (no endpoint configured)',
347 |         details: {
348 |           skipped: true,
349 |           reason: 'No LLM endpoint configured',
350 |           configPath: 'config.analysis.semanticAnalysis.llmIntegration.endpoint'
351 |         }
352 |       };
353 |     }
354 | 
355 |     // TODO: Once LLM API client is available, implement actual validation here
356 |     // For now, log that it's not yet implemented even though config is enabled
357 |     this.logger.warn('[LLM GATE] LLM self-check requested but API client not yet implemented');
358 |     this.logger.debug(`[LLM GATE] Would validate with template: ${criteria.prompt_template}`);
359 | 
360 |     return {
361 |       type: 'llm_self_check',
362 |       passed: true, // Auto-pass until implementation complete
363 |       score: 1.0,
364 |       message: 'LLM validation not yet implemented (API client integration pending)',
365 |       details: {
366 |         skipped: true,
367 |         reason: 'LLM API client not yet implemented',
368 |         configEnabled: this.llmConfig.enabled,
369 |         endpoint: this.llmConfig.endpoint,
370 |         templateRequested: criteria.prompt_template || 'default',
371 |         implementation: 'TODO: Wire LLM client from semantic analyzer'
372 |       }
373 |     };
374 |   }
375 | 
376 |   /**
377 |    * Generate retry hints based on failed checks
378 |    */
379 |   private generateRetryHints(
380 |     gate: LightweightGateDefinition,
381 |     checks: ValidationCheck[]
382 |   ): string[] {
383 |     const hints: string[] = [];
384 |     const failedChecks = checks.filter(check => !check.passed);
385 | 
386 |     if (failedChecks.length === 0) {
387 |       return hints;
388 |     }
389 | 
390 |     // Add gate-specific guidance as a hint
391 |     if (gate.guidance) {
392 |       hints.push(`Remember the ${gate.name} guidelines:\n${gate.guidance}`);
393 |     }
394 | 
395 |     // Add specific failure hints
396 |     for (const check of failedChecks) {
397 |       switch (check.type) {
398 |         case 'content_check':
399 |           if (check.message.includes('too short')) {
400 |             hints.push('Add more detail, examples, or explanations to meet length requirements');
401 |           }
402 |           if (check.message.includes('too long')) {
403 |             hints.push('Condense your response by removing redundant information');
404 |           }
405 |           if (check.message.includes('Missing required content')) {
406 |             hints.push(`Ensure your response includes: ${check.message.split(': ')[1]}`);
407 |           }
408 |           break;
409 |         case 'pattern_check':
410 |           hints.push('Review pattern matching requirements and adjust content structure');
411 |           break;
412 |         case 'llm_self_check':
413 |           hints.push('Review the quality criteria and improve content structure and depth');
414 |           break;
415 |       }
416 |     }
417 | 
418 |     // Ensure we have at least one helpful hint
419 |     if (hints.length === 0) {
420 |       hints.push(`${gate.name} validation failed. Please review the requirements and try again.`);
421 |     }
422 | 
423 |     return hints;
424 |   }
425 | 
426 |   /**
427 |    * Check if content should be retried based on validation results
428 |    *
429 |    * @param validationResults - Results from gate validation
430 |    * @param currentAttempt - Current attempt number
431 |    * @param maxAttempts - Maximum allowed attempts
432 |    * @returns true if retry should be attempted
433 |    */
434 |   shouldRetry(
435 |     validationResults: ValidationResult[],
436 |     currentAttempt: number,
437 |     maxAttempts: number = 3
438 |   ): boolean {
439 |     if (currentAttempt >= maxAttempts) {
440 |       this.logger.debug('[GATE VALIDATOR] Max attempts reached, no retry');
441 |       return false;
442 |     }
443 | 
444 |     // Retry if any validation gate failed
445 |     const shouldRetry = validationResults.some(result => !result.valid);
446 | 
447 |     if (shouldRetry) {
448 |       this.validationStats.retryRequests++;
449 |       this.logger.debug('[GATE VALIDATOR] Retry recommended:', {
450 |         currentAttempt,
451 |         maxAttempts,
452 |         failedGates: validationResults.filter(r => !r.valid).map(r => r.gateId)
453 |       });
454 |     }
455 | 
456 |     return shouldRetry;
457 |   }
458 | 
459 |   /**
460 |    * Update average validation time
461 |    */
462 |   private updateAverageValidationTime(): void {
463 |     if (this.validationTimes.length > 0) {
464 |       const sum = this.validationTimes.reduce((a, b) => a + b, 0);
465 |       this.validationStats.averageValidationTime = sum / this.validationTimes.length;
466 |     }
467 | 
468 |     // Keep only last 100 measurements for rolling average
469 |     if (this.validationTimes.length > 100) {
470 |       this.validationTimes = this.validationTimes.slice(-100);
471 |     }
472 |   }
473 | 
474 |   /**
475 |    * Get validation statistics
476 |    */
477 |   getStatistics(): GateValidationStatistics {
478 |     return { ...this.validationStats };
479 |   }
480 | 
481 |   /**
482 |    * Reset validation statistics
483 |    */
484 |   resetStatistics(): void {
485 |     this.validationStats = {
486 |       totalValidations: 0,
487 |       successfulValidations: 0,
488 |       failedValidations: 0,
489 |       averageValidationTime: 0,
490 |       retryRequests: 0
491 |     };
492 |     this.validationTimes = [];
493 |     this.logger.debug('[GATE VALIDATOR] Statistics reset');
494 |   }
495 | }
496 | 
497 | /**
498 |  * Create a gate validator instance
499 |  */
500 | export function createGateValidator(logger: Logger, gateLoader: GateLoader, llmConfig?: LLMIntegrationConfig): GateValidator {
501 |   return new GateValidator(logger, gateLoader, llmConfig);
502 | }
```

--------------------------------------------------------------------------------
/docs/prompt-vs-template-guide.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Execution Modes Guide - Prompt vs Template vs Chain
  2 | 
  3 | ## Overview
  4 | 
  5 | The Claude Prompts MCP Server provides **three intelligent execution modes** optimized for different use cases. All execution happens through the consolidated `prompt_engine` MCP tool with automatic mode detection and framework integration.
  6 | 
  7 | > 📖 **For comprehensive details**, see the [Execution Architecture Guide](./execution-architecture-guide.md)
  8 | 
  9 | ## Three Execution Modes
 10 | 
 11 | - **Prompt**: Basic variable substitution (fastest, ~10-50ms)
 12 | - **Template**: Framework-aware processing with methodology guidance (balanced, ~100-500ms) 
 13 | - **Chain**: LLM-driven iterative execution with instructions (most capable, variable timing)
 14 | 
 15 | **Intelligent Detection**: The `prompt_engine` automatically detects the optimal execution mode based on your prompt's complexity and structure.
 16 | 
 17 | ## Quick Decision Guide
 18 | 
 19 | ### 🚀 Use **Prompt Mode** When:
 20 | 
 21 | - Speed is critical (sub-100ms execution)
 22 | - Simple variable substitution needed
 23 | - Development/testing scenarios
 24 | - Basic text formatting or generation
 25 | - No framework methodology needed
 26 | 
 27 | ### 🧠 Use **Template Mode** When:
 28 | 
 29 | - Complex reasoning or analysis required
 30 | - Framework methodology benefits (CAGEERF, ReACT, 5W1H, SCAMPER)
 31 | - Professional-quality outputs needed
 32 | - Quality gates and validation desired
 33 | - System prompt enhancement helpful
 34 | 
 35 | ### 🔗 Use **Chain Mode** When:
 36 | 
 37 | - Multi-step processes requiring iterative execution
 38 | - Building complex outputs progressively through LLM guidance
 39 | - Context needs to flow between steps
 40 | - Mission-critical processes requiring step-by-step validation
 41 | - LLM should control execution flow and decision-making
 42 | 
 43 | ## MCP Tool Usage
 44 | 
 45 | All execution uses the consolidated `prompt_engine` MCP tool:
 46 | 
 47 | ### Basic Execution
 48 | 
 49 | ```bash
 50 | # Automatic mode detection (recommended)
 51 | prompt_engine >>my_prompt input="analyze this data"
 52 | 
 53 | # Explicit mode specification
 54 | prompt_engine >>my_prompt input="data" execution_mode="prompt"     # Force basic mode
 55 | prompt_engine >>my_prompt input="data" execution_mode="template"   # Force framework mode  
 56 | prompt_engine >>my_prompt input="data" execution_mode="chain"      # Force chain mode
 57 | ```
 58 | 
 59 | ### JSON Command Format
 60 | 
 61 | ```bash
 62 | # Alternative JSON syntax for complex arguments
 63 | prompt_engine command='{"command": ">>analysis_prompt", "args": {"data": "complex data", "focus": "security"}}'
 64 | ```
 65 | 
 66 | ### Framework Integration
 67 | 
 68 | Templates automatically use the active framework methodology:
 69 | 
 70 | ```bash
 71 | # Check current framework and system status
 72 | system_control status
 73 | 
 74 | # Switch framework for enhanced template processing
 75 | system_control switch_framework framework="CAGEERF" reason="Need comprehensive analysis"
 76 | system_control switch_framework framework="ReACT" reason="Problem-solving focus"
 77 | ```
 78 | 
 79 | ## Execution Mode Details
 80 | 
 81 | ### Prompt Mode (`execution_mode="prompt"`)
 82 | 
 83 | **Purpose**: Lightning-fast variable substitution without framework overhead
 84 | 
 85 | **Features**:
 86 | - Simple Nunjucks template processing
 87 | - Direct variable substitution
 88 | - No system prompt enhancement
 89 | - Minimal processing overhead
 90 | - Optional quality gates
 91 | 
 92 | **Output Format**: `⚡ **Basic Prompt Execution** | 🚀 Fast variable substitution`
 93 | 
 94 | **Example**:
 95 | ```bash
 96 | prompt_engine >>format_code code="function test() {}" style="prettier" execution_mode="prompt"
 97 | ```
 98 | 
 99 | ### Template Mode (`execution_mode="template"`)
100 | 
101 | **Purpose**: Framework-enhanced execution with methodology guidance
102 | 
103 | **Features**:
104 | - Full framework processing with active methodology
105 | - System prompt injection from framework guides
106 | - Quality gates integration (when enabled)
107 | - Framework-specific enhancement and validation
108 | - Professional-quality outputs
109 | 
110 | **Output Format**: `🧠 **Framework Template Execution** | 🎯 [Active Framework] | ✅ Quality gates applied`
111 | 
112 | **Example**:
113 | ```bash
114 | prompt_engine >>security_analysis code="{{codebase}}" execution_mode="template" gate_validation=true
115 | ```
116 | 
117 | ### Chain Mode (`execution_mode="chain"`)
118 | 
119 | **Purpose**: LLM-driven iterative execution with step-by-step guidance
120 | 
121 | **Revolutionary Architecture**: Instead of server-side orchestration, chains return **structured instructions** that guide the LLM through iterative execution.
122 | 
123 | **How Chain Mode Works**:
124 | 1. Chain mode analyzes the chain definition and current state
125 | 2. Returns **LLM instruction template** for the next step to execute
126 | 3. LLM executes the step by calling `prompt_engine` again with step-specific arguments
127 | 4. Server tracks progress and provides instructions for subsequent steps
128 | 5. Process continues until chain completion
129 | 
130 | **Features**:
131 | - LLM controls execution flow and decision-making
132 | - Natural conversation flow preservation
133 | - Automatic step progression with state tracking
134 | - Quality gates enabled by default (`gate_validation=true`)
135 | - Error recovery and retry capabilities
136 | - Context preservation between steps
137 | 
138 | **Output Format**: `🔗 **Chain Execution**: [Chain Name] | Step [N/Total] | [Next Instructions]`
139 | 
140 | **Example**:
141 | ```bash
142 | # Execute complete chain with automatic progression
143 | prompt_engine >>research_pipeline topic="AI Ethics" llm_driven_execution=true
144 | 
145 | # Manual step-by-step execution
146 | prompt_engine >>research_pipeline topic="AI Ethics" execution_mode="chain"
147 | # Returns instructions for Step 1, then call again based on instructions
148 | ```
149 | 
150 | ## Performance Characteristics
151 | 
152 | | Execution Mode | Speed         | Memory | CPU | Framework | Quality Gates | Best Use Case |
153 | |----------------|---------------|--------|-----|-----------|---------------|---------------|
154 | | **Prompt**     | ⚡ ~10-50ms   | Low    | Low | None      | Optional      | Variable substitution, formatting |
155 | | **Template**   | 🚀 ~100-500ms | Medium | Med | Active    | Optional      | Analysis, reasoning, quality output |
156 | | **Chain**      | 🔄 Variable   | Medium | Med | Active    | Default On    | Multi-step processes, complex orchestration |
157 | 
158 | ## Advanced Features
159 | 
160 | ### Automatic Mode Detection
161 | 
162 | When `execution_mode="auto"` (default):
163 | 
164 | 1. **Semantic Analysis**: Analyzes prompt structure and complexity
165 | 2. **Chain Detection**: Automatically detects chains based on presence of `chainSteps`
166 | 3. **Template Detection**: Complex arguments, template variables, or analysis requirements
167 | 4. **Prompt Fallback**: Simple variable substitution (default)
168 | 
169 | **Detection Logic**:
170 | ```typescript
171 | if (prompt.chainSteps?.length) return "chain"
172 | if (hasComplexArguments || requiresFramework) return "template"  
173 | return "prompt"  // Default for simple cases
174 | ```
175 | 
176 | ### Framework System Integration
177 | 
178 | **Active Framework Impact**:
179 | - **Prompt Mode**: No framework enhancement
180 | - **Template Mode**: Full framework processing with methodology guidance
181 | - **Chain Mode**: Framework-aware step instructions and validation
182 | 
183 | **Available Methodologies**:
184 | - **CAGEERF**: Comprehensive structured analysis (Context, Analysis, Goals, Execution, Evaluation, Refinement, Framework)
185 | - **ReACT**: Reasoning and Acting systematic problem-solving approach  
186 | - **5W1H**: Who, What, When, Where, Why, How systematic analysis framework
187 | - **SCAMPER**: Creative problem-solving (Substitute, Combine, Adapt, Modify, Put to other uses, Eliminate, Reverse)
188 | 
189 | ### Quality Gates Integration
190 | 
191 | **Gate Validation Levels**:
192 | - **Prompts**: Optional gates (`gate_validation=false` by default)
193 | - **Templates**: Optional gates (`gate_validation=true` recommended)
194 | - **Chains**: Automatic gates (`gate_validation=true` by default)
195 | 
196 | **Gate Types Available**:
197 | - Content analysis (length, readability, tone, grammar)
198 | - Structure validation (format, sections, hierarchy)
199 | - Pattern matching (keywords, patterns, links)
200 | - Custom logic (required fields, completeness, security)
201 | 
202 | ## Common Usage Patterns
203 | 
204 | ### Speed-Critical Operations
205 | 
206 | ```bash
207 | # Use prompt mode for rapid iteration and simple tasks
208 | prompt_engine >>format_json data="{{raw_data}}" execution_mode="prompt"
209 | prompt_engine >>generate_title content="{{article}}" execution_mode="prompt"
210 | ```
211 | 
212 | ### Analysis and Reasoning Tasks
213 | 
214 | ```bash
215 | # Templates provide framework methodology enhancement
216 | prompt_engine >>code_review code="{{source}}" execution_mode="template"
217 | prompt_engine >>market_analysis data="{{research}}" execution_mode="template" gate_validation=true
218 | ```
219 | 
220 | ### Complex Multi-Step Processes
221 | 
222 | ```bash
223 | # Chains handle iterative LLM-driven execution
224 | prompt_engine >>content_creation_workflow topic="{{subject}}" length="comprehensive" llm_driven_execution=true
225 | prompt_engine >>research_and_analysis_pipeline query="{{research_question}}" depth="thorough"
226 | ```
227 | 
228 | ### Framework-Specific Execution
229 | 
230 | ```bash
231 | # Switch framework and execute with methodology guidance
232 | system_control switch_framework framework="CAGEERF" reason="Comprehensive analysis needed"
233 | prompt_engine >>strategic_analysis situation="{{business_context}}" execution_mode="template"
234 | 
235 | # Different methodology for creative tasks  
236 | system_control switch_framework framework="SCAMPER" reason="Creative problem solving"
237 | prompt_engine >>innovation_workshop challenge="{{problem}}" execution_mode="template"
238 | ```
239 | 
240 | ## Troubleshooting
241 | 
242 | ### Mode Detection Issues
243 | 
244 | ```bash
245 | # Check what execution mode was detected and why
246 | system_control analytics
247 | 
248 | # View detailed execution history and mode usage
249 | system_control status
250 | 
251 | # Force specific mode if auto-detection is incorrect
252 | prompt_engine >>my_prompt input="data" execution_mode="template"
253 | ```
254 | 
255 | ### Performance Optimization
256 | 
257 | **Speed Priority**:
258 | - Use `execution_mode="prompt"` for maximum speed
259 | - Disable quality gates: `gate_validation=false`
260 | - Use simple variable names and minimal template logic
261 | 
262 | **Quality Priority**:
263 | - Use `execution_mode="template"` with appropriate framework
264 | - Enable quality gates: `gate_validation=true`  
265 | - Switch to methodology that matches your task type
266 | 
267 | **Complex Workflow Priority**:
268 | - Use `execution_mode="chain"` for multi-step processes
269 | - Enable `llm_driven_execution=true` for LLM-driven coordination
270 | - Let LLM control flow - don't force manual step control
271 | 
272 | ### Chain Execution Issues
273 | 
274 | **Chain Not Progressing**:
275 | ```bash
276 | # Check chain state and progress
277 | system_control status
278 | 
279 | # Reset chain state if stuck
280 | prompt_engine >>your_chain_name execution_mode="chain"  # Restarts from current step
281 | ```
282 | 
283 | **Chain Step Failures**:
284 | - Quality gates are enabled by default - check gate validation results
285 | - LLM instructions may need clarification - review step definitions
286 | - Framework methodology may not match chain requirements
287 | 
288 | ### Framework Integration Issues
289 | 
290 | ```bash
291 | # Verify active framework
292 | system_control status
293 | 
294 | # Check framework switching history and performance
295 | system_control analytics include_history=true
296 | 
297 | # Switch to appropriate framework for your task
298 | system_control switch_framework framework="ReACT" reason="Problem-solving task"
299 | ```
300 | 
301 | ## Migration Guide
302 | 
303 | ### From Simple to Complex Execution
304 | 
305 | **Development Phase**:
306 | 1. Start with **prompt mode** for rapid prototyping: `execution_mode="prompt"`
307 | 2. Test with various inputs and ensure variable substitution works correctly
308 | 
309 | **Quality Phase**:
310 | 3. Upgrade to **template mode** when output quality matters: `execution_mode="template"`
311 | 4. Choose appropriate framework methodology for your use case
312 | 5. Enable quality gates for validation: `gate_validation=true`
313 | 
314 | **Production Phase**:
315 | 6. Convert to **chain mode** for multi-step processes: `execution_mode="chain"`
316 | 7. Enable LLM-driven chain coordination: `llm_driven_execution=true`
317 | 8. Monitor execution analytics and optimize based on usage patterns
318 | 
319 | ### Framework Selection Guide
320 | 
321 | **Choose Framework Based on Task Type**:
322 | 
323 | - **CAGEERF**: Complex analysis, strategic planning, comprehensive evaluation
324 | - **ReACT**: Problem-solving, debugging, systematic reasoning tasks  
325 | - **5W1H**: Research, investigation, systematic information gathering
326 | - **SCAMPER**: Creative tasks, innovation, brainstorming, design thinking
327 | 
328 | ## System Integration
329 | 
330 | ### MCP Tool Coordination
331 | 
332 | ```bash
333 | # Complete workflow using all consolidated tools
334 | system_control status                           # Check system and framework state
335 | system_control switch_framework framework="CAGEERF"  # Set methodology
336 | prompt_engine >>analysis_task data="{{input}}" execution_mode="template"  # Execute with framework
337 | system_control analytics                        # Monitor performance
338 | ```
339 | 
340 | ### Analytics and Monitoring
341 | 
342 | **Execution Statistics**:
343 | - Mode usage distribution (prompt/template/chain percentages)
344 | - Framework usage patterns and switching frequency
345 | - Performance metrics per execution mode
346 | - Quality gate success rates and common failures
347 | 
348 | **Access Analytics**:
349 | ```bash
350 | # View comprehensive execution analytics
351 | system_control analytics include_history=true
352 | 
353 | # Monitor system health including execution performance
354 | system_control health
355 | 
356 | # Reset metrics if needed for fresh tracking
357 | system_control reset_metrics confirm=true
358 | ```
359 | 
360 | ## Best Practices
361 | 
362 | ### Execution Mode Selection
363 | 
364 | - **Start Simple**: Begin with automatic mode detection, override only when necessary
365 | - **Performance Testing**: Benchmark your specific use cases to choose optimal modes
366 | - **Framework Alignment**: Match execution mode with framework - templates benefit most from methodology
367 | - **Quality Requirements**: Use quality gates in template/chain modes for production workloads
368 | 
369 | ### Framework Integration
370 | 
371 | - **Task-Appropriate Frameworks**: Switch frameworks based on task type, not randomly
372 | - **Consistent Methodology**: Stick with one framework per logical workflow or project phase
373 | - **Performance Monitoring**: Track framework effectiveness for your specific use cases
374 | - **Strategic Switching**: Plan framework switches, don't change mid-workflow unnecessarily
375 | 
376 | ### Chain Development
377 | 
378 | - **Step Design**: Design clear, discrete steps that can be executed independently
379 | - **State Management**: Let the LLM handle state and flow - avoid over-constraining steps
380 | - **Error Recovery**: Design steps to be retryable and recoverable from failures
381 | - **Progress Tracking**: Monitor chain execution through system analytics
382 | 
383 | ### Quality Assurance
384 | 
385 | - **Gate Strategy**: Enable gates for production, disable for development speed
386 | - **Framework Quality**: Use appropriate methodology - each framework has quality strengths
387 | - **Validation Testing**: Test execution modes with realistic data before production
388 | - **Monitoring Setup**: Implement analytics monitoring for production workloads
389 | 
390 | ## Advanced Topics
391 | 
392 | ### Custom Chain Development
393 | 
394 | For creating sophisticated multi-step workflows:
395 | 
396 | ```bash
397 | # Define chain with clear step progression
398 | prompt_manager create_template name="custom_analysis_chain" category="analysis" \
399 |   content="Multi-step analysis workflow with data collection and synthesis" \
400 |   chain_steps='[
401 |     {"promptId": "data_collection", "stepName": "Data Collection"},
402 |     {"promptId": "analysis_processing", "stepName": "Analysis"},
403 |     {"promptId": "synthesis_generation", "stepName": "Synthesis"}
404 |   ]'
405 | ```
406 | 
407 | ### Performance Optimization Strategies
408 | 
409 | **For High-Throughput Scenarios**:
410 | - Batch similar executions using prompt mode
411 | - Cache framework contexts when possible  
412 | - Monitor memory usage during chain execution
413 | - Use analytics to identify bottlenecks
414 | 
415 | **For Quality-Critical Scenarios**:
416 | - Always enable quality gates in production
417 | - Use appropriate framework methodology consistently
418 | - Implement comprehensive error handling and retry logic
419 | - Monitor quality gate success rates and adjust criteria
420 | 
421 | ---
422 | 
423 | **Quick Summary**: The MCP server provides three intelligent execution modes accessible through the `prompt_engine` tool. Use automatic mode detection for most cases, prompt mode for speed, template mode for quality with framework enhancement, and chain mode for complex LLM-driven iterative processes. All modes integrate seamlessly with the framework system and quality gates for professional-grade AI prompt execution.
```

--------------------------------------------------------------------------------
/docs/template-development-guide.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Template Development Guide
  2 | 
  3 | ## Overview
  4 | 
  5 | This guide covers creating **framework-aware templates** that leverage the Claude Prompts MCP Server's methodology system for enhanced, systematic prompt execution. Templates represent the middle tier of our three-tier execution model, providing structured guidance and quality assurance.
  6 | 
  7 | ## Related Documentation
  8 | 
  9 | - **[Three-Tier Execution System](execution-architecture-guide.md)** - Understanding template execution in the broader system
 10 | - **[Prompt Format Guide](prompt-format-guide.md)** - Basic prompt formatting (foundation for templates)
 11 | - **[Chain System Analysis](chain-system-analysis.md)** - Using templates within chain workflows
 12 | - **[Enhanced Gate System](enhanced-gate-system.md)** - Quality validation for templates
 13 | - **[MCP Tools Reference](mcp-tools-reference.md)** - Using tools with template execution
 14 | 
 15 | ## What Are Framework-Aware Templates?
 16 | 
 17 | Framework-aware templates are enhanced prompts that:
 18 | - **Integrate with methodology guides** (CAGEERF, ReACT, 5W1H, SCAMPER)
 19 | - **Include system prompt injection** for structured thinking
 20 | - **Apply quality gates** for validation and consistency
 21 | - **Provide structured guidance** to LLMs for better outcomes
 22 | 
 23 | ## Template Structure
 24 | 
 25 | ### Basic Template Format
 26 | 
 27 | ```markdown
 28 | # Template Name
 29 | 
 30 | **🔄 TEMPLATE EXECUTION**: Framework-aware processing with {{framework}} methodology
 31 | 
 32 | ## System Message
 33 | You are an expert {{role}} who follows systematic approaches to {{task_type}}.
 34 | Use the active framework methodology to ensure comprehensive analysis.
 35 | 
 36 | ## User Message Template
 37 | {{user_content_with_variables}}
 38 | 
 39 | ## Arguments
 40 | - role: The expert role for this template
 41 | - task_type: Type of task being performed
 42 | - user_content_with_variables: Main template content
 43 | ```
 44 | 
 45 | ### Template Markers
 46 | 
 47 | Templates are identified by specific markers:
 48 | 
 49 | #### Execution Type Markers
 50 | ```markdown
 51 | **🔄 TEMPLATE EXECUTION**: Framework-aware processing
 52 | **⚡ EXECUTION REQUIRED**: Uses template execution for framework integration
 53 | ```
 54 | 
 55 | #### Framework Integration Markers
 56 | ```markdown
 57 | **📋 FRAMEWORK**: Uses active methodology ({{framework}}) for systematic approach
 58 | **🎯 METHODOLOGY**: Applies {{framework}} principles throughout execution
 59 | ```
 60 | 
 61 | ## Framework Integration
 62 | 
 63 | ### Available Frameworks
 64 | 
 65 | #### CAGEERF Framework
 66 | **Use for**: Comprehensive structured analysis
 67 | - **Context**: Understand the situation
 68 | - **Analysis**: Break down the problem  
 69 | - **Goals**: Define clear objectives
 70 | - **Execution**: Implement systematic approach
 71 | - **Evaluation**: Assess results
 72 | - **Refinement**: Improve based on feedback
 73 | - **Framework**: Apply methodology consistently
 74 | 
 75 | ```markdown
 76 | # CAGEERF Analysis Template
 77 | **🔄 TEMPLATE EXECUTION**: Uses CAGEERF methodology for systematic analysis
 78 | 
 79 | ## System Message
 80 | You are an expert analyst who follows the CAGEERF methodology for comprehensive evaluation.
 81 | Apply each phase systematically: Context → Analysis → Goals → Execution → Evaluation → Refinement → Framework consistency.
 82 | 
 83 | ## User Message Template
 84 | Analyze the following using CAGEERF methodology:
 85 | {{content}}
 86 | 
 87 | Focus areas: {{focus_areas}}
 88 | ```
 89 | 
 90 | #### ReACT Framework
 91 | **Use for**: Reasoning and action-oriented tasks
 92 | - **Reasoning**: Think through the problem systematically
 93 | - **Acting**: Take concrete steps based on reasoning
 94 | 
 95 | ```markdown
 96 | # ReACT Problem Solving Template
 97 | **🔄 TEMPLATE EXECUTION**: Uses ReACT methodology for reasoning and action
 98 | 
 99 | ## System Message  
100 | You are an expert problem solver who uses ReACT (Reasoning and Acting) methodology.
101 | For each step: 1) Reason about the situation, 2) Act based on that reasoning.
102 | 
103 | ## User Message Template
104 | Apply ReACT methodology to solve:
105 | {{problem_statement}}
106 | 
107 | Available actions: {{available_actions}}
108 | ```
109 | 
110 | #### 5W1H Framework
111 | **Use for**: Comprehensive information gathering
112 | - **Who**: Key stakeholders and people involved
113 | - **What**: Core facts and details
114 | - **When**: Timing and sequence
115 | - **Where**: Location and context
116 | - **Why**: Motivations and reasons
117 | - **How**: Methods and processes
118 | 
119 | ```markdown
120 | # 5W1H Analysis Template
121 | **🔄 TEMPLATE EXECUTION**: Uses 5W1H methodology for comprehensive analysis
122 | 
123 | ## System Message
124 | You are an expert investigator who uses the 5W1H framework for thorough analysis.
125 | Address each question systematically: Who, What, When, Where, Why, and How.
126 | 
127 | ## User Message Template
128 | Analyze using 5W1H framework:
129 | {{subject}}
130 | 
131 | Priority questions: {{priority_questions}}
132 | ```
133 | 
134 | #### SCAMPER Framework  
135 | **Use for**: Creative problem-solving and innovation
136 | - **Substitute**: What can be substituted?
137 | - **Combine**: What can be combined?
138 | - **Adapt**: What can be adapted?
139 | - **Modify**: What can be modified?
140 | - **Put to other uses**: How else can this be used?
141 | - **Eliminate**: What can be eliminated?
142 | - **Reverse**: What can be reversed?
143 | 
144 | ```markdown
145 | # SCAMPER Innovation Template
146 | **🔄 TEMPLATE EXECUTION**: Uses SCAMPER methodology for creative problem-solving
147 | 
148 | ## System Message
149 | You are an innovation expert who applies SCAMPER methodology for creative solutions.
150 | Systematically explore: Substitute, Combine, Adapt, Modify, Put to other uses, Eliminate, Reverse.
151 | 
152 | ## User Message Template
153 | Apply SCAMPER methodology to innovate on:
154 | {{concept}}
155 | 
156 | Focus areas: {{focus_areas}}
157 | ```
158 | 
159 | ### Framework Selection
160 | 
161 | #### Automatic Framework Application
162 | Templates automatically use the **active framework** set in the system:
163 | 
164 | ```bash
165 | # Check current framework
166 | system_control status
167 | 
168 | # Switch framework for template execution
169 | system_control switch_framework framework=CAGEERF reason="Need comprehensive analysis"
170 | ```
171 | 
172 | #### Framework-Specific Templates
173 | Create templates optimized for specific frameworks:
174 | 
175 | ```markdown
176 | # CAGEERF-Optimized Template
177 | **📋 FRAMEWORK**: Optimized for CAGEERF methodology
178 | 
179 | This template works best with CAGEERF framework active.
180 | To use: `system_control switch_framework framework=CAGEERF`
181 | ```
182 | 
183 | ## Template Development Process
184 | 
185 | ### Step 1: Define Template Purpose
186 | 
187 | ```markdown
188 | # Template Planning
189 | - **Purpose**: What specific task does this template address?
190 | - **Target Framework**: Which methodology best supports this task?
191 | - **Complexity Level**: Simple, moderate, or complex template?
192 | - **Quality Requirements**: What validation is needed?
193 | ```
194 | 
195 | ### Step 2: Choose Template Structure
196 | 
197 | #### Simple Template (Basic framework integration)
198 | ```markdown
199 | # Simple Analysis Template
200 | **🔄 TEMPLATE EXECUTION**: Framework-aware analysis
201 | 
202 | Analyze: {{content}}
203 | Focus: {{focus_area}}
204 | ```
205 | 
206 | #### Structured Template (Full framework integration)
207 | ```markdown
208 | # Comprehensive Analysis Template  
209 | **🔄 TEMPLATE EXECUTION**: Uses {{framework}} for systematic analysis
210 | 
211 | ## System Message
212 | You are an expert analyst following {{framework}} methodology.
213 | [Detailed system instructions...]
214 | 
215 | ## User Message Template  
216 | [Structured template with multiple variables...]
217 | 
218 | ## Arguments
219 | - content: Content to analyze
220 | - framework: Active methodology framework
221 | - focus_area: Specific focus for analysis
222 | ```
223 | 
224 | #### Advanced Template (Custom framework guidance)
225 | ```markdown
226 | # Advanced Research Template
227 | **🔄 TEMPLATE EXECUTION**: Advanced framework integration with custom quality gates
228 | 
229 | ## Framework-Specific Guidance
230 | {{#if framework == "CAGEERF"}}
231 | Apply CAGEERF phases systematically...
232 | {{elif framework == "ReACT"}}
233 | Use reasoning-action cycles...
234 | {{else}}
235 | Apply general systematic approach...
236 | {{/if}}
237 | 
238 | [Rest of template...]
239 | ```
240 | 
241 | ### Step 3: Implement Template Logic
242 | 
243 | #### Variable Definition
244 | ```markdown
245 | ## Arguments
246 | - content (required): Primary content for processing
247 | - focus_area (optional): Specific area to emphasize
248 | - depth_level (optional, default: "moderate"): Analysis depth
249 | - output_format (optional, default: "markdown"): Desired output format
250 | ```
251 | 
252 | #### Conditional Logic
253 | ```markdown
254 | ## User Message Template
255 | Analyze the following content:
256 | {{content}}
257 | 
258 | {{#if focus_area}}
259 | Pay special attention to: {{focus_area}}
260 | {{/if}}
261 | 
262 | {{#if depth_level == "deep"}}
263 | Provide comprehensive analysis including edge cases and implications.
264 | {{elif depth_level == "surface"}}
265 | Provide high-level overview focusing on key points.
266 | {{else}}
267 | Provide balanced analysis covering main points and key details.
268 | {{/if}}
269 | ```
270 | 
271 | ### Step 4: Add Quality Gates
272 | 
273 | #### Template-Level Quality Requirements
274 | ```markdown
275 | # Template with Quality Gates
276 | **🔄 TEMPLATE EXECUTION**: Framework-aware with enhanced validation
277 | **🛡️ QUALITY GATES**: Enabled - Content analysis, structure validation, methodology compliance
278 | 
279 | [Template content...]
280 | ```
281 | 
282 | #### Custom Quality Criteria
283 | ```markdown
284 | ## Quality Requirements
285 | - Minimum response length: 500 words
286 | - Must include framework methodology application
287 | - Structured output with clear sections
288 | - Evidence-based conclusions
289 | ```
290 | 
291 | ## Advanced Template Features
292 | 
293 | ### Nunjucks Template Features
294 | 
295 | #### Loops and Iteration
296 | ```markdown
297 | ## Analysis Points
298 | {{#each analysis_points}}
299 | ### {{@index + 1}}. {{this.title}}
300 | {{this.description}}
301 | 
302 | {{/each}}
303 | ```
304 | 
305 | #### Filters and Functions
306 | ```markdown
307 | ## Processed Content
308 | Original length: {{content | length}} characters
309 | Summary: {{content | truncate(200)}}
310 | Formatted: {{content | upper | trim}}
311 | ```
312 | 
313 | #### Macros for Reusable Components
314 | ```markdown
315 | {{#macro section_header(title, framework)}}
316 | ## {{title}}
317 | *Using {{framework}} methodology*
318 | {{/macro}}
319 | 
320 | {{section_header("Analysis", framework)}}
321 | Your analysis content here...
322 | ```
323 | 
324 | ### Framework Context Injection
325 | 
326 | #### Accessing Framework Information
327 | ```markdown
328 | ## Current Framework Context
329 | - **Active Framework**: {{framework}}  
330 | - **Methodology Guide**: {{framework_description}}
331 | - **Quality Criteria**: {{framework_quality_gates}}
332 | 
333 | Apply {{framework}} principles throughout this analysis.
334 | ```
335 | 
336 | #### Framework-Specific Customization
337 | ```markdown
338 | {{#if framework == "CAGEERF"}}
339 | ## CAGEERF Analysis Structure
340 | 1. **Context**: {{context_analysis}}
341 | 2. **Analysis**: {{detailed_analysis}}  
342 | 3. **Goals**: {{goal_definition}}
343 | 4. **Execution**: {{implementation_plan}}
344 | 5. **Evaluation**: {{results_assessment}}
345 | 6. **Refinement**: {{improvement_suggestions}}
346 | 7. **Framework**: {{methodology_consistency}}
347 | {{/if}}
348 | ```
349 | 
350 | ## Testing Templates
351 | 
352 | ### Local Testing
353 | 
354 | ```bash
355 | # Test template execution
356 | prompt_engine >>your_template content="test content" focus_area="key points"
357 | 
358 | # Test with specific framework
359 | system_control switch_framework framework=CAGEERF
360 | prompt_engine >>your_template execution_mode=template
361 | ```
362 | 
363 | ### Quality Gate Testing
364 | 
365 | ```bash
366 | # Test with quality gates enabled
367 | prompt_engine >>your_template gate_validation=true
368 | 
369 | # Test quality gate compliance
370 | prompt_engine >>your_template execution_mode=template gate_validation=true
371 | ```
372 | 
373 | ### Framework Integration Testing
374 | 
375 | ```bash
376 | # Test with different frameworks
377 | system_control switch_framework framework=ReACT
378 | prompt_engine >>your_template
379 | 
380 | system_control switch_framework framework=5W1H  
381 | prompt_engine >>your_template
382 | 
383 | # Compare framework-specific outputs
384 | ```
385 | 
386 | ## Best Practices
387 | 
388 | ### Template Design
389 | 
390 | #### DO:
391 | - **Use clear template markers** for execution type identification
392 | - **Define all required arguments** with descriptions
393 | - **Include framework integration markers** for methodology awareness
394 | - **Structure templates logically** with clear sections
395 | - **Test across different frameworks** to ensure compatibility
396 | 
397 | #### DON'T:
398 | - **Hard-code framework references** - use {{framework}} variables
399 | - **Create overly complex templates** - prefer clarity over cleverness
400 | - **Ignore quality gate requirements** - design for validation
401 | - **Mix execution tiers** - keep templates focused on their tier
402 | 
403 | ### Performance Optimization
404 | 
405 | #### Template Efficiency
406 | - **Minimize complex conditional logic**
407 | - **Use efficient Nunjucks operations**
408 | - **Cache reusable template components**
409 | - **Optimize variable substitution**
410 | 
411 | #### Framework Integration
412 | - **Leverage active framework selection** rather than switching
413 | - **Use framework-appropriate templates** for best performance
414 | - **Cache framework context** when possible
415 | 
416 | ### Quality Assurance
417 | 
418 | #### Template Validation
419 | - **Test all argument combinations**
420 | - **Verify framework integration works correctly**
421 | - **Validate output structure and format**
422 | - **Check quality gate compliance**
423 | 
424 | #### Documentation
425 | - **Document template purpose clearly**
426 | - **Provide usage examples**
427 | - **List framework compatibility**
428 | - **Include troubleshooting guidance**
429 | 
430 | ## Migration from Basic Prompts
431 | 
432 | ### Converting Existing Prompts
433 | 
434 | #### Step 1: Add Template Markers
435 | ```markdown
436 | # Before (basic prompt)
437 | Analyze this content: {{content}}
438 | 
439 | # After (template)  
440 | **🔄 TEMPLATE EXECUTION**: Framework-aware analysis
441 | 
442 | Analyze this content using systematic methodology: {{content}}
443 | ```
444 | 
445 | #### Step 2: Add Framework Integration
446 | ```markdown
447 | # Enhanced template
448 | **🔄 TEMPLATE EXECUTION**: Uses {{framework}} methodology
449 | 
450 | ## System Message
451 | You are an expert analyst applying {{framework}} methodology for systematic analysis.
452 | 
453 | ## User Message Template
454 | Apply {{framework}} principles to analyze: {{content}}
455 | ```
456 | 
457 | #### Step 3: Add Quality Requirements
458 | ```markdown
459 | # Final template with quality gates
460 | **🔄 TEMPLATE EXECUTION**: Framework-aware with quality validation
461 | **🛡️ QUALITY GATES**: Content analysis, methodology compliance
462 | 
463 | [Template content with framework integration]
464 | ```
465 | 
466 | ## Troubleshooting
467 | 
468 | ### Common Issues
469 | 
470 | #### Template Not Using Framework
471 | **Problem**: Template executes as basic prompt instead of framework-aware template
472 | **Solution**: Add proper template execution markers and check framework is active
473 | 
474 | #### Quality Gate Failures  
475 | **Problem**: Template fails validation
476 | **Solution**: Review quality gate requirements and adjust template structure
477 | 
478 | #### Variable Substitution Issues
479 | **Problem**: Variables not being replaced correctly
480 | **Solution**: Check variable names match argument definitions exactly
481 | 
482 | ### Debug Information
483 | 
484 | Enable verbose logging to debug template execution:
485 | ```bash
486 | npm run start:verbose
487 | ```
488 | 
489 | This shows:
490 | - Template execution tier detection
491 | - Framework integration process
492 | - Quality gate evaluation results
493 | - Variable substitution details
494 | 
495 | ## Examples Library
496 | 
497 | ### Content Analysis Template
498 | ```markdown
499 | # Content Analysis Template
500 | **🔄 TEMPLATE EXECUTION**: Framework-aware content analysis
501 | 
502 | ## System Message
503 | You are an expert content analyst who uses systematic methodology for comprehensive analysis.
504 | Apply the active framework to ensure thorough and structured evaluation.
505 | 
506 | ## User Message Template
507 | Analyze the following content using {{framework}} methodology:
508 | 
509 | **Content:**
510 | {{content}}
511 | 
512 | **Analysis Focus:**
513 | {{#if focus_areas}}
514 | Pay special attention to: {{focus_areas}}
515 | {{else}}
516 | Provide comprehensive analysis across all relevant dimensions.
517 | {{/if}}
518 | 
519 | **Output Requirements:**
520 | - Use {{framework}} structured approach
521 | - Provide evidence-based insights
522 | - Include actionable recommendations
523 | - Maintain systematic methodology throughout
524 | 
525 | ## Arguments
526 | - content: Content to analyze (required)
527 | - focus_areas: Specific areas to emphasize (optional)
528 | ```
529 | 
530 | ### Problem-Solving Template
531 | ```markdown
532 | # Systematic Problem Solving Template
533 | **🔄 TEMPLATE EXECUTION**: Framework-driven problem solving
534 | 
535 | ## System Message
536 | You are an expert problem solver who applies systematic methodology to address complex challenges.
537 | Use the active framework to ensure comprehensive problem analysis and solution development.
538 | 
539 | ## User Message Template
540 | Apply {{framework}} methodology to solve this problem:
541 | 
542 | **Problem Statement:**
543 | {{problem}}
544 | 
545 | **Constraints:**
546 | {{constraints}}
547 | 
548 | **Available Resources:**
549 | {{resources}}
550 | 
551 | **Success Criteria:**
552 | {{success_criteria}}
553 | 
554 | Follow {{framework}} principles to:
555 | 1. Analyze the problem systematically
556 | 2. Develop structured solutions
557 | 3. Evaluate options methodically
558 | 4. Provide implementation guidance
559 | 
560 | ## Arguments
561 | - problem: Problem description (required)
562 | - constraints: Known limitations (required)
563 | - resources: Available resources (optional)
564 | - success_criteria: Definition of success (required)
565 | ```
566 | 
567 | This guide provides the foundation for creating powerful, framework-aware templates that leverage the full capabilities of the Claude Prompts MCP Server's methodology system.
```

--------------------------------------------------------------------------------
/server/src/mcp-tools/prompt-manager/operations/file-operations.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * File system and category management operations
  3 |  */
  4 | 
  5 | import * as fs from "fs/promises";
  6 | import { readFile } from "fs/promises";
  7 | import path from "path";
  8 | import { Logger } from "../../../logging/index.js";
  9 | import { ConfigManager } from "../../../config/index.js";
 10 | import { PromptData, PromptsConfigFile } from "../../../types/index.js";
 11 | import { safeWriteFile } from "../../../prompts/promptUtils.js";
 12 | import {
 13 |   OperationResult,
 14 |   CategoryResult,
 15 |   FileOperationResult,
 16 |   PromptManagerDependencies
 17 | } from "../core/types.js";
 18 | import { CategoryManager } from "../utils/category-manager.js";
 19 | 
 20 | /**
 21 |  * File system operations for prompt management
 22 |  */
 23 | export class FileOperations {
 24 |   private logger: Logger;
 25 |   private configManager: ConfigManager;
 26 |   private categoryManager: CategoryManager;
 27 | 
 28 |   constructor(dependencies: Pick<PromptManagerDependencies, 'logger' | 'configManager'>) {
 29 |     this.logger = dependencies.logger;
 30 |     this.configManager = dependencies.configManager;
 31 |     this.categoryManager = new CategoryManager(this.logger);
 32 |   }
 33 | 
 34 |   /**
 35 |    * Update prompt implementation (shared by create/update)
 36 |    */
 37 |   async updatePromptImplementation(promptData: any): Promise<OperationResult> {
 38 |     const PROMPTS_FILE = this.configManager.getPromptsFilePath();
 39 |     const messages: string[] = [];
 40 | 
 41 |     const fileContent = await readFile(PROMPTS_FILE, "utf8");
 42 |     const promptsConfig = JSON.parse(fileContent) as PromptsConfigFile;
 43 | 
 44 |     if (!promptsConfig.categories) promptsConfig.categories = [];
 45 |     if (!promptsConfig.imports) promptsConfig.imports = [];
 46 | 
 47 |     // Ensure category exists
 48 |     const { effectiveCategory, created: categoryCreated } =
 49 |       await this.categoryManager.ensureCategoryExists(promptData.category, promptsConfig, PROMPTS_FILE);
 50 | 
 51 |     if (categoryCreated) {
 52 |       messages.push(`✅ Created category: '${effectiveCategory}'`);
 53 |     }
 54 | 
 55 |     // Create/update prompt file
 56 |     const { exists: promptExists } = await this.createOrUpdatePromptFile(
 57 |       promptData,
 58 |       effectiveCategory,
 59 |       PROMPTS_FILE
 60 |     );
 61 | 
 62 |     messages.push(`✅ ${promptExists ? 'Updated' : 'Created'} prompt file and registry entry`);
 63 | 
 64 |     return {
 65 |       message: messages.join('\n'),
 66 |       affectedFiles: [`${promptData.id}.md`]
 67 |     };
 68 |   }
 69 | 
 70 |   /**
 71 |    * Delete prompt implementation
 72 |    */
 73 |   async deletePromptImplementation(id: string): Promise<OperationResult> {
 74 |     const PROMPTS_FILE = this.configManager.getPromptsFilePath();
 75 |     const promptsConfigDir = path.dirname(PROMPTS_FILE);
 76 |     const messages: string[] = [];
 77 |     const affectedFiles: string[] = [];
 78 | 
 79 |     const fileContent = await readFile(PROMPTS_FILE, "utf8");
 80 |     const promptsConfig = JSON.parse(fileContent) as PromptsConfigFile;
 81 | 
 82 |     let promptFound = false;
 83 | 
 84 |     // Search through category imports
 85 |     for (const categoryImport of promptsConfig.imports || []) {
 86 |       const categoryPath = path.join(promptsConfigDir, categoryImport);
 87 | 
 88 |       try {
 89 |         const categoryContent = await readFile(categoryPath, "utf8");
 90 |         const categoryData = JSON.parse(categoryContent);
 91 | 
 92 |         const promptIndex = categoryData.prompts.findIndex((p: PromptData) => p.id === id);
 93 | 
 94 |         if (promptIndex > -1) {
 95 |           const promptEntry = categoryData.prompts[promptIndex];
 96 | 
 97 |           // Remove from category
 98 |           categoryData.prompts.splice(promptIndex, 1);
 99 |           await safeWriteFile(categoryPath, JSON.stringify(categoryData, null, 2), "utf8");
100 | 
101 |           // Delete markdown file
102 |           const markdownPath = path.join(path.dirname(categoryPath), promptEntry.file);
103 |           try {
104 |             await fs.unlink(markdownPath);
105 |             messages.push(`✅ Deleted prompt file: ${promptEntry.file}`);
106 |             affectedFiles.push(promptEntry.file);
107 |           } catch (unlinkError: any) {
108 |             if (unlinkError.code !== "ENOENT") {
109 |               messages.push(`⚠️ Could not delete file: ${unlinkError.message}`);
110 |             }
111 |           }
112 | 
113 |           messages.push(`✅ Removed from category: ${categoryImport}`);
114 |           promptFound = true;
115 | 
116 |           // Automatically clean up empty category
117 |           if (categoryData.prompts.length === 0) {
118 |             this.logger.info(`Category ${categoryImport} is now empty, performing automatic cleanup`);
119 |             const cleanupResult = await this.categoryManager.cleanupEmptyCategory(categoryImport, promptsConfig, PROMPTS_FILE);
120 |             messages.push(`🧹 **Automatic Category Cleanup**:\n${cleanupResult.message}`);
121 |           }
122 | 
123 |           break;
124 |         }
125 |       } catch (error) {
126 |         this.logger.warn(`Could not process category file: ${categoryPath}`, error);
127 |       }
128 |     }
129 | 
130 |     if (!promptFound) {
131 |       throw new Error(`Prompt not found: ${id}`);
132 |     }
133 | 
134 |     return {
135 |       message: messages.join('\n'),
136 |       affectedFiles
137 |     };
138 |   }
139 | 
140 |   /**
141 |    * Create or update prompt file
142 |    */
143 |   async createOrUpdatePromptFile(
144 |     promptData: any,
145 |     effectiveCategory: string,
146 |     promptsFile: string
147 |   ): Promise<FileOperationResult> {
148 |     const promptFilename = `${promptData.id}.md`;
149 |     const categoryDir = path.join(path.dirname(promptsFile), effectiveCategory);
150 |     const promptPath = path.join(categoryDir, promptFilename);
151 | 
152 |     // Create markdown content
153 |     let content = `# ${promptData.name}\n\n`;
154 |     content += `## Description\n${promptData.description}\n\n`;
155 | 
156 |     if (promptData.systemMessage) {
157 |       content += `## System Message\n${promptData.systemMessage}\n\n`;
158 |     }
159 | 
160 |     content += `## User Message Template\n${promptData.userMessageTemplate}\n`;
161 | 
162 |     // Build gate configuration section separately
163 |     let gateConfigSection = '';
164 |     this.logger.error(`[GATE-TRACE] 💾 FILE-OPS Gate Configuration Check for ${promptData.id}:`, {
165 |       hasGateConfiguration: !!promptData.gateConfiguration,
166 |       gateConfigType: typeof promptData.gateConfiguration,
167 |       gateConfigContent: promptData.gateConfiguration,
168 |       promptId: promptData.id
169 |     });
170 | 
171 |     if (promptData.gateConfiguration) {
172 |       this.logger.error(`[GATE-TRACE] ✅ Building gate configuration section for prompt ${promptData.id}`);
173 |       gateConfigSection = `\n## Gate Configuration\n\n`;
174 |       gateConfigSection += `\`\`\`json\n`;
175 |       const gateConfigJson = JSON.stringify(promptData.gateConfiguration, null, 2);
176 |       gateConfigSection += gateConfigJson;
177 |       gateConfigSection += `\n\`\`\`\n`;
178 |       this.logger.error(`[GATE-TRACE] 📝 Gate configuration JSON content:`, gateConfigJson);
179 |     } else {
180 |       this.logger.error(`[GATE-TRACE] ❌ NO GATE CONFIGURATION FOUND for prompt ${promptData.id}`);
181 |     }
182 | 
183 |     // Build chain steps section
184 |     let chainStepsSection = '';
185 |     if ((promptData.chainSteps?.length ?? 0) > 0) {
186 |       chainStepsSection = `\n## Chain Steps\n\n`;
187 |       promptData.chainSteps.forEach((step: any, index: number) => {
188 |         chainStepsSection += `${index + 1}. **${step.stepName}** (${step.promptId})\n`;
189 |         if (step.inputMapping) {
190 |           chainStepsSection += `   - Input Mapping: ${JSON.stringify(step.inputMapping)}\n`;
191 |         }
192 |         if (step.outputMapping) {
193 |           chainStepsSection += `   - Output Mapping: ${JSON.stringify(step.outputMapping)}\n`;
194 |         }
195 |         chainStepsSection += `\n`;
196 |       });
197 |     }
198 | 
199 |     // Check if file exists and handle Gate Configuration replacement
200 |     const existsBefore = await fs.access(promptPath).then(() => true).catch(() => false);
201 | 
202 |     if (existsBefore && gateConfigSection) {
203 |       try {
204 |         // Read existing file to preserve structure and replace Gate Configuration section
205 |         const existingContent = await readFile(promptPath, "utf8");
206 | 
207 |         // Remove ALL existing Gate Configuration sections (handles multiple duplicates)
208 |         const gateConfigRegex = /## Gate Configuration\s*\n```json\s*\n[\s\S]*?\n```\s*/g;
209 |         let cleanedContent = existingContent.replace(gateConfigRegex, '');
210 | 
211 |         // Find insertion point - after User Message Template, before Chain Steps or end
212 |         const chainStepsIndex = cleanedContent.indexOf('## Chain Steps');
213 | 
214 |         if (chainStepsIndex > 0) {
215 |           // Insert gate config before Chain Steps
216 |           content = cleanedContent.slice(0, chainStepsIndex).trimEnd() + '\n' +
217 |                     gateConfigSection + '\n' +
218 |                     cleanedContent.slice(chainStepsIndex);
219 |           this.logger.error(`[GATE-TRACE] ✅ Replaced Gate Configuration section (inserted before Chain Steps)`);
220 |         } else {
221 |           // No Chain Steps - append at end
222 |           content = cleanedContent.trimEnd() + '\n' + gateConfigSection;
223 |           this.logger.error(`[GATE-TRACE] ✅ Replaced Gate Configuration section (appended at end)`);
224 |         }
225 |       } catch (readError) {
226 |         // If read fails, fall back to full regeneration
227 |         this.logger.warn(`[GATE-TRACE] ⚠️ Failed to read existing file for section replacement, using full regeneration`, readError);
228 |         content += gateConfigSection + chainStepsSection;
229 |       }
230 |     } else {
231 |       // New file or no gate configuration - use simple append
232 |       content += gateConfigSection + chainStepsSection;
233 |       if (gateConfigSection) {
234 |         this.logger.error(`[GATE-TRACE] ✅ Added Gate Configuration section to new file`);
235 |       }
236 |     }
237 | 
238 |     // Write markdown file
239 |     await safeWriteFile(promptPath, content, "utf8");
240 | 
241 |     // Update category prompts.json
242 |     const categoryPromptsPath = path.join(categoryDir, "prompts.json");
243 |     let categoryData: { prompts: PromptData[] };
244 | 
245 |     try {
246 |       const categoryContent = await readFile(categoryPromptsPath, "utf8");
247 |       categoryData = JSON.parse(categoryContent);
248 |     } catch {
249 |       categoryData = { prompts: [] };
250 |     }
251 | 
252 |     const promptEntry: PromptData = {
253 |       id: promptData.id,
254 |       name: promptData.name,
255 |       category: effectiveCategory,
256 |       description: promptData.description,
257 |       file: promptFilename,
258 |       arguments: promptData.arguments || []
259 |     };
260 | 
261 |     const existingIndex = categoryData.prompts.findIndex(p => p.id === promptData.id);
262 |     if (existingIndex > -1) {
263 |       categoryData.prompts[existingIndex] = promptEntry;
264 |     } else {
265 |       categoryData.prompts.push(promptEntry);
266 |     }
267 | 
268 |     await safeWriteFile(categoryPromptsPath, JSON.stringify(categoryData, null, 2), "utf8");
269 | 
270 |     return {
271 |       exists: existsBefore,
272 |       path: promptPath
273 |     };
274 |   }
275 | 
276 |   /**
277 |    * Ensure category exists in the configuration
278 |    */
279 |   async ensureCategoryExists(
280 |     category: string,
281 |     promptsConfig: PromptsConfigFile,
282 |     promptsFile: string
283 |   ): Promise<CategoryResult> {
284 |     return this.categoryManager.ensureCategoryExists(category, promptsConfig, promptsFile);
285 |   }
286 | 
287 |   /**
288 |    * Clean up empty category
289 |    */
290 |   async cleanupEmptyCategory(
291 |     categoryImport: string,
292 |     promptsConfig: PromptsConfigFile,
293 |     promptsFile: string
294 |   ): Promise<OperationResult> {
295 |     return this.categoryManager.cleanupEmptyCategory(categoryImport, promptsConfig, promptsFile);
296 |   }
297 | 
298 |   /**
299 |    * Validate file system state
300 |    */
301 |   async validateFileSystemState(): Promise<{
302 |     valid: boolean;
303 |     issues: string[];
304 |     stats: Record<string, number>;
305 |   }> {
306 |     const issues: string[] = [];
307 |     const PROMPTS_FILE = this.configManager.getPromptsFilePath();
308 | 
309 |     try {
310 |       // Check main config file
311 |       const fileContent = await readFile(PROMPTS_FILE, "utf8");
312 |       const promptsConfig = JSON.parse(fileContent) as PromptsConfigFile;
313 | 
314 |       // Validate categories and imports
315 |       const stats = await this.categoryManager.getCategoryStats(promptsConfig.imports || [], PROMPTS_FILE);
316 | 
317 |       // Check each category structure
318 |       for (const categoryImport of promptsConfig.imports || []) {
319 |         const validation = await this.categoryManager.validateCategoryStructure(categoryImport, PROMPTS_FILE);
320 |         if (!validation.valid) {
321 |           issues.push(`Category ${categoryImport}: ${validation.issues.join(', ')}`);
322 |         }
323 |       }
324 | 
325 |       return {
326 |         valid: issues.length === 0,
327 |         issues,
328 |         stats
329 |       };
330 | 
331 |     } catch (error) {
332 |       issues.push(`Failed to validate file system: ${error instanceof Error ? error.message : String(error)}`);
333 |       return {
334 |         valid: false,
335 |         issues,
336 |         stats: {}
337 |       };
338 |     }
339 |   }
340 | 
341 |   /**
342 |    * Backup prompt files
343 |    */
344 |   async backupPrompts(): Promise<{
345 |     backupPath: string;
346 |     fileCount: number;
347 |   }> {
348 |     const PROMPTS_FILE = this.configManager.getPromptsFilePath();
349 |     const promptsDir = path.dirname(PROMPTS_FILE);
350 |     const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
351 |     const backupDir = path.join(promptsDir, `backup-${timestamp}`);
352 | 
353 |     await fs.mkdir(backupDir, { recursive: true });
354 | 
355 |     // Copy main config
356 |     await fs.copyFile(PROMPTS_FILE, path.join(backupDir, 'promptsConfig.json'));
357 |     let fileCount = 1;
358 | 
359 |     // Copy all categories and their prompts
360 |     const fileContent = await readFile(PROMPTS_FILE, "utf8");
361 |     const promptsConfig = JSON.parse(fileContent) as PromptsConfigFile;
362 | 
363 |     for (const categoryImport of promptsConfig.imports || []) {
364 |       const sourcePath = path.join(promptsDir, categoryImport);
365 |       const targetPath = path.join(backupDir, categoryImport);
366 | 
367 |       // Create category directory in backup
368 |       await fs.mkdir(path.dirname(targetPath), { recursive: true });
369 | 
370 |       try {
371 |         // Copy category config
372 |         await fs.copyFile(sourcePath, targetPath);
373 |         fileCount++;
374 | 
375 |         // Copy all markdown files in category
376 |         const categoryDir = path.dirname(sourcePath);
377 |         const files = await fs.readdir(categoryDir);
378 | 
379 |         for (const file of files) {
380 |           if (file.endsWith('.md')) {
381 |             const sourceFile = path.join(categoryDir, file);
382 |             const targetFile = path.join(path.dirname(targetPath), file);
383 |             await fs.copyFile(sourceFile, targetFile);
384 |             fileCount++;
385 |           }
386 |         }
387 |       } catch (error) {
388 |         this.logger.warn(`Failed to backup category ${categoryImport}:`, error);
389 |       }
390 |     }
391 | 
392 |     this.logger.info(`Created backup with ${fileCount} files at ${backupDir}`);
393 | 
394 |     return {
395 |       backupPath: backupDir,
396 |       fileCount
397 |     };
398 |   }
399 | 
400 |   /**
401 |    * Get file system statistics
402 |    */
403 |   async getFileSystemStats(): Promise<{
404 |     totalCategories: number;
405 |     totalPrompts: number;
406 |     totalFiles: number;
407 |     diskUsage: number;
408 |   }> {
409 |     const PROMPTS_FILE = this.configManager.getPromptsFilePath();
410 |     const promptsDir = path.dirname(PROMPTS_FILE);
411 | 
412 |     let totalCategories = 0;
413 |     let totalPrompts = 0;
414 |     let totalFiles = 0;
415 |     let diskUsage = 0;
416 | 
417 |     try {
418 |       const fileContent = await readFile(PROMPTS_FILE, "utf8");
419 |       const promptsConfig = JSON.parse(fileContent) as PromptsConfigFile;
420 | 
421 |       totalCategories = promptsConfig.categories?.length || 0;
422 | 
423 |       const stats = await this.categoryManager.getCategoryStats(promptsConfig.imports || [], PROMPTS_FILE);
424 |       totalPrompts = Object.values(stats).reduce((sum, count) => sum + count, 0);
425 | 
426 |       // Count files and calculate disk usage
427 |       const calculateDirSize = async (dirPath: string): Promise<{ files: number; size: number }> => {
428 |         let files = 0;
429 |         let size = 0;
430 | 
431 |         try {
432 |           const items = await fs.readdir(dirPath, { withFileTypes: true });
433 | 
434 |           for (const item of items) {
435 |             const itemPath = path.join(dirPath, item.name);
436 | 
437 |             if (item.isDirectory()) {
438 |               const subResult = await calculateDirSize(itemPath);
439 |               files += subResult.files;
440 |               size += subResult.size;
441 |             } else {
442 |               files++;
443 |               const stat = await fs.stat(itemPath);
444 |               size += stat.size;
445 |             }
446 |           }
447 |         } catch (error) {
448 |           // Ignore errors for inaccessible directories
449 |         }
450 | 
451 |         return { files, size };
452 |       };
453 | 
454 |       const dirStats = await calculateDirSize(promptsDir);
455 |       totalFiles = dirStats.files;
456 |       diskUsage = dirStats.size;
457 | 
458 |     } catch (error) {
459 |       this.logger.warn('Failed to calculate file system stats:', error);
460 |     }
461 | 
462 |     return {
463 |       totalCategories,
464 |       totalPrompts,
465 |       totalFiles,
466 |       diskUsage
467 |     };
468 |   }
469 | }
```

--------------------------------------------------------------------------------
/server/src/frameworks/prompt-guidance/methodology-tracker.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Methodology Tracker - Phase 3 Implementation
  3 |  *
  4 |  * Tracks active methodology state and handles framework switching.
  5 |  * Consolidated from framework-state-manager for better separation of concerns.
  6 |  */
  7 | 
  8 | import { EventEmitter } from "events";
  9 | import { Logger } from "../../logging/index.js";
 10 | import {
 11 |   FrameworkDefinition,
 12 |   MethodologyState,
 13 |   MethodologySwitchRequest,
 14 |   MethodologyHealth,
 15 |   PersistedMethodologyState
 16 | } from "../types/index.js";
 17 | import * as fs from 'fs/promises';
 18 | import * as path from 'path';
 19 | 
 20 | /**
 21 |  * Methodology tracking configuration
 22 |  */
 23 | export interface MethodologyTrackerConfig {
 24 |   persistStateToDisk: boolean;
 25 |   stateFilePath: string;
 26 |   enableHealthMonitoring: boolean;
 27 |   healthCheckIntervalMs: number;
 28 |   maxSwitchHistory: number;
 29 |   enableMetrics: boolean;
 30 | }
 31 | 
 32 | /**
 33 |  * Methodology Tracker Events
 34 |  */
 35 | export interface MethodologyTrackerEvents {
 36 |   'methodology-switched': (previous: string, current: string, reason: string) => void;
 37 |   'methodology-error': (methodology: string, error: Error) => void;
 38 |   'health-changed': (health: MethodologyHealth) => void;
 39 |   'state-persisted': (state: PersistedMethodologyState) => void;
 40 | }
 41 | 
 42 | /**
 43 |  * Methodology Tracker
 44 |  *
 45 |  * Maintains methodology state across operations, handles switching,
 46 |  * and provides health monitoring for the methodology system.
 47 |  */
 48 | export class MethodologyTracker extends EventEmitter {
 49 |   private logger: Logger;
 50 |   private config: MethodologyTrackerConfig;
 51 |   private currentState: MethodologyState;
 52 |   private readonly rootPath: string;
 53 |   private switchHistory: Array<{
 54 |     from: string;
 55 |     to: string;
 56 |     timestamp: Date;
 57 |     reason: string;
 58 |     success: boolean;
 59 |   }> = [];
 60 |   private healthCheckTimer: NodeJS.Timeout | null = null;
 61 |   private switchingMetrics = {
 62 |     totalSwitches: 0,
 63 |     successfulSwitches: 0,
 64 |     failedSwitches: 0,
 65 |     averageResponseTime: 0,
 66 |     responseTimes: [] as number[]
 67 |   };
 68 | 
 69 |   constructor(logger: Logger, config?: Partial<MethodologyTrackerConfig>) {
 70 |     super();
 71 |     this.logger = logger;
 72 |     const rootPath = path.resolve(process.env.MCP_SERVER_ROOT || process.cwd());
 73 |     this.rootPath = rootPath;
 74 |     const runtimeStatePath = path.join(rootPath, 'runtime-state', 'framework-state.json');
 75 | 
 76 |     const defaultConfig: MethodologyTrackerConfig = {
 77 |       persistStateToDisk: true,
 78 |       stateFilePath: runtimeStatePath,
 79 |       enableHealthMonitoring: true,
 80 |       healthCheckIntervalMs: 30000, // 30 seconds
 81 |       maxSwitchHistory: 100,
 82 |       enableMetrics: true
 83 |     };
 84 | 
 85 |     this.config = {
 86 |       ...defaultConfig,
 87 |       ...config,
 88 |       stateFilePath: config?.stateFilePath
 89 |         ? path.isAbsolute(config.stateFilePath)
 90 |           ? config.stateFilePath
 91 |           : path.resolve(rootPath, config.stateFilePath)
 92 |         : defaultConfig.stateFilePath
 93 |     };
 94 | 
 95 |     // Initialize default state
 96 |     this.currentState = {
 97 |       activeMethodology: "CAGEERF", // Default methodology
 98 |       previousMethodology: null,
 99 |       switchedAt: new Date(),
100 |       switchReason: "Initial state",
101 |       isHealthy: true,
102 |       methodologySystemEnabled: true,
103 |       switchingMetrics: {
104 |         switchCount: 0,
105 |         averageResponseTime: 0,
106 |         errorCount: 0
107 |       }
108 |     };
109 |   }
110 | 
111 |   /**
112 |    * Initialize methodology tracker with state restoration
113 |    */
114 |   async initialize(): Promise<void> {
115 |     this.logger.info("Initializing MethodologyTracker...");
116 | 
117 |     try {
118 |       // Restore state from disk if enabled
119 |       if (this.config.persistStateToDisk) {
120 |         await this.restoreState();
121 |       }
122 | 
123 |       // Start health monitoring if enabled
124 |       if (this.config.enableHealthMonitoring) {
125 |         this.startHealthMonitoring();
126 |       }
127 | 
128 |       this.logger.info(`MethodologyTracker initialized with ${this.currentState.activeMethodology} methodology`);
129 |     } catch (error) {
130 |       this.logger.error("Failed to initialize MethodologyTracker:", error);
131 |       throw error;
132 |     }
133 |   }
134 | 
135 |   /**
136 |    * Switch to a different methodology
137 |    * Consolidated from framework-state-manager.switchFramework()
138 |    */
139 |   async switchMethodology(request: MethodologySwitchRequest): Promise<boolean> {
140 |     const startTime = Date.now();
141 |     const previousMethodology = this.currentState.activeMethodology;
142 |     const targetMethodology = request.targetMethodology;
143 |     const reason = request.reason || "Manual switch";
144 | 
145 |     this.logger.info(`Switching methodology: ${previousMethodology} -> ${targetMethodology} (${reason})`);
146 | 
147 |     try {
148 |       // Validate switch request
149 |       if (!this.validateSwitchRequest(request)) {
150 |         throw new Error(`Invalid switch request: ${targetMethodology}`);
151 |       }
152 | 
153 |       // Update state
154 |       this.currentState = {
155 |         ...this.currentState,
156 |         previousMethodology,
157 |         activeMethodology: targetMethodology,
158 |         switchedAt: new Date(),
159 |         switchReason: reason,
160 |         switchingMetrics: {
161 |           ...this.currentState.switchingMetrics,
162 |           switchCount: this.currentState.switchingMetrics.switchCount + 1
163 |         }
164 |       };
165 | 
166 |       // Record switch in history
167 |       const switchRecord = {
168 |         from: previousMethodology,
169 |         to: targetMethodology,
170 |         timestamp: new Date(),
171 |         reason,
172 |         success: true
173 |       };
174 |       this.addToSwitchHistory(switchRecord);
175 | 
176 |       // Update metrics
177 |       if (this.config.enableMetrics) {
178 |         this.updateSwitchingMetrics(Date.now() - startTime, true);
179 |       }
180 | 
181 |       // Persist state if enabled
182 |       if (this.config.persistStateToDisk) {
183 |         await this.persistState();
184 |       }
185 | 
186 |       // Emit event
187 |       this.emit('methodology-switched', previousMethodology, targetMethodology, reason);
188 | 
189 |       this.logger.info(`Methodology switch completed: ${previousMethodology} -> ${targetMethodology} in ${Date.now() - startTime}ms`);
190 |       return true;
191 | 
192 |     } catch (error) {
193 |       this.logger.error(`Failed to switch methodology to ${targetMethodology}:`, error);
194 | 
195 |       // Record failed switch
196 |       this.addToSwitchHistory({
197 |         from: previousMethodology,
198 |         to: targetMethodology,
199 |         timestamp: new Date(),
200 |         reason,
201 |         success: false
202 |       });
203 | 
204 |       // Update failure metrics
205 |       if (this.config.enableMetrics) {
206 |         this.updateSwitchingMetrics(Date.now() - startTime, false);
207 |       }
208 | 
209 |       // Emit error event
210 |       this.emit('methodology-error', targetMethodology, error instanceof Error ? error : new Error(String(error)));
211 | 
212 |       return false;
213 |     }
214 |   }
215 | 
216 |   /**
217 |    * Get current methodology state
218 |    */
219 |   getCurrentState(): MethodologyState {
220 |     return { ...this.currentState };
221 |   }
222 | 
223 |   /**
224 |    * Get methodology system health
225 |    */
226 |   getSystemHealth(): MethodologyHealth {
227 |     return {
228 |       status: this.currentState.isHealthy ? "healthy" : "error",
229 |       activeMethodology: this.currentState.activeMethodology,
230 |       methodologySystemEnabled: this.currentState.methodologySystemEnabled,
231 |       lastSwitchTime: this.currentState.switchedAt,
232 |       switchingMetrics: {
233 |         totalSwitches: this.switchingMetrics.totalSwitches,
234 |         successfulSwitches: this.switchingMetrics.successfulSwitches,
235 |         failedSwitches: this.switchingMetrics.failedSwitches,
236 |         averageResponseTime: this.switchingMetrics.averageResponseTime
237 |       },
238 |       issues: this.detectHealthIssues()
239 |     };
240 |   }
241 | 
242 |   /**
243 |    * Enable or disable the methodology system
244 |    */
245 |   async setMethodologySystemEnabled(enabled: boolean, reason: string = "Manual toggle"): Promise<void> {
246 |     const previousState = this.currentState.methodologySystemEnabled;
247 | 
248 |     this.currentState.methodologySystemEnabled = enabled;
249 |     this.currentState.switchReason = `System ${enabled ? 'enabled' : 'disabled'}: ${reason}`;
250 | 
251 |     this.logger.info(`Methodology system ${enabled ? 'enabled' : 'disabled'}: ${reason}`);
252 | 
253 |     // Persist state change
254 |     if (this.config.persistStateToDisk) {
255 |       await this.persistState();
256 |     }
257 | 
258 |     // Emit event if state changed
259 |     if (previousState !== enabled) {
260 |       this.emit('methodology-system-toggled' as any, enabled, reason);
261 |     }
262 |   }
263 | 
264 |   /**
265 |    * Get switch history
266 |    */
267 |   getSwitchHistory(): Array<{ from: string; to: string; timestamp: Date; reason: string; success: boolean }> {
268 |     return [...this.switchHistory];
269 |   }
270 | 
271 |   /**
272 |    * Clear switch history
273 |    */
274 |   clearSwitchHistory(): void {
275 |     this.switchHistory = [];
276 |     this.logger.debug("Switch history cleared");
277 |   }
278 | 
279 |   /**
280 |    * Shutdown methodology tracker
281 |    */
282 |   async shutdown(): Promise<void> {
283 |     this.logger.info("Shutting down MethodologyTracker...");
284 | 
285 |     // Stop health monitoring
286 |     if (this.healthCheckTimer) {
287 |       clearInterval(this.healthCheckTimer);
288 |       this.healthCheckTimer = null;
289 |     }
290 | 
291 |     // Persist final state
292 |     if (this.config.persistStateToDisk) {
293 |       await this.persistState();
294 |     }
295 | 
296 |     this.logger.info("MethodologyTracker shutdown complete");
297 |   }
298 | 
299 |   /**
300 |    * Validate switch request
301 |    */
302 |   private validateSwitchRequest(request: MethodologySwitchRequest): boolean {
303 |     // Check if methodology system is enabled
304 |     if (!this.currentState.methodologySystemEnabled) {
305 |       this.logger.warn("Methodology switch rejected - system disabled");
306 |       return false;
307 |     }
308 | 
309 |     // Check if switching to same methodology
310 |     if (request.targetMethodology === this.currentState.activeMethodology) {
311 |       this.logger.debug(`Already using ${request.targetMethodology} methodology`);
312 |       return true; // Not an error, but no switch needed
313 |     }
314 | 
315 |     // Validate methodology exists (basic validation)
316 |     const validMethodologies = ["CAGEERF", "ReACT", "5W1H", "SCAMPER"];
317 |     if (!validMethodologies.includes(request.targetMethodology)) {
318 |       this.logger.error(`Invalid methodology: ${request.targetMethodology}`);
319 |       return false;
320 |     }
321 | 
322 |     return true;
323 |   }
324 | 
325 |   /**
326 |    * Add switch record to history
327 |    */
328 |   private addToSwitchHistory(record: {
329 |     from: string;
330 |     to: string;
331 |     timestamp: Date;
332 |     reason: string;
333 |     success: boolean;
334 |   }): void {
335 |     this.switchHistory.push(record);
336 | 
337 |     // Trim history if it exceeds maximum
338 |     if (this.switchHistory.length > this.config.maxSwitchHistory) {
339 |       this.switchHistory = this.switchHistory.slice(-this.config.maxSwitchHistory);
340 |     }
341 |   }
342 | 
343 |   /**
344 |    * Update switching metrics
345 |    */
346 |   private updateSwitchingMetrics(responseTime: number, success: boolean): void {
347 |     this.switchingMetrics.totalSwitches++;
348 | 
349 |     if (success) {
350 |       this.switchingMetrics.successfulSwitches++;
351 |     } else {
352 |       this.switchingMetrics.failedSwitches++;
353 |     }
354 | 
355 |     // Update response time metrics
356 |     this.switchingMetrics.responseTimes.push(responseTime);
357 |     if (this.switchingMetrics.responseTimes.length > 100) {
358 |       this.switchingMetrics.responseTimes = this.switchingMetrics.responseTimes.slice(-100);
359 |     }
360 | 
361 |     this.switchingMetrics.averageResponseTime =
362 |       this.switchingMetrics.responseTimes.reduce((sum, time) => sum + time, 0) /
363 |       this.switchingMetrics.responseTimes.length;
364 | 
365 |     // Update current state metrics
366 |     this.currentState.switchingMetrics = {
367 |       switchCount: this.switchingMetrics.totalSwitches,
368 |       averageResponseTime: this.switchingMetrics.averageResponseTime,
369 |       errorCount: this.switchingMetrics.failedSwitches
370 |     };
371 |   }
372 | 
373 |   /**
374 |    * Start health monitoring
375 |    */
376 |   private startHealthMonitoring(): void {
377 |     this.healthCheckTimer = setInterval(() => {
378 |       this.performHealthCheck();
379 |     }, this.config.healthCheckIntervalMs);
380 | 
381 |     this.logger.debug(`Health monitoring started (interval: ${this.config.healthCheckIntervalMs}ms)`);
382 |   }
383 | 
384 |   /**
385 |    * Perform health check
386 |    */
387 |   private performHealthCheck(): void {
388 |     const wasHealthy = this.currentState.isHealthy;
389 |     const health = this.getSystemHealth();
390 | 
391 |     // Update health status
392 |     this.currentState.isHealthy = health.status === "healthy";
393 | 
394 |     // Emit health change event if status changed
395 |     if (wasHealthy !== this.currentState.isHealthy) {
396 |       this.emit('health-changed', health);
397 |       this.logger.info(`Methodology system health changed: ${health.status}`);
398 |     }
399 |   }
400 | 
401 |   /**
402 |    * Detect health issues
403 |    */
404 |   private detectHealthIssues(): string[] {
405 |     const issues: string[] = [];
406 | 
407 |     // Check error rate
408 |     const errorRate = this.switchingMetrics.totalSwitches > 0
409 |       ? this.switchingMetrics.failedSwitches / this.switchingMetrics.totalSwitches
410 |       : 0;
411 | 
412 |     if (errorRate > 0.1) { // More than 10% error rate
413 |       issues.push(`High error rate: ${(errorRate * 100).toFixed(1)}%`);
414 |     }
415 | 
416 |     // Check response time
417 |     if (this.switchingMetrics.averageResponseTime > 1000) { // More than 1 second
418 |       issues.push(`Slow switching: ${this.switchingMetrics.averageResponseTime.toFixed(0)}ms average`);
419 |     }
420 | 
421 |     // Check if system is disabled
422 |     if (!this.currentState.methodologySystemEnabled) {
423 |       issues.push("Methodology system is disabled");
424 |     }
425 | 
426 |     return issues;
427 |   }
428 | 
429 |   /**
430 |    * Persist state to disk
431 |    */
432 |   private async persistState(): Promise<void> {
433 |     try {
434 |       const persistedState: PersistedMethodologyState = {
435 |         version: "1.0.0",
436 |         methodologySystemEnabled: this.currentState.methodologySystemEnabled,
437 |         activeMethodology: this.currentState.activeMethodology,
438 |         lastSwitchedAt: this.currentState.switchedAt.toISOString(),
439 |         switchReason: this.currentState.switchReason
440 |       };
441 | 
442 |       await fs.mkdir(path.dirname(this.config.stateFilePath), { recursive: true });
443 |       await fs.writeFile(
444 |         this.config.stateFilePath,
445 |         JSON.stringify(persistedState, null, 2)
446 |       );
447 |       this.emit('state-persisted', persistedState);
448 |       this.logger.debug(`State persisted to ${this.config.stateFilePath}`);
449 | 
450 |     } catch (error) {
451 |       this.logger.error("Failed to persist methodology state:", error);
452 |     }
453 |   }
454 | 
455 |   /**
456 |    * Restore state from disk
457 |    */
458 |   private async restoreState(): Promise<void> {
459 |     const persistedState = await this.readPersistedState();
460 | 
461 |     if (!persistedState) {
462 |       this.logger.debug("Using default methodology state");
463 |       return;
464 |     }
465 | 
466 |     this.currentState = {
467 |       ...this.currentState,
468 |       activeMethodology: persistedState.activeMethodology,
469 |       methodologySystemEnabled: persistedState.methodologySystemEnabled,
470 |       switchedAt: new Date(persistedState.lastSwitchedAt),
471 |       switchReason: persistedState.switchReason
472 |     };
473 | 
474 |     this.logger.info(
475 |       `State restored from ${this.config.stateFilePath}: ${persistedState.activeMethodology}`
476 |     );
477 |   }
478 | 
479 |   private async readPersistedState(): Promise<PersistedMethodologyState | null> {
480 |     try {
481 |       const stateData = await fs.readFile(this.config.stateFilePath, 'utf-8');
482 |       return JSON.parse(stateData);
483 |     } catch (error: any) {
484 |       if (error?.code !== 'ENOENT') {
485 |         this.logger.warn(
486 |           `Failed to read methodology state from ${this.config.stateFilePath}: ${
487 |             error instanceof Error ? error.message : String(error)
488 |           }`
489 |         );
490 |       }
491 |       return null;
492 |     }
493 |   }
494 | 
495 |   /**
496 |    * Update tracker configuration
497 |    */
498 |   updateConfig(config: Partial<MethodologyTrackerConfig>): void {
499 |     const oldConfig = { ...this.config };
500 |     this.config = { ...this.config, ...config };
501 | 
502 |     if (config.stateFilePath) {
503 |       this.config.stateFilePath = path.isAbsolute(config.stateFilePath)
504 |         ? config.stateFilePath
505 |         : path.resolve(this.rootPath, config.stateFilePath);
506 |     }
507 | 
508 |     // Restart health monitoring if interval changed
509 |     if (oldConfig.healthCheckIntervalMs !== this.config.healthCheckIntervalMs && this.config.enableHealthMonitoring) {
510 |       if (this.healthCheckTimer) {
511 |         clearInterval(this.healthCheckTimer);
512 |       }
513 |       this.startHealthMonitoring();
514 |     }
515 | 
516 |     this.logger.debug('MethodologyTracker configuration updated', config);
517 |   }
518 | 
519 |   /**
520 |    * Get current tracker configuration
521 |    */
522 |   getConfig(): MethodologyTrackerConfig {
523 |     return { ...this.config };
524 |   }
525 | }
526 | 
527 | /**
528 |  * Create and initialize a MethodologyTracker instance
529 |  */
530 | export async function createMethodologyTracker(
531 |   logger: Logger,
532 |   config?: Partial<MethodologyTrackerConfig>
533 | ): Promise<MethodologyTracker> {
534 |   const tracker = new MethodologyTracker(logger, config);
535 |   await tracker.initialize();
536 |   return tracker;
537 | }
538 | 
```

--------------------------------------------------------------------------------
/server/src/api/index.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * API Management Module
  3 |  * Handles Express app setup, middleware, and REST API endpoints
  4 |  */
  5 | 
  6 | import express, { Request, Response } from "express";
  7 | import { mkdir, readFile, writeFile } from "fs/promises";
  8 | import path from "path";
  9 | import { ConfigManager } from "../config/index.js";
 10 | import { Logger } from "../logging/index.js";
 11 | import { McpToolsManager } from "../mcp-tools/index.js";
 12 | import { PromptManager } from "../prompts/index.js";
 13 | import { modifyPromptSection } from "../prompts/promptUtils.js";
 14 | import { Category, PromptData, PromptsFile } from "../types/index.js";
 15 | 
 16 | /**
 17 |  * API Manager class
 18 |  */
 19 | export class ApiManager {
 20 |   private logger: Logger;
 21 |   private configManager: ConfigManager;
 22 |   private promptManager?: PromptManager;
 23 |   private mcpToolsManager?: McpToolsManager;
 24 |   private promptsData: PromptData[] = [];
 25 |   private categories: Category[] = [];
 26 |   private convertedPrompts: any[] = [];
 27 | 
 28 |   constructor(
 29 |     logger: Logger,
 30 |     configManager: ConfigManager,
 31 |     promptManager?: PromptManager,
 32 |     mcpToolsManager?: McpToolsManager
 33 |   ) {
 34 |     this.logger = logger;
 35 |     this.configManager = configManager;
 36 |     this.promptManager = promptManager;
 37 |     this.mcpToolsManager = mcpToolsManager;
 38 |   }
 39 | 
 40 |   /**
 41 |    * Update data references
 42 |    */
 43 |   updateData(
 44 |     promptsData: PromptData[],
 45 |     categories: Category[],
 46 |     convertedPrompts: any[]
 47 |   ): void {
 48 |     this.promptsData = promptsData;
 49 |     this.categories = categories;
 50 |     this.convertedPrompts = convertedPrompts;
 51 |   }
 52 | 
 53 |   /**
 54 |    * Create and configure Express application
 55 |    */
 56 |   createApp(): express.Application {
 57 |     const app = express();
 58 | 
 59 |     // Setup middleware
 60 |     this.setupMiddleware(app);
 61 | 
 62 |     // Setup routes
 63 |     this.setupRoutes(app);
 64 | 
 65 |     return app;
 66 |   }
 67 | 
 68 |   /**
 69 |    * Setup Express middleware
 70 |    */
 71 |   private setupMiddleware(app: express.Application): void {
 72 |     // Enable CORS for Cursor integration
 73 |     app.use((req, res, next) => {
 74 |       res.header("Access-Control-Allow-Origin", "*");
 75 |       res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE");
 76 |       res.header(
 77 |         "Access-Control-Allow-Headers",
 78 |         "Origin, X-Requested-With, Content-Type, Accept"
 79 |       );
 80 |       if (req.method === "OPTIONS") {
 81 |         return res.sendStatus(200);
 82 |       }
 83 |       next();
 84 |     });
 85 | 
 86 |     // Add JSON body parser middleware
 87 |     app.use(express.json());
 88 | 
 89 |     // Add request logging middleware
 90 |     app.use((req, res, next) => {
 91 |       this.logger.debug(
 92 |         `${req.method} ${req.url} - Headers: ${JSON.stringify(req.headers)}`
 93 |       );
 94 |       next();
 95 |     });
 96 |   }
 97 | 
 98 |   /**
 99 |    * Setup API routes
100 |    */
101 |   private setupRoutes(app: express.Application): void {
102 |     // Basic routes
103 |     this.setupBasicRoutes(app);
104 | 
105 |     // Prompt and category routes
106 |     this.setupPromptRoutes(app);
107 | 
108 |     // Tool API routes
109 |     this.setupToolRoutes(app);
110 |   }
111 | 
112 |   /**
113 |    * Setup basic routes (home, health)
114 |    */
115 |   private setupBasicRoutes(app: express.Application): void {
116 |     app.get("/", (_req: Request, res: Response) => {
117 |       res.send(
118 |         "Claude Custom Prompts MCP Server - Use /mcp endpoint for MCP connections"
119 |       );
120 |     });
121 | 
122 |     // Health check endpoint
123 |     app.get("/health", (_req: Request, res: Response) => {
124 |       const config = this.configManager.getConfig();
125 |       res.json({ status: "ok", version: config.server.version });
126 |     });
127 |   }
128 | 
129 |   /**
130 |    * Setup prompt and category routes
131 |    */
132 |   private setupPromptRoutes(app: express.Application): void {
133 |     // Get all categories and prompts
134 |     app.get("/prompts", (_req: Request, res: Response) => {
135 |       const result = {
136 |         categories: this.categories,
137 |         prompts: this.promptsData.map((prompt) => ({
138 |           id: prompt.id,
139 |           name: prompt.name,
140 |           category: prompt.category,
141 |           description: prompt.description,
142 |           arguments: prompt.arguments,
143 |         })),
144 |       };
145 |       res.json(result);
146 |     });
147 | 
148 |     // Get prompts by category
149 |     app.get(
150 |       "/categories/:categoryId/prompts",
151 |       (req: Request, res: Response) => {
152 |         const categoryId = req.params.categoryId;
153 |         const categoryPrompts = this.promptsData.filter(
154 |           (prompt) => prompt.category === categoryId
155 |         );
156 | 
157 |         if (categoryPrompts.length === 0) {
158 |           return res
159 |             .status(404)
160 |             .json({ error: `No prompts found for category: ${categoryId}` });
161 |         }
162 | 
163 |         res.json(categoryPrompts);
164 |       }
165 |     );
166 |   }
167 | 
168 |   /**
169 |    * Setup tool API routes
170 |    */
171 |   private setupToolRoutes(app: express.Application): void {
172 |     // Create category endpoint
173 |     app.post(
174 |       "/api/v1/tools/create_category",
175 |       async (req: Request, res: Response) => {
176 |         await this.handleCreateCategory(req, res);
177 |       }
178 |     );
179 | 
180 |     // Update prompt endpoint
181 |     app.post(
182 |       "/api/v1/tools/update_prompt",
183 |       async (req: Request, res: Response) => {
184 |         await this.handleUpdatePrompt(req, res);
185 |       }
186 |     );
187 | 
188 |     // Delete prompt endpoint
189 |     app.delete(
190 |       "/api/v1/tools/prompts/:id",
191 |       async (req: Request, res: Response) => {
192 |         await this.handleDeletePrompt(req, res);
193 |       }
194 |     );
195 | 
196 |     // Modify prompt section endpoint
197 |     app.post(
198 |       "/api/v1/tools/modify_prompt_section",
199 |       async (req: Request, res: Response) => {
200 |         await this.handleModifyPromptSection(req, res);
201 |       }
202 |     );
203 | 
204 |     // Reload prompts endpoint
205 |     app.post(
206 |       "/api/v1/tools/reload_prompts",
207 |       async (req: Request, res: Response) => {
208 |         await this.handleReloadPrompts(req, res);
209 |       }
210 |     );
211 |   }
212 | 
213 |   /**
214 |    * Handle create category API endpoint
215 |    */
216 |   private async handleCreateCategory(
217 |     req: Request,
218 |     res: Response
219 |   ): Promise<void> {
220 |     try {
221 |       this.logger.info("API request to create category:", req.body);
222 | 
223 |       // Validate required fields
224 |       if (!req.body.id || !req.body.name || !req.body.description) {
225 |         res.status(400).json({
226 |           error:
227 |             "Missing required fields. Please provide id, name, and description.",
228 |         });
229 |         return;
230 |       }
231 | 
232 |       const { id, name, description } = req.body;
233 | 
234 |       // Read the current prompts configuration file
235 |       const PROMPTS_FILE = this.getPromptsFilePath();
236 |       const fileContent = await readFile(PROMPTS_FILE, "utf8");
237 |       const promptsFile = JSON.parse(fileContent) as PromptsFile;
238 | 
239 |       // Check if the category already exists
240 |       const categoryExists = promptsFile.categories.some(
241 |         (cat) => cat.id === id
242 |       );
243 |       if (categoryExists) {
244 |         res.status(400).json({ error: `Category '${id}' already exists.` });
245 |         return;
246 |       }
247 | 
248 |       // Add the new category
249 |       promptsFile.categories.push({ id, name, description });
250 | 
251 |       // Write the updated file
252 |       await writeFile(
253 |         PROMPTS_FILE,
254 |         JSON.stringify(promptsFile, null, 2),
255 |         "utf8"
256 |       );
257 | 
258 |       // Create the category directory if it doesn't exist
259 |       const categoryDirPath = path.join(path.dirname(PROMPTS_FILE), id);
260 |       try {
261 |         await mkdir(categoryDirPath, { recursive: true });
262 |       } catch (error) {
263 |         this.logger.error(
264 |           `Error creating directory ${categoryDirPath}:`,
265 |           error
266 |         );
267 |         // Continue even if directory creation fails
268 |       }
269 | 
270 |       // Reload prompts and categories if prompt manager is available
271 |       if (this.promptManager) {
272 |         try {
273 |           await this.reloadPromptData();
274 |           this.logger.info(
275 |             `Reloaded ${this.promptsData.length} prompts and ${this.categories.length} categories after creating category: ${id}`
276 |           );
277 |         } catch (error) {
278 |           this.logger.error("Error reloading prompts data:", error);
279 |         }
280 |       }
281 | 
282 |       res.status(200).json({
283 |         success: true,
284 |         message: `Category '${name}' created successfully`,
285 |       });
286 |     } catch (error) {
287 |       this.logger.error("Error handling create_category API request:", error);
288 |       res.status(500).json({
289 |         error: "Internal server error",
290 |         details: error instanceof Error ? error.message : String(error),
291 |       });
292 |     }
293 |   }
294 | 
295 |   /**
296 |    * Handle update prompt API endpoint
297 |    */
298 |   private async handleUpdatePrompt(req: Request, res: Response): Promise<void> {
299 |     try {
300 |       this.logger.info("API request to update prompt:", req.body);
301 | 
302 |       // Validate required fields
303 |       if (
304 |         !req.body.id ||
305 |         !req.body.name ||
306 |         !req.body.category ||
307 |         !req.body.userMessageTemplate
308 |       ) {
309 |         res.status(400).json({
310 |           error:
311 |             "Missing required fields. Please provide id, name, category, and userMessageTemplate.",
312 |         });
313 |         return;
314 |       }
315 | 
316 |       const {
317 |         id,
318 |         name,
319 |         category,
320 |         description,
321 |         userMessageTemplate,
322 |         arguments: promptArgs,
323 |         systemMessage,
324 |         isChain,
325 |         chainSteps,
326 |       } = req.body;
327 | 
328 |       // Implementation would include full update logic...
329 |       // For brevity, this is a simplified version
330 |       res.status(200).json({
331 |         success: true,
332 |         message: `Prompt '${name}' updated successfully`,
333 |       });
334 |     } catch (error) {
335 |       this.logger.error("Error handling update_prompt API request:", error);
336 |       res.status(500).json({
337 |         error: "Internal server error",
338 |         details: error instanceof Error ? error.message : String(error),
339 |       });
340 |     }
341 |   }
342 | 
343 |   /**
344 |    * Handle delete prompt API endpoint
345 |    */
346 |   private async handleDeletePrompt(req: Request, res: Response): Promise<void> {
347 |     try {
348 |       const id = req.params.id;
349 |       this.logger.info(`API request to delete prompt: ${id}`);
350 | 
351 |       if (!id) {
352 |         res.status(400).json({ error: "Prompt ID is required" });
353 |         return;
354 |       }
355 | 
356 |       // Implementation would include full delete logic...
357 |       res.status(200).json({
358 |         success: true,
359 |         message: `Prompt '${id}' deleted successfully`,
360 |       });
361 |     } catch (error) {
362 |       this.logger.error("Error handling delete_prompt API request:", error);
363 |       res.status(500).json({
364 |         error: "Internal server error",
365 |         details: error instanceof Error ? error.message : String(error),
366 |       });
367 |     }
368 |   }
369 | 
370 |   /**
371 |    * Handle modify prompt section API endpoint
372 |    */
373 |   private async handleModifyPromptSection(
374 |     req: Request,
375 |     res: Response
376 |   ): Promise<void> {
377 |     try {
378 |       this.logger.info("Received request to modify prompt section:", req.body);
379 | 
380 |       const { id, section_name, new_content, restartServer } = req.body;
381 | 
382 |       if (!id || !section_name || !new_content) {
383 |         res.status(400).json({
384 |           success: false,
385 |           message:
386 |             "Missing required fields: id, section_name, and new_content are required",
387 |         });
388 |         return;
389 |       }
390 | 
391 |       // Use the modifyPromptSection function from promptUtils
392 |       const PROMPTS_FILE = this.getPromptsFilePath();
393 |       const result = await modifyPromptSection(
394 |         id,
395 |         section_name,
396 |         new_content,
397 |         PROMPTS_FILE
398 |       );
399 | 
400 |       if (!result.success) {
401 |         res.status(404).json({
402 |           success: false,
403 |           message: result.message,
404 |         });
405 |         return;
406 |       }
407 | 
408 |       // Reload prompt data if available
409 |       if (this.promptManager) {
410 |         try {
411 |           await this.reloadPromptData();
412 |           this.logger.info(
413 |             `Triggered server refresh${
414 |               restartServer ? " with restart" : ""
415 |             } after modifying section: ${section_name}`
416 |           );
417 |         } catch (refreshError) {
418 |           this.logger.error(
419 |             `Error refreshing server after modifying section: ${section_name}`,
420 |             refreshError
421 |           );
422 |         }
423 |       }
424 | 
425 |       res.status(200).json({
426 |         success: true,
427 |         message: result.message,
428 |         restarting: restartServer || false,
429 |       });
430 |     } catch (error) {
431 |       this.logger.error(
432 |         "Error handling modify_prompt_section API request:",
433 |         error
434 |       );
435 |       res.status(500).json({
436 |         success: false,
437 |         message: "Internal server error",
438 |       });
439 |     }
440 |   }
441 | 
442 |   /**
443 |    * Handle reload prompts API endpoint
444 |    */
445 |   private async handleReloadPrompts(
446 |     req: Request,
447 |     res: Response
448 |   ): Promise<void> {
449 |     try {
450 |       this.logger.info("API request to reload prompts");
451 | 
452 |       const shouldRestart = req.body && req.body.restart === true;
453 |       const reason =
454 |         req.body && req.body.reason
455 |           ? req.body.reason
456 |           : "Manual reload requested";
457 | 
458 |       try {
459 |         // Reload prompt data if available
460 |         if (this.promptManager) {
461 |           await this.reloadPromptData();
462 |         }
463 | 
464 |         if (shouldRestart) {
465 |           res.status(200).json({
466 |             success: true,
467 |             message: `Successfully refreshed the server with ${this.promptsData.length} prompts and ${this.categories.length} categories. Server is now restarting.`,
468 |             data: {
469 |               promptsCount: this.promptsData.length,
470 |               categoriesCount: this.categories.length,
471 |               convertedPromptsCount: this.convertedPrompts.length,
472 |               restarting: true,
473 |             },
474 |           });
475 |         } else {
476 |           res.status(200).json({
477 |             success: true,
478 |             message: `Successfully refreshed the server with ${this.promptsData.length} prompts and ${this.categories.length} categories`,
479 |             data: {
480 |               promptsCount: this.promptsData.length,
481 |               categoriesCount: this.categories.length,
482 |               convertedPromptsCount: this.convertedPrompts.length,
483 |             },
484 |           });
485 |         }
486 |       } catch (refreshError) {
487 |         this.logger.error("Error refreshing server:", refreshError);
488 |         res.status(500).json({
489 |           success: false,
490 |           message: `Failed to refresh server: ${
491 |             refreshError instanceof Error
492 |               ? refreshError.message
493 |               : String(refreshError)
494 |           }`,
495 |         });
496 |       }
497 |     } catch (error) {
498 |       this.logger.error("Error handling reload_prompts API request:", error);
499 |       res.status(500).json({
500 |         success: false,
501 |         message: "Internal server error",
502 |       });
503 |     }
504 |   }
505 | 
506 |   /**
507 |    * Helper method to reload prompt data
508 |    */
509 |   private async reloadPromptData(): Promise<void> {
510 |     if (!this.promptManager) {
511 |       throw new Error("PromptManager not available");
512 |     }
513 | 
514 |     const PROMPTS_FILE = this.getPromptsFilePath();
515 | 
516 |     const result = await this.promptManager.loadAndConvertPrompts(PROMPTS_FILE);
517 |     this.updateData(
518 |       result.promptsData,
519 |       result.categories,
520 |       result.convertedPrompts
521 |     );
522 | 
523 |     // Update MCP tools manager if available
524 |     if (this.mcpToolsManager) {
525 |       this.mcpToolsManager.updateData(
526 |         result.promptsData,
527 |         result.convertedPrompts,
528 |         result.categories
529 |       );
530 |     }
531 |   }
532 | 
533 |   /**
534 |    * Get prompts file path using consistent resolution logic
535 |    * This ensures all API operations use the same path resolution as the orchestration module
536 |    */
537 |   private getPromptsFilePath(): string {
538 |     // ENHANCED: Use same path resolution logic as orchestration module
539 |     // This ensures API operations also respect MCP_PROMPTS_CONFIG_PATH environment variable
540 |     let PROMPTS_FILE: string;
541 | 
542 |     if (process.env.MCP_PROMPTS_CONFIG_PATH) {
543 |       PROMPTS_FILE = process.env.MCP_PROMPTS_CONFIG_PATH;
544 |       this.logger.info(
545 |         "🎯 API: Using MCP_PROMPTS_CONFIG_PATH environment variable override"
546 |       );
547 |     } else {
548 |       // Fallback to ConfigManager's getPromptsFilePath() method which handles server root properly
549 |       PROMPTS_FILE = this.configManager.getPromptsFilePath();
550 |       this.logger.info(
551 |         "📁 API: Using config-based prompts file path resolution"
552 |       );
553 |     }
554 | 
555 |     // Ensure absolute path (critical for Claude Desktop)
556 |     if (!path.isAbsolute(PROMPTS_FILE)) {
557 |       PROMPTS_FILE = path.resolve(PROMPTS_FILE);
558 |       this.logger.info(`🔧 API: Converted to absolute path: ${PROMPTS_FILE}`);
559 |     }
560 | 
561 |     return PROMPTS_FILE;
562 |   }
563 | }
564 | 
565 | /**
566 |  * Create and configure an API manager
567 |  */
568 | export function createApiManager(
569 |   logger: Logger,
570 |   configManager: ConfigManager,
571 |   promptManager?: PromptManager,
572 |   mcpToolsManager?: McpToolsManager
573 | ): ApiManager {
574 |   return new ApiManager(logger, configManager, promptManager, mcpToolsManager);
575 | }
576 | 
```

--------------------------------------------------------------------------------
/server/tests/integration/unified-parsing-integration.test.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Integration Tests for Unified Parsing System
  3 |  * 
  4 |  * End-to-end integration tests that verify the complete parsing system
  5 |  * works correctly with the real MCP server infrastructure.
  6 |  */
  7 | 
  8 | import { describe, test, expect, beforeEach, afterEach, jest } from '@jest/globals';
  9 | import { Logger } from '../../src/logging/index.js';
 10 | import { PromptManager } from '../../src/prompts/index.js';
 11 | import { ConsolidatedPromptEngine, createConsolidatedPromptEngine } from '../../src/mcp-tools/consolidated-prompt-engine.js';
 12 | import { SemanticAnalyzer } from '../../src/analysis/semantic-analyzer.js';
 13 | import { PromptData, ConvertedPrompt } from '../../src/types/index.js';
 14 | import { isChainPrompt } from '../../src/utils/chainUtils.js';
 15 | 
 16 | // Mock logger
 17 | const mockLogger: Logger = {
 18 |   debug: jest.fn(),
 19 |   info: jest.fn(),
 20 |   warn: jest.fn(),
 21 |   error: jest.fn()
 22 | } as any;
 23 | 
 24 | // Mock MCP server
 25 | const mockMcpServer = {
 26 |   tool: jest.fn()
 27 | };
 28 | 
 29 | // Mock prompt manager
 30 | const mockPromptManager = {
 31 |   processTemplateAsync: jest.fn().mockResolvedValue('Processed template content'),
 32 |   convertedPrompts: [] as ConvertedPrompt[],
 33 |   promptsData: [] as PromptData[]
 34 | } as any;
 35 | 
 36 | // Mock semantic analyzer
 37 | const mockSemanticAnalyzer = {
 38 |   analyzePrompt: jest.fn().mockResolvedValue({
 39 |     executionType: 'template',
 40 |     requiresExecution: true,
 41 |     confidence: 0.8,
 42 |     reasoning: ['Simple prompt detected'],
 43 |     suggestedGates: []
 44 |   })
 45 | } as any;
 46 | 
 47 | // Test data
 48 | const testPromptsData: PromptData[] = [
 49 |   {
 50 |     id: 'simple_test',
 51 |     name: 'simple_test',
 52 |     description: 'A simple test prompt',
 53 |     userMessageTemplate: 'Process this: {{content}}',
 54 |     arguments: [
 55 |       {
 56 |         name: 'content',
 57 |         description: 'Content to process',
 58 |         required: true
 59 |       }
 60 |     ],
 61 |     category: 'test'
 62 |   },
 63 |   {
 64 |     id: 'multi_arg_test',
 65 |     name: 'multi_arg_test', 
 66 |     description: 'Multi-argument test prompt',
 67 |     userMessageTemplate: 'Transform {{text}} to {{format}} in {{language}}',
 68 |     arguments: [
 69 |       {
 70 |         name: 'text',
 71 |         description: 'Text to transform',
 72 |         required: true
 73 |       },
 74 |       {
 75 |         name: 'format',
 76 |         description: 'Output format (json, xml, csv)',
 77 |         required: false
 78 |       },
 79 |       {
 80 |         name: 'language',
 81 |         description: 'Target language',
 82 |         required: false
 83 |       }
 84 |     ],
 85 |     category: 'test'
 86 |   },
 87 |   {
 88 |     id: 'chain_test',
 89 |     name: 'chain_test',
 90 |     description: 'Chain execution test prompt',
 91 |     userMessageTemplate: 'Step result: {{result}}',
 92 |     arguments: [
 93 |       {
 94 |         name: 'result',
 95 |         description: 'Result from previous step',
 96 |         required: false
 97 |       }
 98 |     ],
 99 |     category: 'test'
100 |   }
101 | ];
102 | 
103 | const testConvertedPrompts: ConvertedPrompt[] = testPromptsData.map(prompt => ({
104 |   ...prompt,
105 |   chainSteps: prompt.id === 'chain_test' ? [
106 |     { stepName: 'Step 1', promptId: 'simple_test' },
107 |     { stepName: 'Step 2', promptId: 'multi_arg_test' }
108 |   ] : undefined
109 | }));
110 | 
111 | describe('Unified Parsing Integration Tests', () => {
112 |   let promptEngine: ConsolidatedPromptEngine;
113 | 
114 |   beforeEach(() => {
115 |     // Reset mocks
116 |     jest.clearAllMocks();
117 |     
118 |     // Create prompt engine with enhanced parsing
119 |     promptEngine = createConsolidatedPromptEngine(
120 |       mockLogger,
121 |       mockMcpServer,
122 |       mockPromptManager,
123 |       mockSemanticAnalyzer
124 |     );
125 |     
126 |     // Update test data
127 |     promptEngine.updateData(testPromptsData, testConvertedPrompts);
128 |   });
129 | 
130 |   describe('End-to-End Command Processing', () => {
131 |     test('should process simple command through entire pipeline', async () => {
132 |       const mockExecutePrompt = jest.fn();
133 |       
134 |       // Mock the internal executePrompt method
135 |       (promptEngine as any).executePrompt = mockExecutePrompt.mockResolvedValue({
136 |         content: [{ type: 'text', text: 'Success: Processed content' }]
137 |       });
138 | 
139 |       // Simulate the command execution
140 |       const result = await (promptEngine as any).executePrompt({
141 |         command: '>>simple_test Hello world',
142 |         execution_mode: 'auto'
143 |       }, {});
144 | 
145 |       expect(mockExecutePrompt).toHaveBeenCalledWith(
146 |         expect.objectContaining({
147 |           command: '>>simple_test Hello world',
148 |           execution_mode: 'auto'
149 |         }),
150 |         {}
151 |       );
152 |     });
153 | 
154 |     test('should handle JSON command format', async () => {
155 |       const mockExecutePrompt = jest.fn().mockResolvedValue({
156 |         content: [{ type: 'text', text: 'Success: JSON processed' }]
157 |       });
158 |       
159 |       (promptEngine as any).executePrompt = mockExecutePrompt;
160 | 
161 |       const jsonCommand = JSON.stringify({
162 |         command: '>>multi_arg_test',
163 |         args: {
164 |           text: 'Hello world',
165 |           format: 'json',
166 |           language: 'en'
167 |         }
168 |       });
169 | 
170 |       await (promptEngine as any).executePrompt({
171 |         command: jsonCommand,
172 |         execution_mode: 'auto'
173 |       }, {});
174 | 
175 |       expect(mockExecutePrompt).toHaveBeenCalled();
176 |     });
177 | 
178 |     test('should handle structured command format', async () => {
179 |       const mockExecutePrompt = jest.fn().mockResolvedValue({
180 |         content: [{ type: 'text', text: 'Success: Structured processed' }]
181 |       });
182 |       
183 |       (promptEngine as any).executePrompt = mockExecutePrompt;
184 | 
185 |       const structuredCommand = 'multi_arg_test {"text": "Hello", "format": "xml"}';
186 | 
187 |       await (promptEngine as any).executePrompt({
188 |         command: structuredCommand,
189 |         execution_mode: 'template'
190 |       }, {});
191 | 
192 |       expect(mockExecutePrompt).toHaveBeenCalled();
193 |     });
194 | 
195 |     test('should parse multi-line arguments in simple command format', async () => {
196 |       const multiLineCommand = [
197 |         '>>simple_test **Title**: Network Layers Model',
198 |         '**Summary**:',
199 |         'Line one of details.',
200 |         'Line two of details.'
201 |       ].join('\n');
202 | 
203 |       const result = await (promptEngine as any).parseCommandUnified(multiLineCommand);
204 | 
205 |       expect(result.promptId).toBe('simple_test');
206 |       expect(result.arguments).toBeDefined();
207 |       expect(result.arguments.content).toContain('Line two of details.');
208 |       expect(result.arguments.content.split('\n').length).toBeGreaterThan(1);
209 |     });
210 |   });
211 | 
212 |   describe('Context-Aware Processing', () => {
213 |     test('should use conversation history for context', async () => {
214 |       // Mock conversation history in prompt manager
215 |       const mockHistory = [
216 |         { role: 'user', content: 'Previous message content', timestamp: Date.now() - 1000 }
217 |       ];
218 |       
219 |       mockPromptManager.getHistory = jest.fn().mockReturnValue(mockHistory);
220 | 
221 |       const mockExecutePrompt = jest.fn().mockResolvedValue({
222 |         content: [{ type: 'text', text: 'Success: Context aware' }]
223 |       });
224 |       
225 |       (promptEngine as any).executePrompt = mockExecutePrompt;
226 | 
227 |       // Execute command that should use context
228 |       await (promptEngine as any).executePrompt({
229 |         command: '>>simple_test',
230 |         execution_mode: 'auto'
231 |       }, {});
232 | 
233 |       expect(mockExecutePrompt).toHaveBeenCalled();
234 |     });
235 | 
236 |     test('should resolve environment variables for defaults', async () => {
237 |       // Set environment variable
238 |       process.env.PROMPT_FORMAT = 'json';
239 |       process.env.PROMPT_LANGUAGE = 'es';
240 | 
241 |       const mockExecutePrompt = jest.fn().mockResolvedValue({
242 |         content: [{ type: 'text', text: 'Success: Environment resolved' }]
243 |       });
244 |       
245 |       (promptEngine as any).executePrompt = mockExecutePrompt;
246 | 
247 |       await (promptEngine as any).executePrompt({
248 |         command: '>>multi_arg_test Hello world',
249 |         execution_mode: 'auto'
250 |       }, {});
251 | 
252 |       expect(mockExecutePrompt).toHaveBeenCalled();
253 | 
254 |       // Clean up
255 |       delete process.env.PROMPT_FORMAT;
256 |       delete process.env.PROMPT_LANGUAGE;
257 |     });
258 |   });
259 | 
260 |   describe('Error Handling and Recovery', () => {
261 |     test('should provide helpful error messages for unknown prompts', async () => {
262 |       try {
263 |         await (promptEngine as any).parseCommandUnified('>>unknown_prompt test');
264 |         expect(true).toBe(false); // Should not reach here
265 |       } catch (error: any) {
266 |         expect(error.message).toContain('Unknown prompt: unknown_prompt');
267 |         expect(error.message).toContain('>>listprompts');
268 |       }
269 |     });
270 | 
271 |     test('should suggest corrections for typos', async () => {
272 |       try {
273 |         await (promptEngine as any).parseCommandUnified('>>simple_tst test');
274 |       } catch (error: any) {
275 |         expect(error.message).toContain('simple_test');
276 |       }
277 |     });
278 | 
279 |     test('should handle malformed JSON gracefully', async () => {
280 |       try {
281 |         await (promptEngine as any).parseCommandUnified('{"command": ">>simple_test", "malformed": json}');
282 |       } catch (error: any) {
283 |         expect(error.message).toContain('Supported command formats');
284 |       }
285 |     });
286 |   });
287 | 
288 |   describe('Performance and Statistics', () => {
289 |     test('should track parsing statistics', async () => {
290 |       // Execute several commands
291 |       const commands = [
292 |         '>>simple_test hello',
293 |         '>>multi_arg_test world format=json',
294 |         'chain_test {"result": "test"}'
295 |       ];
296 | 
297 |       for (const command of commands) {
298 |         try {
299 |           await (promptEngine as any).parseCommandUnified(command);
300 |         } catch (error) {
301 |           // Expected for some test cases
302 |         }
303 |       }
304 | 
305 |       const stats = promptEngine.getParsingStats();
306 |       
307 |       expect(stats.commandParser).toBeDefined();
308 |       expect(stats.argumentProcessor).toBeDefined();
309 |       expect(stats.contextResolver).toBeDefined();
310 |       
311 |       expect(stats.commandParser.totalParses).toBeGreaterThan(0);
312 |       expect(stats.argumentProcessor.totalProcessed).toBeGreaterThan(0);
313 |       expect(stats.contextResolver.totalResolutions).toBeGreaterThan(0);
314 |     });
315 | 
316 |     test('should allow statistics reset', () => {
317 |       promptEngine.resetParsingStats();
318 |       
319 |       const stats = promptEngine.getParsingStats();
320 |       expect(stats.commandParser.totalParses).toBe(0);
321 |       expect(stats.argumentProcessor.totalProcessed).toBe(0);
322 |       expect(stats.contextResolver.totalResolutions).toBe(0);
323 |     });
324 |   });
325 | 
326 |   describe('Execution Mode Detection', () => {
327 |     test('should detect template mode for simple prompts', async () => {
328 |       mockSemanticAnalyzer.analyzePrompt.mockResolvedValue({
329 |         executionType: 'template',
330 |         requiresExecution: false,
331 |         confidence: 0.9,
332 |         reasoning: ['Simple informational prompt'],
333 |         suggestedGates: []
334 |       });
335 | 
336 |       const mockExecuteTemplate = jest.fn().mockResolvedValue({
337 |         content: [{ type: 'text', text: 'Template result' }]
338 |       });
339 |       
340 |       (promptEngine as any).executeTemplate = mockExecuteTemplate;
341 | 
342 |       await (promptEngine as any).executePrompt({
343 |         command: '>>simple_test info request',
344 |         execution_mode: 'auto'
345 |       }, {});
346 | 
347 |       // Would verify template mode was selected
348 |     });
349 | 
350 |     test('should detect chain mode for chain prompts', async () => {
351 |       const chainPrompt = testConvertedPrompts.find(p => isChainPrompt(p));
352 |       expect(chainPrompt).toBeDefined();
353 | 
354 |       const mockExecuteChain = jest.fn().mockResolvedValue({
355 |         content: [{ type: 'text', text: 'Chain result' }]
356 |       });
357 |       
358 |       (promptEngine as any).executeChain = mockExecuteChain;
359 | 
360 |       // Test would verify chain execution
361 |     });
362 |   });
363 | 
364 |   describe('Backward Compatibility', () => {
365 |     test('should maintain compatibility with legacy parseCommand calls', async () => {
366 |       const legacyResult = await (promptEngine as any).parseCommand('>>simple_test legacy test');
367 |       
368 |       expect(legacyResult.promptId).toBe('simple_test');
369 |       expect(legacyResult.arguments).toBeDefined();
370 |       expect(legacyResult.convertedPrompt).toBeDefined();
371 |     });
372 | 
373 |     test('should maintain compatibility with legacy parseArguments calls', async () => {
374 |       const legacyResult = await (promptEngine as any).parseArguments(
375 |         'legacy argument test',
376 |         testPromptsData[0]
377 |       );
378 |       
379 |       expect(legacyResult).toBeDefined();
380 |       expect(typeof legacyResult).toBe('object');
381 |     });
382 | 
383 |     test('should log migration warnings for deprecated methods', async () => {
384 |       await (promptEngine as any).parseCommand('>>simple_test legacy');
385 |       await (promptEngine as any).parseArguments('test', testPromptsData[0]);
386 |       
387 |       expect(mockLogger.warn).toHaveBeenCalledWith(
388 |         expect.stringContaining('[MIGRATION]')
389 |       );
390 |     });
391 |   });
392 | 
393 |   describe('Real-World Scenarios', () => {
394 |     test('should handle complex multi-step workflow', async () => {
395 |       const workflow = [
396 |         '>>simple_test Extract key information from this document',
397 |         '>>multi_arg_test format=json language=en',
398 |         '>>chain_test'
399 |       ];
400 | 
401 |       for (const command of workflow) {
402 |         try {
403 |           await (promptEngine as any).parseCommandUnified(command);
404 |         } catch (error) {
405 |           // Some commands may fail in test environment
406 |         }
407 |       }
408 | 
409 |       // Verify the workflow was processed
410 |       const stats = promptEngine.getParsingStats();
411 |       expect(stats.commandParser.totalParses).toBe(workflow.length);
412 |     });
413 | 
414 |     test('should handle concurrent command processing', async () => {
415 |       const concurrentCommands = [
416 |         '>>simple_test concurrent test 1',
417 |         '>>multi_arg_test concurrent test 2',
418 |         '>>simple_test concurrent test 3'
419 |       ];
420 | 
421 |       const promises = concurrentCommands.map(command => 
422 |         (promptEngine as any).parseCommandUnified(command).catch(() => null)
423 |       );
424 | 
425 |       await Promise.all(promises);
426 | 
427 |       const stats = promptEngine.getParsingStats();
428 |       expect(stats.commandParser.totalParses).toBe(concurrentCommands.length);
429 |     });
430 | 
431 |     test('should maintain state consistency under load', async () => {
432 |       const commands = Array(50).fill(null).map((_, i) => 
433 |         `>>simple_test load test ${i}`
434 |       );
435 | 
436 |       for (const command of commands) {
437 |         try {
438 |           await (promptEngine as any).parseCommandUnified(command);
439 |         } catch (error) {
440 |           // Expected in test environment
441 |         }
442 |       }
443 | 
444 |       const stats = promptEngine.getParsingStats();
445 |       expect(stats.commandParser.successfulParses + stats.commandParser.failedParses)
446 |         .toBe(stats.commandParser.totalParses);
447 |     });
448 |   });
449 | });
450 | 
451 | describe('Migration Validation', () => {
452 |   test('should demonstrate zero-breaking-changes migration', async () => {
453 |     const promptEngine = createConsolidatedPromptEngine(
454 |       mockLogger,
455 |       mockMcpServer,
456 |       mockPromptManager,
457 |       mockSemanticAnalyzer
458 |     );
459 |     
460 |     promptEngine.updateData(testPromptsData, testConvertedPrompts);
461 | 
462 |     // All these legacy patterns should still work
463 |     const legacyPatterns = [
464 |       '>>simple_test hello',
465 |       '>>multi_arg_test text format=json',
466 |       'chain_test'
467 |     ];
468 | 
469 |     let allPassed = true;
470 |     for (const pattern of legacyPatterns) {
471 |       try {
472 |         await (promptEngine as any).parseCommandUnified(pattern);
473 |       } catch (error) {
474 |         // Error handling is expected, but should be graceful
475 |         expect((error as Error).message).toBeTruthy();
476 |       }
477 |     }
478 | 
479 |     // Verify enhanced features are available
480 |     expect(promptEngine.getParsingStats).toBeDefined();
481 |     expect(promptEngine.resetParsingStats).toBeDefined();
482 |   });
483 | });
484 | 
485 | describe('System Health and Monitoring', () => {
486 |   test('should provide comprehensive system health metrics', () => {
487 |     const promptEngine = createConsolidatedPromptEngine(
488 |       mockLogger,
489 |       mockMcpServer,
490 |       mockPromptManager,
491 |       mockSemanticAnalyzer
492 |     );
493 | 
494 |     const executionStats = promptEngine.getAnalytics();
495 |     const parsingStats = promptEngine.getParsingStats();
496 | 
497 |     expect(executionStats).toHaveProperty('totalExecutions');
498 |     expect(executionStats).toHaveProperty('successfulExecutions');
499 |     expect(executionStats).toHaveProperty('executionsByMode');
500 | 
501 |     expect(parsingStats).toHaveProperty('commandParser');
502 |     expect(parsingStats).toHaveProperty('argumentProcessor');
503 |     expect(parsingStats).toHaveProperty('contextResolver');
504 |   });
505 | 
506 |   test('should enable performance monitoring', async () => {
507 |     const promptEngine = createConsolidatedPromptEngine(
508 |       mockLogger,
509 |       mockMcpServer,
510 |       mockPromptManager,
511 |       mockSemanticAnalyzer
512 |     );
513 |     
514 |     promptEngine.updateData(testPromptsData, testConvertedPrompts);
515 | 
516 |     // Perform operations
517 |     try {
518 |       await (promptEngine as any).parseCommandUnified('>>simple_test monitoring test');
519 |     } catch (error) {
520 |       // Expected in test environment
521 |     }
522 | 
523 |     const stats = promptEngine.getParsingStats();
524 |     
525 |     // Verify metrics are being collected
526 |     expect(stats.commandParser.totalParses).toBeGreaterThan(0);
527 |     expect(stats.commandParser.averageConfidence).toBeGreaterThanOrEqual(0);
528 |   });
529 | });
530 | 
```

--------------------------------------------------------------------------------
/server/src/prompts/file-observer.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * File Observer Module
  3 |  * Handles file system watching for automatic change detection and hot reload triggers
  4 |  */
  5 | 
  6 | import * as fs from "fs";
  7 | import { FSWatcher } from "fs";
  8 | import path from "path";
  9 | import { Logger } from "../logging/index.js";
 10 | import { EventEmitter } from "events";
 11 | import { ConfigManager } from "../config/index.js";
 12 | 
 13 | /**
 14 |  * File change event types
 15 |  */
 16 | export type FileChangeType = 'added' | 'modified' | 'removed' | 'renamed';
 17 | 
 18 | /**
 19 |  * Framework analysis data for file changes
 20 |  */
 21 | export interface FrameworkAnalysisData {
 22 |   requiresFrameworkUpdate: boolean;
 23 |   affectedFrameworks: string[];
 24 |   analysisInvalidated: boolean;
 25 |   performanceImpact: 'low' | 'medium' | 'high';
 26 | }
 27 | 
 28 | /**
 29 |  * File change event data
 30 |  */
 31 | export interface FileChangeEvent {
 32 |   type: FileChangeType;
 33 |   filePath: string;
 34 |   filename: string;
 35 |   timestamp: number;
 36 |   isPromptFile: boolean;
 37 |   isConfigFile: boolean;
 38 |   category?: string;
 39 |   frameworkAnalysis?: FrameworkAnalysisData;
 40 | }
 41 | 
 42 | /**
 43 |  * Framework integration capabilities
 44 |  */
 45 | export interface FrameworkIntegration {
 46 |   enabled: boolean;
 47 |   analyzeChanges: boolean;
 48 |   cacheInvalidation: boolean;
 49 |   performanceTracking: boolean;
 50 | }
 51 | 
 52 | /**
 53 |  * File observer configuration
 54 |  */
 55 | export interface FileObserverConfig {
 56 |   enabled: boolean;
 57 |   debounceMs: number;
 58 |   watchPromptFiles: boolean;
 59 |   watchConfigFiles: boolean;
 60 |   recursive: boolean;
 61 |   ignoredPatterns: string[];
 62 |   maxRetries: number;
 63 |   retryDelayMs: number;
 64 |   frameworkIntegration?: FrameworkIntegration;
 65 | }
 66 | 
 67 | /**
 68 |  * File observer statistics
 69 |  */
 70 | export interface FileObserverStats {
 71 |   watchersActive: number;
 72 |   eventsDetected: number;
 73 |   eventsDebounced: number;
 74 |   eventsTriggered: number;
 75 |   lastEventTime?: number;
 76 |   uptime: number;
 77 |   retryCount: number;
 78 |   frameworkEvents: number;
 79 |   frameworkCacheInvalidations: number;
 80 | }
 81 | 
 82 | /**
 83 |  * Default configuration for FileObserver
 84 |  */
 85 | const DEFAULT_CONFIG: FileObserverConfig = {
 86 |   enabled: true,
 87 |   debounceMs: 500,
 88 |   watchPromptFiles: true,
 89 |   watchConfigFiles: true,
 90 |   recursive: true,
 91 |   ignoredPatterns: [
 92 |     '**/.git/**',
 93 |     '**/node_modules/**',
 94 |     '**/.DS_Store',
 95 |     '**/Thumbs.db',
 96 |     '**/*.tmp',
 97 |     '**/*.temp',
 98 |     '**/dist/**',
 99 |     '**/*.log'
100 |   ],
101 |   maxRetries: 3,
102 |   retryDelayMs: 1000,
103 |   frameworkIntegration: {
104 |     enabled: false,
105 |     analyzeChanges: false,
106 |     cacheInvalidation: false,
107 |     performanceTracking: false
108 |   }
109 | };
110 | 
111 | /**
112 |  * FileObserver class
113 |  * Provides robust file system watching with event-driven architecture
114 |  */
115 | export class FileObserver extends EventEmitter {
116 |   protected logger: Logger;
117 |   private config: FileObserverConfig;
118 |   private watchers: Map<string, FSWatcher> = new Map();
119 |   private debounceTimers: Map<string, NodeJS.Timeout> = new Map();
120 |   private stats: FileObserverStats;
121 |   private isStarted: boolean = false;
122 |   private startTime: number = 0;
123 |   private retryCount: number = 0;
124 |   private configManager?: ConfigManager;
125 | 
126 |   constructor(logger: Logger, config?: Partial<FileObserverConfig>, configManager?: ConfigManager) {
127 |     super();
128 |     this.logger = logger;
129 |     this.config = { ...DEFAULT_CONFIG, ...config };
130 |     this.configManager = configManager;
131 |     this.stats = {
132 |       watchersActive: 0,
133 |       eventsDetected: 0,
134 |       eventsDebounced: 0,
135 |       eventsTriggered: 0,
136 |       uptime: 0,
137 |       retryCount: 0,
138 |       frameworkEvents: 0,
139 |       frameworkCacheInvalidations: 0
140 |     };
141 | 
142 |     // Set max listeners to prevent warning for multiple prompt directories
143 |     this.setMaxListeners(50);
144 |   }
145 | 
146 |   /**
147 |    * Start file watching
148 |    */
149 |   async start(): Promise<void> {
150 |     if (this.isStarted) {
151 |       this.logger.warn("FileObserver is already started");
152 |       return;
153 |     }
154 | 
155 |     if (!this.config.enabled) {
156 |       this.logger.info("FileObserver is disabled in configuration");
157 |       return;
158 |     }
159 | 
160 |     this.logger.info("📁 FileObserver: Starting file system watching...");
161 |     this.startTime = Date.now();
162 |     this.isStarted = true;
163 | 
164 |     // Listen for process termination to clean up watchers
165 |     process.on('SIGINT', () => this.stop());
166 |     process.on('SIGTERM', () => this.stop());
167 | 
168 |     this.logger.info(`✅ FileObserver started with debounce: ${this.config.debounceMs}ms`);
169 |   }
170 | 
171 |   /**
172 |    * Stop file watching and clean up resources
173 |    */
174 |   async stop(): Promise<void> {
175 |     if (!this.isStarted) {
176 |       return;
177 |     }
178 | 
179 |     this.logger.info("🛑 FileObserver: Stopping file system watching...");
180 | 
181 |     // Clear all debounce timers
182 |     for (const timer of this.debounceTimers.values()) {
183 |       clearTimeout(timer);
184 |     }
185 |     this.debounceTimers.clear();
186 | 
187 |     // Close all watchers
188 |     for (const [path, watcher] of this.watchers.entries()) {
189 |       try {
190 |         watcher.close();
191 |         this.logger.debug(`Closed watcher for: ${path}`);
192 |       } catch (error) {
193 |         this.logger.warn(`Failed to close watcher for ${path}:`, error);
194 |       }
195 |     }
196 |     this.watchers.clear();
197 | 
198 |     this.isStarted = false;
199 |     this.stats.watchersActive = 0;
200 | 
201 |     this.logger.info("✅ FileObserver stopped and resources cleaned up");
202 |   }
203 | 
204 |   /**
205 |    * Add a directory to watch
206 |    */
207 |   async watchDirectory(directoryPath: string, category?: string): Promise<void> {
208 |     if (!this.isStarted) {
209 |       throw new Error("FileObserver must be started before adding watchers");
210 |     }
211 | 
212 |     if (this.watchers.has(directoryPath)) {
213 |       this.logger.debug(`Directory already being watched: ${directoryPath}`);
214 |       return;
215 |     }
216 | 
217 |     try {
218 |       // Verify directory exists
219 |       const stats = await fs.promises.stat(directoryPath);
220 |       if (!stats.isDirectory()) {
221 |         throw new Error(`Path is not a directory: ${directoryPath}`);
222 |       }
223 | 
224 |       const watcher = fs.watch(directoryPath, { recursive: this.config.recursive }, (eventType, filename) => {
225 |         this.handleFileEvent(eventType, directoryPath, filename, category);
226 |       });
227 | 
228 |       watcher.on('error', (error) => {
229 |         this.handleWatcherError(directoryPath, error);
230 |       });
231 | 
232 |       this.watchers.set(directoryPath, watcher);
233 |       this.stats.watchersActive = this.watchers.size;
234 | 
235 |       this.logger.info(`👁️ FileObserver: Watching directory: ${directoryPath}${category ? ` (category: ${category})` : ''}`);
236 | 
237 |     } catch (error) {
238 |       this.logger.error(`Failed to watch directory ${directoryPath}:`, error);
239 |       if (this.retryCount < this.config.maxRetries) {
240 |         this.retryCount++;
241 |         this.stats.retryCount++;
242 |         this.logger.info(`Retrying in ${this.config.retryDelayMs}ms (attempt ${this.retryCount}/${this.config.maxRetries})`);
243 |         setTimeout(() => this.watchDirectory(directoryPath, category), this.config.retryDelayMs);
244 |       } else {
245 |         throw error;
246 |       }
247 |     }
248 |   }
249 | 
250 |   /**
251 |    * Remove a directory from watching
252 |    */
253 |   async unwatchDirectory(directoryPath: string): Promise<void> {
254 |     const watcher = this.watchers.get(directoryPath);
255 |     if (!watcher) {
256 |       this.logger.debug(`Directory not being watched: ${directoryPath}`);
257 |       return;
258 |     }
259 | 
260 |     try {
261 |       watcher.close();
262 |       this.watchers.delete(directoryPath);
263 |       this.stats.watchersActive = this.watchers.size;
264 | 
265 |       // Clear any pending debounce timers for this directory
266 |       const timersToRemove: string[] = [];
267 |       for (const [key, timer] of this.debounceTimers.entries()) {
268 |         if (key.startsWith(directoryPath)) {
269 |           clearTimeout(timer);
270 |           timersToRemove.push(key);
271 |         }
272 |       }
273 |       timersToRemove.forEach(key => this.debounceTimers.delete(key));
274 | 
275 |       this.logger.info(`🚫 FileObserver: Stopped watching directory: ${directoryPath}`);
276 | 
277 |     } catch (error) {
278 |       this.logger.error(`Failed to stop watching directory ${directoryPath}:`, error);
279 |       throw error;
280 |     }
281 |   }
282 | 
283 |   /**
284 |    * Handle file system events
285 |    */
286 |   private handleFileEvent(eventType: string, directoryPath: string, filename: string | null, category?: string): void {
287 |     if (!filename) {
288 |       return;
289 |     }
290 | 
291 |     const filePath = path.join(directoryPath, filename);
292 |     this.stats.eventsDetected++;
293 | 
294 |     // Check if file should be ignored
295 |     if (this.shouldIgnoreFile(filePath, filename)) {
296 |       return;
297 |     }
298 | 
299 |     // Determine file types
300 |     const isPromptFile = this.isPromptFile(filename);
301 |     const isConfigFile = this.isConfigFile(filename, filePath);
302 | 
303 |     // Skip if we're not watching this type
304 |     if (!isPromptFile && !isConfigFile) {
305 |       return;
306 |     }
307 | 
308 |     if (!this.config.watchPromptFiles && isPromptFile) {
309 |       return;
310 |     }
311 | 
312 |     if (!this.config.watchConfigFiles && isConfigFile) {
313 |       return;
314 |     }
315 | 
316 |     const changeType = this.mapEventType(eventType);
317 |     const event: FileChangeEvent = {
318 |       type: changeType,
319 |       filePath,
320 |       filename,
321 |       timestamp: Date.now(),
322 |       isPromptFile,
323 |       isConfigFile,
324 |       category
325 |     };
326 | 
327 |     // Add framework analysis if enabled
328 |     if (this.config.frameworkIntegration?.enabled) {
329 |       event.frameworkAnalysis = this.analyzeFrameworkImpact(event);
330 |       if (event.frameworkAnalysis.requiresFrameworkUpdate) {
331 |         this.stats.frameworkEvents++;
332 |       }
333 |     }
334 | 
335 |     this.logger.debug(`File event detected: ${changeType} ${filename} in ${directoryPath}`);
336 | 
337 |     // Apply debouncing
338 |     this.debounceEvent(event);
339 |   }
340 | 
341 |   /**
342 |    * Apply debouncing to prevent excessive event firing
343 |    */
344 |   private debounceEvent(event: FileChangeEvent): void {
345 |     const debounceKey = `${event.filePath}_${event.type}`;
346 |     
347 |     // Clear existing timer for this file+type
348 |     const existingTimer = this.debounceTimers.get(debounceKey);
349 |     if (existingTimer) {
350 |       clearTimeout(existingTimer);
351 |       this.stats.eventsDebounced++;
352 |     }
353 | 
354 |     // Set new timer
355 |     const timer = setTimeout(() => {
356 |       this.debounceTimers.delete(debounceKey);
357 |       this.emitFileChangeEvent(event);
358 |     }, this.config.debounceMs);
359 | 
360 |     this.debounceTimers.set(debounceKey, timer);
361 |   }
362 | 
363 |   /**
364 |    * Emit the file change event
365 |    */
366 |   private emitFileChangeEvent(event: FileChangeEvent): void {
367 |     this.stats.eventsTriggered++;
368 |     this.stats.lastEventTime = event.timestamp;
369 | 
370 |     this.logger.info(`🔄 FileObserver: File ${event.type}: ${event.filename}`);
371 |     
372 |     // Emit specific event types
373 |     this.emit('fileChange', event);
374 |     this.emit(`file:${event.type}`, event);
375 |     
376 |     if (event.isPromptFile) {
377 |       this.emit('promptFileChange', event);
378 |     }
379 |     
380 |     if (event.isConfigFile) {
381 |       this.emit('configFileChange', event);
382 |     }
383 |   }
384 | 
385 |   /**
386 |    * Handle watcher errors
387 |    */
388 |   private handleWatcherError(directoryPath: string, error: Error): void {
389 |     this.logger.error(`FileObserver: Watcher error for ${directoryPath}:`, error);
390 |     
391 |     // Remove failed watcher
392 |     this.watchers.delete(directoryPath);
393 |     this.stats.watchersActive = this.watchers.size;
394 | 
395 |     // Emit error event
396 |     this.emit('watcherError', { directoryPath, error });
397 | 
398 |     // Attempt to restart watcher
399 |     if (this.retryCount < this.config.maxRetries) {
400 |       this.retryCount++;
401 |       this.stats.retryCount++;
402 |       setTimeout(() => {
403 |         this.logger.info(`Attempting to restart watcher for: ${directoryPath}`);
404 |         this.watchDirectory(directoryPath).catch(retryError => {
405 |           this.logger.error(`Failed to restart watcher for ${directoryPath}:`, retryError);
406 |         });
407 |       }, this.config.retryDelayMs);
408 |     }
409 |   }
410 | 
411 |   /**
412 |    * Check if file should be ignored
413 |    */
414 |   private shouldIgnoreFile(filePath: string, filename: string): boolean {
415 |     const normalizedPath = path.normalize(filePath).replace(/\\/g, '/');
416 |     
417 |     return this.config.ignoredPatterns.some(pattern => {
418 |       // Simple glob pattern matching
419 |       const regexPattern = pattern
420 |         .replace(/\*\*/g, '.*')
421 |         .replace(/\*/g, '[^/]*')
422 |         .replace(/\?/g, '[^/]');
423 |       
424 |       const regex = new RegExp(`^${regexPattern}$`);
425 |       return regex.test(normalizedPath) || regex.test(filename);
426 |     });
427 |   }
428 | 
429 |   /**
430 |    * Check if file is a prompt file
431 |    */
432 |   private isPromptFile(filename: string): boolean {
433 |     const ext = path.extname(filename).toLowerCase();
434 |     return ext === '.md' || ext === '.markdown';
435 |   }
436 | 
437 |   /**
438 |    * Check if file is a configuration file
439 |    */
440 |   private isConfigFile(filename: string, fullPath?: string): boolean {
441 |     const basename = path.basename(filename);
442 |     
443 |     // Standard config files
444 |     if (basename === 'prompts.json' || basename === 'config.json') {
445 |       return true;
446 |     }
447 |     
448 |     // Main prompts config - get filename from ConfigManager if available
449 |     if (this.configManager && fullPath) {
450 |       try {
451 |         const mainConfigPath = this.configManager.getPromptsFilePath();
452 |         const mainConfigFilename = path.basename(mainConfigPath);
453 |         return basename === mainConfigFilename;
454 |       } catch (error) {
455 |         // Fallback to default behavior if ConfigManager fails
456 |         this.logger.debug(`Could not get prompts config path from ConfigManager: ${error}`);
457 |       }
458 |     }
459 |     
460 |     // Fallback for backward compatibility
461 |     return basename === 'promptsConfig.json';
462 |   }
463 | 
464 |   /**
465 |    * Map fs.watch event types to our event types
466 |    */
467 |   private mapEventType(eventType: string): FileChangeType {
468 |     switch (eventType) {
469 |       case 'rename':
470 |         return 'renamed';
471 |       case 'change':
472 |         return 'modified';
473 |       default:
474 |         return 'modified';
475 |     }
476 |   }
477 | 
478 |   /**
479 |    * Get current statistics
480 |    */
481 |   getStats(): FileObserverStats {
482 |     return {
483 |       ...this.stats,
484 |       uptime: this.isStarted ? Date.now() - this.startTime : 0
485 |     };
486 |   }
487 | 
488 |   /**
489 |    * Get current configuration
490 |    */
491 |   getConfig(): FileObserverConfig {
492 |     return { ...this.config };
493 |   }
494 | 
495 |   /**
496 |    * Update configuration
497 |    */
498 |   updateConfig(newConfig: Partial<FileObserverConfig>): void {
499 |     this.config = { ...this.config, ...newConfig };
500 |     this.logger.info("FileObserver configuration updated");
501 |   }
502 | 
503 |   /**
504 |    * Get list of watched directories
505 |    */
506 |   getWatchedDirectories(): string[] {
507 |     return Array.from(this.watchers.keys());
508 |   }
509 | 
510 |   /**
511 |    * Check if FileObserver is running
512 |    */
513 |   isRunning(): boolean {
514 |     return this.isStarted;
515 |   }
516 | 
517 |   /**
518 |    * Analyze framework impact of file changes
519 |    * Phase 1: Basic analysis without complex framework dependencies
520 |    */
521 |   private analyzeFrameworkImpact(event: FileChangeEvent): FrameworkAnalysisData {
522 |     // Basic framework analysis for Phase 1 compatibility
523 |     const requiresFrameworkUpdate = event.isPromptFile || event.isConfigFile;
524 |     const affectedFrameworks = requiresFrameworkUpdate ? ['basic'] : [];
525 |     const analysisInvalidated = event.isPromptFile && (event.type === 'modified' || event.type === 'added');
526 |     const performanceImpact: 'low' | 'medium' | 'high' = event.isConfigFile ? 'high' : 'low';
527 | 
528 |     if (requiresFrameworkUpdate && this.config.frameworkIntegration?.cacheInvalidation) {
529 |       this.stats.frameworkCacheInvalidations++;
530 |       this.logger.debug(`Framework cache invalidation triggered by ${event.filename}`);
531 |     }
532 | 
533 |     return {
534 |       requiresFrameworkUpdate,
535 |       affectedFrameworks,
536 |       analysisInvalidated,
537 |       performanceImpact
538 |     };
539 |   }
540 | 
541 |   /**
542 |    * Enable framework integration
543 |    */
544 |   enableFrameworkIntegration(options: Partial<FrameworkIntegration> = {}): void {
545 |     this.config.frameworkIntegration = {
546 |       enabled: true,
547 |       analyzeChanges: true,
548 |       cacheInvalidation: true,
549 |       performanceTracking: true,
550 |       ...options
551 |     };
552 |     this.logger.info("Framework integration enabled for FileObserver");
553 |   }
554 | 
555 |   /**
556 |    * Disable framework integration
557 |    */
558 |   disableFrameworkIntegration(): void {
559 |     this.config.frameworkIntegration = {
560 |       enabled: false,
561 |       analyzeChanges: false,
562 |       cacheInvalidation: false,
563 |       performanceTracking: false
564 |     };
565 |     this.logger.info("Framework integration disabled for FileObserver");
566 |   }
567 | 
568 |   /**
569 |    * Check if framework integration is enabled
570 |    */
571 |   isFrameworkIntegrationEnabled(): boolean {
572 |     return this.config.frameworkIntegration?.enabled ?? false;
573 |   }
574 | 
575 |   /**
576 |    * Get debug information
577 |    */
578 |   getDebugInfo(): {
579 |     isRunning: boolean;
580 |     config: FileObserverConfig;
581 |     stats: FileObserverStats;
582 |     watchedDirectories: string[];
583 |     activeDebounceTimers: number;
584 |     frameworkIntegration: FrameworkIntegration | undefined;
585 |   } {
586 |     return {
587 |       isRunning: this.isRunning(),
588 |       config: this.getConfig(),
589 |       stats: this.getStats(),
590 |       watchedDirectories: this.getWatchedDirectories(),
591 |       activeDebounceTimers: this.debounceTimers.size,
592 |       frameworkIntegration: this.config.frameworkIntegration
593 |     };
594 |   }
595 | }
596 | 
597 | /**
598 |  * Factory function to create a FileObserver instance
599 |  */
600 | export function createFileObserver(logger: Logger, config?: Partial<FileObserverConfig>, configManager?: ConfigManager): FileObserver {
601 |   return new FileObserver(logger, config, configManager);
602 | }
```
Page 9/18FirstPrevNextLast