#
tokens: 48173/50000 9/252 files (page 10/18)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 10 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/prompts/hot-reload-manager.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Hot Reload Manager Module
  3 |  * Orchestrates file system monitoring and reload workflows with event-driven architecture
  4 |  */
  5 | 
  6 | import { Logger } from "../logging/index.js";
  7 | import { FileObserver, FileChangeEvent, FileObserverConfig, createFileObserver } from "./file-observer.js";
  8 | import { CategoryManager } from "./category-manager.js";
  9 | import { ConfigManager } from "../config/index.js";
 10 | import path from "path";
 11 | import * as fs from "fs/promises";
 12 | 
 13 | /**
 14 |  * Hot reload event types
 15 |  */
 16 | export type HotReloadEventType = 'prompt_changed' | 'config_changed' | 'category_changed' | 'reload_required';
 17 | 
 18 | /**
 19 |  * Hot reload event data
 20 |  */
 21 | export interface HotReloadEvent {
 22 |   type: HotReloadEventType;
 23 |   reason: string;
 24 |   affectedFiles: string[];
 25 |   category?: string;
 26 |   timestamp: number;
 27 |   requiresFullReload: boolean;
 28 | }
 29 | 
 30 | /**
 31 |  * Framework-aware hot reload capabilities
 32 |  */
 33 | export interface FrameworkHotReloadCapabilities {
 34 |   enabled: boolean;
 35 |   frameworkAnalysis: boolean;
 36 |   performanceMonitoring: boolean;
 37 |   preWarmAnalysis: boolean;
 38 |   invalidateFrameworkCaches: boolean;
 39 | }
 40 | 
 41 | /**
 42 |  * Hot reload configuration
 43 |  */
 44 | export interface HotReloadConfig extends Partial<FileObserverConfig> {
 45 |   enabled: boolean;
 46 |   autoReload: boolean;
 47 |   reloadDelayMs: number;
 48 |   batchChanges: boolean;
 49 |   batchTimeoutMs: number;
 50 |   frameworkCapabilities?: FrameworkHotReloadCapabilities;
 51 | }
 52 | 
 53 | /**
 54 |  * Hot reload statistics
 55 |  */
 56 | export interface HotReloadStats {
 57 |   reloadsTriggered: number;
 58 |   filesChanged: number;
 59 |   lastReloadTime?: number;
 60 |   autoReloadsEnabled: boolean;
 61 |   fileObserverStats: ReturnType<FileObserver['getStats']>;
 62 |   frameworkReloads: number;
 63 |   frameworkCacheClears: number;
 64 |   performanceOptimizations: number;
 65 | }
 66 | 
 67 | /**
 68 |  * Hot reload manager configuration
 69 |  */
 70 | const DEFAULT_HOT_RELOAD_CONFIG: HotReloadConfig = {
 71 |   enabled: true,
 72 |   autoReload: true,
 73 |   reloadDelayMs: 1000,
 74 |   batchChanges: true,
 75 |   batchTimeoutMs: 2000,
 76 |   debounceMs: 500,
 77 |   watchPromptFiles: true,
 78 |   watchConfigFiles: true,
 79 |   recursive: true,
 80 |   ignoredPatterns: [
 81 |     '**/.git/**',
 82 |     '**/node_modules/**',
 83 |     '**/.DS_Store',
 84 |     '**/Thumbs.db',
 85 |     '**/*.tmp',
 86 |     '**/*.temp',
 87 |     '**/dist/**',
 88 |     '**/*.log'
 89 |   ],
 90 |   maxRetries: 3,
 91 |   retryDelayMs: 1000,
 92 |   frameworkCapabilities: {
 93 |     enabled: false,
 94 |     frameworkAnalysis: false,
 95 |     performanceMonitoring: false,
 96 |     preWarmAnalysis: false,
 97 |     invalidateFrameworkCaches: false
 98 |   }
 99 | };
100 | 
101 | /**
102 |  * HotReloadManager class
103 |  * Coordinates file watching and reload operations
104 |  */
105 | export class HotReloadManager {
106 |   protected logger: Logger;
107 |   private config: HotReloadConfig;
108 |   private fileObserver: FileObserver;
109 |   private categoryManager?: CategoryManager;
110 |   private onReloadCallback?: (event: HotReloadEvent) => Promise<void>;
111 |   private stats: HotReloadStats;
112 |   private isStarted: boolean = false;
113 |   private batchTimer?: NodeJS.Timeout;
114 |   private pendingChanges: FileChangeEvent[] = [];
115 |   private watchedDirectories: Set<string> = new Set();
116 | 
117 |   constructor(
118 |     logger: Logger, 
119 |     categoryManager?: CategoryManager,
120 |     config?: Partial<HotReloadConfig>,
121 |     configManager?: ConfigManager
122 |   ) {
123 |     this.logger = logger;
124 |     this.categoryManager = categoryManager;
125 |     this.config = { ...DEFAULT_HOT_RELOAD_CONFIG, ...config };
126 |     
127 |     // Create file observer with filtered config
128 |     const observerConfig = {
129 |       enabled: this.config.enabled,
130 |       debounceMs: this.config.debounceMs,
131 |       watchPromptFiles: this.config.watchPromptFiles,
132 |       watchConfigFiles: this.config.watchConfigFiles,
133 |       recursive: this.config.recursive,
134 |       ignoredPatterns: this.config.ignoredPatterns,
135 |       maxRetries: this.config.maxRetries,
136 |       retryDelayMs: this.config.retryDelayMs
137 |     };
138 |     
139 |     this.fileObserver = createFileObserver(logger, observerConfig, configManager);
140 |     
141 |     this.stats = {
142 |       reloadsTriggered: 0,
143 |       filesChanged: 0,
144 |       autoReloadsEnabled: this.config.autoReload,
145 |       fileObserverStats: this.fileObserver.getStats(),
146 |       frameworkReloads: 0,
147 |       frameworkCacheClears: 0,
148 |       performanceOptimizations: 0
149 |     };
150 | 
151 |     this.setupFileObserverEventHandlers();
152 |   }
153 | 
154 |   /**
155 |    * Start hot reload monitoring
156 |    */
157 |   async start(): Promise<void> {
158 |     if (this.isStarted) {
159 |       this.logger.warn("HotReloadManager is already started");
160 |       return;
161 |     }
162 | 
163 |     if (!this.config.enabled) {
164 |       this.logger.info("HotReloadManager is disabled in configuration");
165 |       return;
166 |     }
167 | 
168 |     this.logger.info("🔥 HotReloadManager: Starting hot reload monitoring...");
169 | 
170 |     await this.fileObserver.start();
171 |     this.isStarted = true;
172 | 
173 |     this.logger.info(`✅ HotReloadManager started - Auto reload: ${this.config.autoReload ? 'ON' : 'OFF'}`);
174 |   }
175 | 
176 |   /**
177 |    * Stop hot reload monitoring
178 |    */
179 |   async stop(): Promise<void> {
180 |     if (!this.isStarted) {
181 |       return;
182 |     }
183 | 
184 |     this.logger.info("🛑 HotReloadManager: Stopping hot reload monitoring...");
185 | 
186 |     // Clear batch timer
187 |     if (this.batchTimer) {
188 |       clearTimeout(this.batchTimer);
189 |       this.batchTimer = undefined;
190 |     }
191 | 
192 |     await this.fileObserver.stop();
193 |     this.isStarted = false;
194 | 
195 |     this.logger.info("✅ HotReloadManager stopped");
196 |   }
197 | 
198 |   /**
199 |    * Set the callback for reload events
200 |    */
201 |   setReloadCallback(callback: (event: HotReloadEvent) => Promise<void>): void {
202 |     this.onReloadCallback = callback;
203 |     this.logger.debug("HotReloadManager: Reload callback registered");
204 |   }
205 | 
206 |   /**
207 |    * Add directories to watch
208 |    */
209 |   async watchDirectories(directories: Array<{ path: string; category?: string }>): Promise<void> {
210 |     if (!this.isStarted) {
211 |       throw new Error("HotReloadManager must be started before watching directories");
212 |     }
213 | 
214 |     for (const { path: dirPath, category } of directories) {
215 |       try {
216 |         await this.fileObserver.watchDirectory(dirPath, category);
217 |         this.watchedDirectories.add(dirPath);
218 |         this.logger.info(`📁 HotReloadManager: Watching directory: ${dirPath}${category ? ` (${category})` : ''}`);
219 |       } catch (error) {
220 |         this.logger.error(`Failed to watch directory ${dirPath}:`, error);
221 |       }
222 |     }
223 |   }
224 | 
225 |   /**
226 |    * Manually trigger a reload
227 |    */
228 |   async triggerReload(reason: string = 'Manual trigger', requiresFullReload: boolean = true): Promise<void> {
229 |     const event: HotReloadEvent = {
230 |       type: 'reload_required',
231 |       reason,
232 |       affectedFiles: [],
233 |       timestamp: Date.now(),
234 |       requiresFullReload
235 |     };
236 | 
237 |     await this.processReloadEvent(event);
238 |   }
239 | 
240 |   /**
241 |    * Setup file observer event handlers
242 |    */
243 |   private setupFileObserverEventHandlers(): void {
244 |     this.fileObserver.on('fileChange', (event: FileChangeEvent) => {
245 |       this.handleFileChange(event);
246 |     });
247 | 
248 |     this.fileObserver.on('watcherError', (error: { directoryPath: string; error: Error }) => {
249 |       this.logger.error(`File watcher error for ${error.directoryPath}:`, error.error);
250 |     });
251 | 
252 |     this.logger.debug("HotReloadManager: File observer event handlers registered");
253 |   }
254 | 
255 |   /**
256 |    * Handle file change events
257 |    */
258 |   private handleFileChange(event: FileChangeEvent): void {
259 |     this.stats.filesChanged++;
260 |     this.logger.debug(`File change detected: ${event.type} - ${event.filename}`);
261 | 
262 |     if (this.config.batchChanges) {
263 |       this.batchFileChange(event);
264 |     } else {
265 |       this.processFileChangeImmediate(event);
266 |     }
267 |   }
268 | 
269 |   /**
270 |    * Batch file changes to prevent excessive reloads
271 |    */
272 |   private batchFileChange(event: FileChangeEvent): void {
273 |     this.pendingChanges.push(event);
274 | 
275 |     // Clear existing timer
276 |     if (this.batchTimer) {
277 |       clearTimeout(this.batchTimer);
278 |     }
279 | 
280 |     // Set new timer
281 |     this.batchTimer = setTimeout(() => {
282 |       this.processBatchedChanges();
283 |     }, this.config.batchTimeoutMs);
284 |   }
285 | 
286 |   /**
287 |    * Process batched file changes
288 |    */
289 |   private async processBatchedChanges(): Promise<void> {
290 |     if (this.pendingChanges.length === 0) {
291 |       return;
292 |     }
293 | 
294 |     const changes = [...this.pendingChanges];
295 |     this.pendingChanges = [];
296 |     this.batchTimer = undefined;
297 | 
298 |     this.logger.info(`Processing ${changes.length} batched file changes`);
299 | 
300 |     // Group changes by type
301 |     const promptChanges = changes.filter(c => c.isPromptFile);
302 |     const configChanges = changes.filter(c => c.isConfigFile);
303 | 
304 |     // Determine reload type
305 |     const requiresFullReload = configChanges.length > 0 || 
306 |       promptChanges.some(c => c.type === 'added' || c.type === 'removed');
307 | 
308 |     let reloadType: HotReloadEventType = 'prompt_changed';
309 |     let reason = `${promptChanges.length} prompt file(s) changed`;
310 | 
311 |     if (configChanges.length > 0) {
312 |       reloadType = 'config_changed';
313 |       reason = `${configChanges.length} config file(s) changed`;
314 |     }
315 | 
316 |     const hotReloadEvent: HotReloadEvent = {
317 |       type: reloadType,
318 |       reason,
319 |       affectedFiles: changes.map(c => c.filePath),
320 |       timestamp: Date.now(),
321 |       requiresFullReload
322 |     };
323 | 
324 |     await this.processReloadEvent(hotReloadEvent);
325 |   }
326 | 
327 |   /**
328 |    * Process immediate file change (no batching)
329 |    */
330 |   private async processFileChangeImmediate(event: FileChangeEvent): Promise<void> {
331 |     let reloadType: HotReloadEventType = 'prompt_changed';
332 |     let requiresFullReload = false;
333 | 
334 |     if (event.isConfigFile) {
335 |       reloadType = 'config_changed';
336 |       requiresFullReload = true;
337 |     } else if (event.type === 'added' || event.type === 'removed') {
338 |       requiresFullReload = true;
339 |     }
340 | 
341 |     const hotReloadEvent: HotReloadEvent = {
342 |       type: reloadType,
343 |       reason: `File ${event.type}: ${event.filename}`,
344 |       affectedFiles: [event.filePath],
345 |       category: event.category,
346 |       timestamp: event.timestamp,
347 |       requiresFullReload
348 |     };
349 | 
350 |     await this.processReloadEvent(hotReloadEvent);
351 |   }
352 | 
353 |   /**
354 |    * Process reload event with framework integration
355 |    */
356 |   protected async processReloadEvent(event: HotReloadEvent): Promise<void> {
357 |     this.stats.reloadsTriggered++;
358 |     this.stats.lastReloadTime = event.timestamp;
359 | 
360 |     this.logger.info(`🔄 Hot reload triggered: ${event.reason}`);
361 | 
362 |     // Framework-aware pre-processing
363 |     if (this.config.frameworkCapabilities?.enabled) {
364 |       await this.processFrameworkPreReload(event);
365 |     }
366 | 
367 |     if (this.config.autoReload && this.onReloadCallback) {
368 |       try {
369 |         // Add delay if configured
370 |         if (this.config.reloadDelayMs > 0) {
371 |           this.logger.debug(`Delaying reload by ${this.config.reloadDelayMs}ms`);
372 |           await new Promise(resolve => setTimeout(resolve, this.config.reloadDelayMs));
373 |         }
374 | 
375 |         await this.onReloadCallback(event);
376 |         
377 |         // Framework-aware post-processing
378 |         if (this.config.frameworkCapabilities?.enabled) {
379 |           await this.processFrameworkPostReload(event);
380 |         }
381 | 
382 |         this.logger.info("✅ Hot reload completed successfully");
383 | 
384 |       } catch (error) {
385 |         this.logger.error("❌ Hot reload failed:", error);
386 |       }
387 |     } else {
388 |       this.logger.info("⏭️ Auto reload is disabled - skipping automatic reload");
389 |     }
390 |   }
391 | 
392 |   /**
393 |    * Get current statistics
394 |    */
395 |   getStats(): HotReloadStats {
396 |     return {
397 |       ...this.stats,
398 |       fileObserverStats: this.fileObserver.getStats()
399 |     };
400 |   }
401 | 
402 |   /**
403 |    * Get current configuration
404 |    */
405 |   getConfig(): HotReloadConfig {
406 |     return { ...this.config };
407 |   }
408 | 
409 |   /**
410 |    * Update configuration
411 |    */
412 |   updateConfig(newConfig: Partial<HotReloadConfig>): void {
413 |     const oldAutoReload = this.config.autoReload;
414 |     this.config = { ...this.config, ...newConfig };
415 |     
416 |     // Update file observer config if needed
417 |     if (newConfig.debounceMs !== undefined || 
418 |         newConfig.watchPromptFiles !== undefined || 
419 |         newConfig.watchConfigFiles !== undefined) {
420 |       this.fileObserver.updateConfig({
421 |         debounceMs: this.config.debounceMs,
422 |         watchPromptFiles: this.config.watchPromptFiles,
423 |         watchConfigFiles: this.config.watchConfigFiles
424 |       });
425 |     }
426 | 
427 |     if (oldAutoReload !== this.config.autoReload) {
428 |       this.stats.autoReloadsEnabled = this.config.autoReload;
429 |       this.logger.info(`Auto reload ${this.config.autoReload ? 'enabled' : 'disabled'}`);
430 |     }
431 | 
432 |     this.logger.info("HotReloadManager configuration updated");
433 |   }
434 | 
435 |   /**
436 |    * Check if hot reload manager is running
437 |    */
438 |   isRunning(): boolean {
439 |     return this.isStarted;
440 |   }
441 | 
442 |   /**
443 |    * Get watched directories
444 |    */
445 |   getWatchedDirectories(): string[] {
446 |     return Array.from(this.watchedDirectories);
447 |   }
448 | 
449 |   /**
450 |    * Framework pre-reload processing
451 |    * Phase 1: Basic framework cache invalidation and analysis
452 |    */
453 |   private async processFrameworkPreReload(event: HotReloadEvent): Promise<void> {
454 |     const startTime = performance.now();
455 |     
456 |     this.logger.debug("Processing framework pre-reload analysis...");
457 |     
458 |     if (this.config.frameworkCapabilities?.invalidateFrameworkCaches) {
459 |       this.stats.frameworkCacheClears++;
460 |       this.logger.debug("Framework caches invalidated for hot-reload");
461 |     }
462 |     
463 |     if (this.config.frameworkCapabilities?.frameworkAnalysis) {
464 |       this.stats.frameworkReloads++;
465 |       this.logger.debug(`Framework analysis prepared for ${event.affectedFiles.length} files`);
466 |     }
467 |     
468 |     const processingTime = performance.now() - startTime;
469 |     this.logger.debug(`Framework pre-reload completed in ${processingTime.toFixed(2)}ms`);
470 |   }
471 | 
472 |   /**
473 |    * Framework post-reload processing
474 |    * Phase 1: Basic performance optimization and cache warming
475 |    */
476 |   private async processFrameworkPostReload(event: HotReloadEvent): Promise<void> {
477 |     const startTime = performance.now();
478 |     
479 |     this.logger.debug("Processing framework post-reload optimizations...");
480 |     
481 |     if (this.config.frameworkCapabilities?.preWarmAnalysis) {
482 |       this.stats.performanceOptimizations++;
483 |       this.logger.debug("Framework analysis cache pre-warmed");
484 |     }
485 |     
486 |     if (this.config.frameworkCapabilities?.performanceMonitoring) {
487 |       const processingTime = performance.now() - startTime;
488 |       this.logger.debug(`Framework post-reload monitoring: ${processingTime.toFixed(2)}ms`);
489 |     }
490 |   }
491 | 
492 |   /**
493 |    * Enable framework capabilities
494 |    */
495 |   enableFrameworkCapabilities(options: Partial<FrameworkHotReloadCapabilities> = {}): void {
496 |     this.config.frameworkCapabilities = {
497 |       enabled: true,
498 |       frameworkAnalysis: true,
499 |       performanceMonitoring: true,
500 |       preWarmAnalysis: true,
501 |       invalidateFrameworkCaches: true,
502 |       ...options
503 |     };
504 |     
505 |     // Enable framework integration on file observer if available
506 |     if ('enableFrameworkIntegration' in this.fileObserver) {
507 |       (this.fileObserver as any).enableFrameworkIntegration({
508 |         enabled: true,
509 |         analyzeChanges: this.config.frameworkCapabilities.frameworkAnalysis,
510 |         cacheInvalidation: this.config.frameworkCapabilities.invalidateFrameworkCaches,
511 |         performanceTracking: this.config.frameworkCapabilities.performanceMonitoring
512 |       });
513 |     }
514 |     
515 |     this.logger.info("Framework capabilities enabled for HotReloadManager");
516 |   }
517 | 
518 |   /**
519 |    * Disable framework capabilities
520 |    */
521 |   disableFrameworkCapabilities(): void {
522 |     this.config.frameworkCapabilities = {
523 |       enabled: false,
524 |       frameworkAnalysis: false,
525 |       performanceMonitoring: false,
526 |       preWarmAnalysis: false,
527 |       invalidateFrameworkCaches: false
528 |     };
529 |     
530 |     // Disable framework integration on file observer if available
531 |     if ('disableFrameworkIntegration' in this.fileObserver) {
532 |       (this.fileObserver as any).disableFrameworkIntegration();
533 |     }
534 |     
535 |     this.logger.info("Framework capabilities disabled for HotReloadManager");
536 |   }
537 | 
538 |   /**
539 |    * Check if framework capabilities are enabled
540 |    */
541 |   isFrameworkCapabilitiesEnabled(): boolean {
542 |     return this.config.frameworkCapabilities?.enabled ?? false;
543 |   }
544 | 
545 |   /**
546 |    * Get debug information
547 |    */
548 |   getDebugInfo(): {
549 |     isRunning: boolean;
550 |     config: HotReloadConfig;
551 |     stats: HotReloadStats;
552 |     watchedDirectories: string[];
553 |     pendingChanges: number;
554 |     fileObserverDebug: ReturnType<FileObserver['getDebugInfo']>;
555 |     frameworkCapabilities: FrameworkHotReloadCapabilities | undefined;
556 |   } {
557 |     return {
558 |       isRunning: this.isRunning(),
559 |       config: this.getConfig(),
560 |       stats: this.getStats(),
561 |       watchedDirectories: this.getWatchedDirectories(),
562 |       pendingChanges: this.pendingChanges.length,
563 |       fileObserverDebug: this.fileObserver.getDebugInfo(),
564 |       frameworkCapabilities: this.config.frameworkCapabilities
565 |     };
566 |   }
567 | }
568 | 
569 | /**
570 |  * Factory function to create a HotReloadManager instance
571 |  */
572 | export function createHotReloadManager(
573 |   logger: Logger, 
574 |   categoryManager?: CategoryManager,
575 |   config?: Partial<HotReloadConfig>,
576 |   configManager?: ConfigManager
577 | ): HotReloadManager {
578 |   return new HotReloadManager(logger, categoryManager, config, configManager);
579 | }
```

--------------------------------------------------------------------------------
/server/src/prompts/registry.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Prompt Registry Module
  3 |  * Handles registering prompts with MCP server using proper MCP protocol and managing conversation history
  4 |  */
  5 | 
  6 | import { z } from "zod";
  7 | import { ConfigManager } from "../config/index.js";
  8 | import { Logger } from "../logging/index.js";
  9 | import {
 10 |   ConversationHistoryItem,
 11 |   ConvertedPrompt,
 12 | } from "../types/index.js";
 13 | import { isChainPrompt } from "../utils/chainUtils.js";
 14 | // TemplateProcessor functionality consolidated into UnifiedPromptProcessor
 15 | 
 16 | /**
 17 |  * Prompt Registry class
 18 |  */
 19 | export class PromptRegistry {
 20 |   private logger: Logger;
 21 |   private mcpServer: any;
 22 |   private configManager: ConfigManager;
 23 |   // templateProcessor removed - functionality consolidated into UnifiedPromptProcessor
 24 |   private conversationHistory: ConversationHistoryItem[] = [];
 25 |   private readonly MAX_HISTORY_SIZE = 100;
 26 |   private registeredPromptNames = new Set<string>(); // Track registered prompts to prevent duplicates
 27 | 
 28 |   /**
 29 |    * Direct template processing method (minimal implementation)
 30 |    * Replaces templateProcessor calls for basic template processing
 31 |    */
 32 |   private async processTemplateDirect(
 33 |     template: string,
 34 |     args: Record<string, string>,
 35 |     specialContext: Record<string, string> = {},
 36 |     toolsEnabled: boolean = false
 37 |   ): Promise<string> {
 38 |     // Import jsonUtils for basic template processing
 39 |     const { processTemplate } = await import("../utils/jsonUtils.js");
 40 |     const { getAvailableTools } = await import("../utils/index.js");
 41 |     
 42 |     const enhancedSpecialContext = { ...specialContext };
 43 |     if (toolsEnabled) {
 44 |       enhancedSpecialContext["tools_available"] = getAvailableTools();
 45 |     }
 46 |     
 47 |     return processTemplate(template, args, enhancedSpecialContext);
 48 |   }
 49 | 
 50 |   constructor(
 51 |     logger: Logger,
 52 |     mcpServer: any,
 53 |     configManager: ConfigManager
 54 |   ) {
 55 |     this.logger = logger;
 56 |     this.mcpServer = mcpServer;
 57 |     this.configManager = configManager;
 58 |     // templateProcessor removed - functionality consolidated into UnifiedPromptProcessor
 59 |   }
 60 | 
 61 |   /**
 62 |    * Register individual prompts using MCP SDK registerPrompt API
 63 |    * This implements the standard MCP prompts protocol using the high-level API
 64 |    */
 65 |   private registerIndividualPrompts(prompts: ConvertedPrompt[]): void {
 66 |     try {
 67 |       this.logger.info('Registering individual prompts with MCP SDK...');
 68 |       let registeredCount = 0;
 69 | 
 70 |       for (const prompt of prompts) {
 71 |         // Skip if already registered (deduplication guard)
 72 |         if (this.registeredPromptNames.has(prompt.name)) {
 73 |           this.logger.debug(`Skipping already registered prompt: ${prompt.name}`);
 74 |           continue;
 75 |         }
 76 | 
 77 |         // Create argument schema
 78 |         const argsSchema: Record<string, any> = {};
 79 |         for (const arg of prompt.arguments) {
 80 |           argsSchema[arg.name] = z
 81 |             .string()
 82 |             .optional()
 83 |             .describe(arg.description || `Argument: ${arg.name}`);
 84 |         }
 85 | 
 86 |         // Register the prompt using the correct MCP SDK API with error recovery
 87 |         try {
 88 |           this.mcpServer.registerPrompt(
 89 |             prompt.name,
 90 |             {
 91 |               title: prompt.name,
 92 |               description: prompt.description || `Prompt: ${prompt.name}`,
 93 |               argsSchema
 94 |             },
 95 |             async (args: any) => {
 96 |               this.logger.debug(`Executing prompt '${prompt.name}' with args:`, args);
 97 |               return await this.executePromptLogic(prompt, args || {});
 98 |             }
 99 |           );
100 | 
101 |           // Track the registered prompt
102 |           this.registeredPromptNames.add(prompt.name);
103 |           registeredCount++;
104 |           this.logger.debug(`Registered prompt: ${prompt.name}`);
105 |         } catch (error: any) {
106 |           if (error.message && error.message.includes('already registered')) {
107 |             // Handle MCP SDK's "already registered" error gracefully
108 |             this.logger.warn(`Prompt '${prompt.name}' already registered in MCP SDK, skipping re-registration`);
109 |             this.registeredPromptNames.add(prompt.name); // Track it anyway
110 |             continue;
111 |           } else {
112 |             // Re-throw other errors
113 |             this.logger.error(`Failed to register prompt '${prompt.name}':`, error.message || error);
114 |             throw error;
115 |           }
116 |         }
117 |       }
118 | 
119 |       this.logger.info(`Successfully registered ${registeredCount} of ${prompts.length} prompts with MCP SDK`);
120 |     } catch (error) {
121 |       this.logger.error('Error registering individual prompts:', error instanceof Error ? error.message : String(error));
122 |       throw error;
123 |     }
124 |   }
125 | 
126 |   /**
127 |    * Execute prompt logic (extracted from createPromptHandler for MCP protocol)
128 |    */
129 |   private async executePromptLogic(promptData: ConvertedPrompt, args: any): Promise<any> {
130 |     try {
131 |       this.logger.info(`Executing prompt '${promptData.name}'...`);
132 | 
133 |       // Check if arguments are effectively empty
134 |       const effectivelyEmptyArgs = this.areArgumentsEffectivelyEmpty(
135 |         promptData.arguments,
136 |         args
137 |       );
138 | 
139 |       if (
140 |         effectivelyEmptyArgs &&
141 |         promptData.onEmptyInvocation === "return_template"
142 |       ) {
143 |         this.logger.info(
144 |           `Prompt '${promptData.name}' invoked without arguments and onEmptyInvocation is 'return_template'. Returning template info.`
145 |         );
146 | 
147 |         let responseText = `Prompt: '${promptData.name}'\n`;
148 |         responseText += `Description: ${promptData.description}\n`;
149 | 
150 |         if (promptData.arguments && promptData.arguments.length > 0) {
151 |           responseText += `This prompt requires the following arguments:\n`;
152 |           promptData.arguments.forEach((arg) => {
153 |             responseText += `  - ${arg.name}${
154 |               arg.required ? " (required)" : " (optional)"
155 |             }: ${arg.description || "No description"}\n`;
156 |           });
157 |           responseText += `\nExample usage: >>${
158 |             promptData.id || promptData.name
159 |           } ${promptData.arguments
160 |             .map((arg) => `${arg.name}=\"value\"`)
161 |             .join(" ")}`;
162 |         } else {
163 |           responseText += "This prompt does not require any arguments.\n";
164 |         }
165 | 
166 |         return {
167 |           messages: [
168 |             {
169 |               role: "assistant" as const,
170 |               content: { type: "text" as const, text: responseText },
171 |             },
172 |           ],
173 |         };
174 |       }
175 | 
176 |       // Check if this is a chain prompt
177 |       if (
178 |         isChainPrompt(promptData) &&
179 |         promptData.chainSteps &&
180 |         promptData.chainSteps.length > 0
181 |       ) {
182 |         this.logger.info(
183 |           `Prompt '${promptData.name}' is a chain with ${promptData.chainSteps.length} steps. NOT automatically executing the chain.`
184 |         );
185 |         // Note: Chain execution is handled elsewhere
186 |       }
187 | 
188 |       // Create messages array with only user and assistant roles
189 |       const messages: {
190 |         role: "user" | "assistant";
191 |         content: { type: "text"; text: string };
192 |       }[] = [];
193 | 
194 |       // Create user message with placeholders replaced
195 |       let userMessageText = promptData.userMessageTemplate;
196 | 
197 |       // If there's a system message, prepend it to the user message
198 |       if (promptData.systemMessage) {
199 |         userMessageText = `[System Info: ${promptData.systemMessage}]\n\n${userMessageText}`;
200 |       }
201 | 
202 |       // Process the template with special context
203 |       // Using direct processing since TemplateProcessor was consolidated
204 |       userMessageText = await this.processTemplateDirect(
205 |         userMessageText,
206 |         args,
207 |         { previous_message: this.getPreviousMessage() },
208 |         promptData.tools || false
209 |       );
210 | 
211 |       // Store in conversation history for future reference
212 |       this.addToConversationHistory({
213 |         role: "user",
214 |         content: userMessageText,
215 |         timestamp: Date.now(),
216 |         isProcessedTemplate: true, // Mark as a processed template
217 |       });
218 | 
219 |       // Push the user message to the messages array
220 |       messages.push({
221 |         role: "user",
222 |         content: {
223 |           type: "text",
224 |           text: userMessageText,
225 |         },
226 |       });
227 | 
228 |       this.logger.debug(
229 |         `Processed messages for prompt '${promptData.name}':`,
230 |         messages
231 |       );
232 |       return { messages };
233 |     } catch (error) {
234 |       this.logger.error(
235 |         `Error executing prompt '${promptData.name}':`,
236 |         error
237 |       );
238 |       throw error; // Re-throw to let the MCP framework handle it
239 |     }
240 |   }
241 | 
242 |   /**
243 |    * Register all prompts with the MCP server using proper MCP protocol
244 |    */
245 |   async registerAllPrompts(prompts: ConvertedPrompt[]): Promise<number> {
246 |     try {
247 |       this.logger.info(
248 |         `Registering ${prompts.length} prompts with MCP SDK registerPrompt API...`
249 |       );
250 | 
251 |       // Register individual prompts using the correct MCP SDK API
252 |       this.registerIndividualPrompts(prompts);
253 | 
254 |       this.logger.info(
255 |         `Successfully registered ${prompts.length} prompts with MCP SDK`
256 |       );
257 |       return prompts.length;
258 |     } catch (error) {
259 |       this.logger.error(`Error registering prompts:`, error);
260 |       throw error;
261 |     }
262 |   }
263 | 
264 | 
265 |   /**
266 |    * Send list_changed notification to clients (for hot-reload)
267 |    * This is the proper MCP way to notify clients about prompt updates
268 |    */
269 |   async notifyPromptsListChanged(): Promise<void> {
270 |     try {
271 |       // Send MCP notification that prompt list has changed
272 |       if (this.mcpServer && typeof this.mcpServer.notification === 'function') {
273 |         this.mcpServer.notification({
274 |           method: "notifications/prompts/list_changed"
275 |         });
276 |         this.logger.info("✅ Sent prompts/list_changed notification to clients");
277 |       } else {
278 |         this.logger.debug("MCP server doesn't support notifications");
279 |       }
280 |     } catch (error) {
281 |       this.logger.warn("Could not send prompts/list_changed notification:", error);
282 |     }
283 |   }
284 | 
285 |   // Note: MCP SDK doesn't provide prompt unregistration
286 |   // Hot-reload is handled through list_changed notifications to clients
287 | 
288 |   /**
289 |    * Helper function to determine if provided arguments are effectively empty
290 |    * for the given prompt definition.
291 |    */
292 |   private areArgumentsEffectivelyEmpty(
293 |     promptArgs: Array<{ name: string }>,
294 |     providedArgs: any
295 |   ): boolean {
296 |     if (
297 |       !providedArgs ||
298 |       typeof providedArgs !== "object" ||
299 |       Object.keys(providedArgs).length === 0
300 |     ) {
301 |       return true; // No arguments provided at all
302 |     }
303 |     // Check if any of the defined arguments for the prompt have a meaningful value
304 |     for (const definedArg of promptArgs) {
305 |       const value = providedArgs[definedArg.name];
306 |       if (
307 |         value !== undefined &&
308 |         value !== null &&
309 |         String(value).trim() !== ""
310 |       ) {
311 |         return false; // Found at least one provided argument with a value
312 |       }
313 |     }
314 |     return true; // All defined arguments are missing or have empty values
315 |   }
316 | 
317 | 
318 | 
319 |   /**
320 |    * Add item to conversation history with size management
321 |    */
322 |   addToConversationHistory(item: ConversationHistoryItem): void {
323 |     this.conversationHistory.push(item);
324 | 
325 |     // Trim history if it exceeds maximum size
326 |     if (this.conversationHistory.length > this.MAX_HISTORY_SIZE) {
327 |       // Remove oldest entries, keeping recent ones
328 |       this.conversationHistory.splice(
329 |         0,
330 |         this.conversationHistory.length - this.MAX_HISTORY_SIZE
331 |       );
332 |       this.logger.debug(
333 |         `Trimmed conversation history to ${this.MAX_HISTORY_SIZE} entries to prevent memory leaks`
334 |       );
335 |     }
336 |   }
337 | 
338 |   /**
339 |    * Get the previous message from conversation history
340 |    */
341 |   getPreviousMessage(): string {
342 |     // Try to find the last user message in conversation history
343 |     if (this.conversationHistory.length > 0) {
344 |       // Start from the end and find the first non-template user message
345 |       for (let i = this.conversationHistory.length - 1; i >= 0; i--) {
346 |         const historyItem = this.conversationHistory[i];
347 |         // Only consider user messages that aren't processed templates
348 |         if (historyItem.role === "user" && !historyItem.isProcessedTemplate) {
349 |           this.logger.debug(
350 |             `Found previous user message for context: ${historyItem.content.substring(
351 |               0,
352 |               50
353 |             )}...`
354 |           );
355 |           return historyItem.content;
356 |         }
357 |       }
358 |     }
359 | 
360 |     // Return a default prompt if no suitable history item is found
361 |     return "[Please check previous messages in the conversation for context]";
362 |   }
363 | 
364 |   /**
365 |    * Get conversation history
366 |    */
367 |   getConversationHistory(): ConversationHistoryItem[] {
368 |     return [...this.conversationHistory];
369 |   }
370 | 
371 |   /**
372 |    * Clear conversation history
373 |    */
374 |   clearConversationHistory(): void {
375 |     this.conversationHistory = [];
376 |     this.logger.info("Conversation history cleared");
377 |   }
378 | 
379 |   /**
380 |    * Get conversation history statistics
381 |    */
382 |   getConversationStats(): {
383 |     totalMessages: number;
384 |     userMessages: number;
385 |     assistantMessages: number;
386 |     processedTemplates: number;
387 |     oldestMessage?: number;
388 |     newestMessage?: number;
389 |   } {
390 |     const userMessages = this.conversationHistory.filter(
391 |       (item) => item.role === "user"
392 |     ).length;
393 |     const assistantMessages = this.conversationHistory.filter(
394 |       (item) => item.role === "assistant"
395 |     ).length;
396 |     const processedTemplates = this.conversationHistory.filter(
397 |       (item) => item.isProcessedTemplate
398 |     ).length;
399 | 
400 |     const timestamps = this.conversationHistory.map((item) => item.timestamp);
401 |     const oldestMessage =
402 |       timestamps.length > 0 ? Math.min(...timestamps) : undefined;
403 |     const newestMessage =
404 |       timestamps.length > 0 ? Math.max(...timestamps) : undefined;
405 | 
406 |     return {
407 |       totalMessages: this.conversationHistory.length,
408 |       userMessages,
409 |       assistantMessages,
410 |       processedTemplates,
411 |       oldestMessage,
412 |       newestMessage,
413 |     };
414 |   }
415 | 
416 |   /**
417 |    * Execute a prompt directly (for testing or internal use)
418 |    */
419 |   async executePromptDirectly(
420 |     promptId: string,
421 |     args: Record<string, string>,
422 |     prompts: ConvertedPrompt[]
423 |   ): Promise<string> {
424 |     try {
425 |       const convertedPrompt = prompts.find((cp) => cp.id === promptId);
426 |       if (!convertedPrompt) {
427 |         throw new Error(`Could not find prompt with ID: ${promptId}`);
428 |       }
429 | 
430 |       this.logger.debug(
431 |         `Running prompt directly: ${promptId} with arguments:`,
432 |         args
433 |       );
434 | 
435 |       // Check for missing arguments but treat all as optional
436 |       const missingArgs = convertedPrompt.arguments
437 |         .filter((arg) => !args[arg.name])
438 |         .map((arg) => arg.name);
439 | 
440 |       if (missingArgs.length > 0) {
441 |         this.logger.info(
442 |           `Missing arguments for '${promptId}': ${missingArgs.join(
443 |             ", "
444 |           )}. Will attempt to use conversation context.`
445 |         );
446 | 
447 |         // Use previous_message for all missing arguments
448 |         missingArgs.forEach((argName) => {
449 |           args[argName] = `{{previous_message}}`;
450 |         });
451 |       }
452 | 
453 |       // Process template with context
454 |       // Using direct processing since TemplateProcessor was consolidated
455 |       const userMessageText = await this.processTemplateDirect(
456 |         convertedPrompt.userMessageTemplate,
457 |         args,
458 |         { previous_message: this.getPreviousMessage() },
459 |         convertedPrompt.tools || false
460 |       );
461 | 
462 |       // Add the message to conversation history
463 |       this.addToConversationHistory({
464 |         role: "user",
465 |         content: userMessageText,
466 |         timestamp: Date.now(),
467 |         isProcessedTemplate: true,
468 |       });
469 | 
470 |       // Generate a response (echo in this MCP implementation)
471 |       const response = `Processed prompt: ${promptId}\nWith message: ${userMessageText}`;
472 | 
473 |       // Store the response in conversation history
474 |       this.addToConversationHistory({
475 |         role: "assistant",
476 |         content: response,
477 |         timestamp: Date.now(),
478 |       });
479 | 
480 |       return response;
481 |     } catch (error) {
482 |       this.logger.error(`Error executing prompt '${promptId}':`, error);
483 |       throw error;
484 |     }
485 |   }
486 | 
487 |   /**
488 |    * Get registration statistics
489 |    */
490 |   getRegistrationStats(prompts: ConvertedPrompt[]): {
491 |     totalPrompts: number;
492 |     chainPrompts: number;
493 |     regularPrompts: number;
494 |     toolEnabledPrompts: number;
495 |     categoriesCount: number;
496 |     averageArgumentsPerPrompt: number;
497 |   } {
498 |     const chainPrompts = prompts.filter((p) => isChainPrompt(p)).length;
499 |     const toolEnabledPrompts = prompts.filter((p) => p.tools).length;
500 |     const categoriesSet = new Set(prompts.map((p) => p.category));
501 |     const totalArguments = prompts.reduce(
502 |       (sum, p) => sum + p.arguments.length,
503 |       0
504 |     );
505 | 
506 |     return {
507 |       totalPrompts: prompts.length,
508 |       chainPrompts,
509 |       regularPrompts: prompts.length - chainPrompts,
510 |       toolEnabledPrompts,
511 |       categoriesCount: categoriesSet.size,
512 |       averageArgumentsPerPrompt:
513 |         prompts.length > 0 ? totalArguments / prompts.length : 0,
514 |     };
515 |   }
516 | }
517 | 
```

--------------------------------------------------------------------------------
/server/src/mcp-tools/prompt-engine/utils/category-extractor.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Category Extraction Utility
  3 |  *
  4 |  * Implements intelligent category detection from multiple sources:
  5 |  * 1. Prompt metadata (PromptData.category)
  6 |  * 2. File path structure (/prompts/analysis/ -> analysis)
  7 |  * 3. Pattern-based detection (fallback)
  8 |  *
  9 |  * Part of Gate System Intelligent Selection Upgrade - Phase 1
 10 |  */
 11 | 
 12 | import type { Logger } from '../../../logging/index.js';
 13 | import path from 'path';
 14 | 
 15 | /**
 16 |  * Template gate configuration
 17 |  */
 18 | export interface GateConfigurationInfo {
 19 |   include?: string[];
 20 |   exclude?: string[];
 21 |   framework_gates?: boolean;
 22 | }
 23 | 
 24 | /**
 25 |  * Extracted category and gate information with source tracking
 26 |  */
 27 | export interface CategoryExtractionResult {
 28 |   /** The determined category */
 29 |   category: string;
 30 |   /** Source of the category determination */
 31 |   source: 'metadata' | 'path' | 'pattern' | 'fallback';
 32 |   /** Confidence level (0-100) */
 33 |   confidence: number;
 34 |   /** Template-level gate configuration */
 35 |   gateConfiguration?: GateConfigurationInfo;
 36 |   /** Original data used for extraction */
 37 |   sourceData?: {
 38 |     metadata?: string;
 39 |     filePath?: string;
 40 |     promptId?: string;
 41 |   };
 42 | }
 43 | 
 44 | /**
 45 |  * Category extractor with intelligent detection
 46 |  */
 47 | export class CategoryExtractor {
 48 |   private logger: Logger;
 49 | 
 50 |   constructor(logger: Logger) {
 51 |     this.logger = logger;
 52 |   }
 53 | 
 54 |   /**
 55 |    * Extract category from prompt using multiple detection strategies
 56 |    *
 57 |    * Priority order:
 58 |    * 1. Prompt metadata category (highest confidence)
 59 |    * 2. File path structure parsing
 60 |    * 3. Prompt ID pattern matching
 61 |    * 4. Default fallback
 62 |    */
 63 |   extractCategory(prompt: any): CategoryExtractionResult {
 64 |     this.logger.debug('[CATEGORY EXTRACTOR] Extracting category from prompt:', {
 65 |       promptId: prompt?.id,
 66 |       promptCategory: prompt?.category,
 67 |       promptFile: prompt?.file,
 68 |       hasGateConfiguration: !!prompt?.gateConfiguration
 69 |     });
 70 | 
 71 |     // Strategy 1: Use prompt metadata category (highest priority)
 72 |     if (prompt?.category && typeof prompt.category === 'string') {
 73 |       const metadataCategory = prompt.category.toLowerCase().trim();
 74 |       if (this.isValidCategory(metadataCategory)) {
 75 |         return {
 76 |           category: metadataCategory,
 77 |           source: 'metadata',
 78 |           confidence: 95,
 79 |           gateConfiguration: prompt.gateConfiguration,
 80 |           sourceData: {
 81 |             metadata: prompt.category,
 82 |             filePath: prompt.file,
 83 |             promptId: prompt.id
 84 |           }
 85 |         };
 86 |       }
 87 |     }
 88 | 
 89 |     // Strategy 2: Extract from file path structure
 90 |     if (prompt?.file && typeof prompt.file === 'string') {
 91 |       const pathCategory = this.extractCategoryFromPath(prompt.file);
 92 |       if (pathCategory) {
 93 |         return {
 94 |           category: pathCategory,
 95 |           source: 'path',
 96 |           confidence: 85,
 97 |           gateConfiguration: prompt.gateConfiguration,
 98 |           sourceData: {
 99 |             filePath: prompt.file,
100 |             promptId: prompt.id
101 |           }
102 |         };
103 |       }
104 |     }
105 | 
106 |     // Strategy 3: Pattern-based detection from prompt ID
107 |     if (prompt?.id && typeof prompt.id === 'string') {
108 |       const patternCategory = this.extractCategoryFromPattern(prompt.id);
109 |       if (patternCategory) {
110 |         return {
111 |           category: patternCategory,
112 |           source: 'pattern',
113 |           confidence: 60,
114 |           gateConfiguration: prompt.gateConfiguration,
115 |           sourceData: {
116 |             promptId: prompt.id,
117 |             filePath: prompt.file
118 |           }
119 |         };
120 |       }
121 |     }
122 | 
123 |     // Strategy 4: Default fallback
124 |     this.logger.debug('[CATEGORY EXTRACTOR] No category detected, using fallback');
125 |     return {
126 |       category: 'general',
127 |       source: 'fallback',
128 |       confidence: 30,
129 |       gateConfiguration: prompt?.gateConfiguration,
130 |       sourceData: {
131 |         promptId: prompt?.id,
132 |         filePath: prompt?.file
133 |       }
134 |     };
135 |   }
136 | 
137 |   /**
138 |    * Extract category from file path structure
139 |    * Examples:
140 |    * - "/prompts/analysis/notes.md" -> "analysis"
141 |    * - "/prompts/education/learning.md" -> "education"
142 |    * - "analysis/query_refinement.md" -> "analysis"
143 |    */
144 |   private extractCategoryFromPath(filePath: string): string | null {
145 |     try {
146 |       // Normalize path separators
147 |       const normalizedPath = filePath.replace(/\\/g, '/');
148 | 
149 |       // Split path and look for category indicators
150 |       const pathSegments = normalizedPath.split('/').filter(segment => segment.length > 0);
151 | 
152 |       // Look for prompts directory structure: /prompts/{category}/
153 |       const promptsIndex = pathSegments.findIndex(segment => segment === 'prompts');
154 |       if (promptsIndex !== -1 && promptsIndex + 1 < pathSegments.length) {
155 |         const categoryCandidate = pathSegments[promptsIndex + 1];
156 |         if (this.isValidCategory(categoryCandidate)) {
157 |           return categoryCandidate;
158 |         }
159 |       }
160 | 
161 |       // Look for direct category directory structure: {category}/
162 |       for (const segment of pathSegments) {
163 |         if (this.isValidCategory(segment)) {
164 |           return segment;
165 |         }
166 |       }
167 | 
168 |       return null;
169 |     } catch (error) {
170 |       this.logger.warn('[CATEGORY EXTRACTOR] Error extracting category from path:', error);
171 |       return null;
172 |     }
173 |   }
174 | 
175 |   /**
176 |    * Extract category from prompt ID patterns
177 |    * Examples:
178 |    * - "analysis_notes" -> "analysis"
179 |    * - "education_learning" -> "education"
180 |    * - "debug_application" -> "debugging"
181 |    */
182 |   private extractCategoryFromPattern(promptId: string): string | null {
183 |     const patterns = [
184 |       { pattern: /^analysis_|_analysis$|analysis/i, category: 'analysis' },
185 |       { pattern: /^education_|_education$|learning|teach/i, category: 'education' },
186 |       { pattern: /^develop_|_develop$|code|programming/i, category: 'development' },
187 |       { pattern: /^research_|_research$|investigate/i, category: 'research' },
188 |       { pattern: /^debug_|_debug$|troubleshoot/i, category: 'debugging' },
189 |       { pattern: /^doc_|_doc$|documentation|readme/i, category: 'documentation' },
190 |       { pattern: /^content_|_content$|process|format/i, category: 'content_processing' }
191 |     ];
192 | 
193 |     for (const { pattern, category } of patterns) {
194 |       if (pattern.test(promptId)) {
195 |         return category;
196 |       }
197 |     }
198 | 
199 |     return null;
200 |   }
201 | 
202 |   /**
203 |    * Validate if a category is recognized
204 |    */
205 |   private isValidCategory(category: string): boolean {
206 |     const validCategories = [
207 |       'analysis',
208 |       'education',
209 |       'development',
210 |       'research',
211 |       'debugging',
212 |       'documentation',
213 |       'content_processing',
214 |       'general'
215 |     ];
216 | 
217 |     return validCategories.includes(category.toLowerCase());
218 |   }
219 | 
220 |   /**
221 |    * Intelligent gate selection with precedence logic
222 |    *
223 |    * Priority order:
224 |    * 1. Explicit template gates (highest priority)
225 |    * 2. Category-based gates
226 |    * 3. Framework-based gates
227 |    * 4. Default fallback gates (lowest priority)
228 |    */
229 |   selectGatesWithPrecedence(
230 |     categoryResult: CategoryExtractionResult,
231 |     frameworkGates: string[] = [],
232 |     fallbackGates: string[] = ['content-structure']
233 |   ): {
234 |     selectedGates: string[];
235 |     precedenceUsed: string[];
236 |     reasoning: string;
237 |   } {
238 |     const { category, gateConfiguration } = categoryResult;
239 |     const categoryGates = CategoryExtractor.getCategoryGateMapping()[category] || [];
240 | 
241 |     this.logger.debug('[GATE PRECEDENCE] Input for gate selection:', {
242 |       category,
243 |       templateGates: gateConfiguration,
244 |       categoryGates,
245 |       frameworkGates,
246 |       fallbackGates
247 |     });
248 | 
249 |     let selectedGates: string[] = [];
250 |     let precedenceUsed: string[] = [];
251 |     let reasoning = '';
252 | 
253 |     // Phase 1: Start with template gates if specified
254 |     if (gateConfiguration) {
255 |       if (gateConfiguration.include && gateConfiguration.include.length > 0) {
256 |         selectedGates.push(...gateConfiguration.include);
257 |         precedenceUsed.push('template-include');
258 |         reasoning += `Template includes: [${gateConfiguration.include.join(', ')}]. `;
259 |       }
260 | 
261 |       // Phase 2: Add category gates if framework_gates is true (default)
262 |       if (gateConfiguration.framework_gates !== false) {
263 |         const additionalCategoryGates = categoryGates.filter(gate => !selectedGates.includes(gate));
264 |         selectedGates.push(...additionalCategoryGates);
265 |         if (additionalCategoryGates.length > 0) {
266 |           precedenceUsed.push('category-gates');
267 |           reasoning += `Category gates: [${additionalCategoryGates.join(', ')}]. `;
268 |         }
269 | 
270 |         // Phase 3: Add framework gates
271 |         const additionalFrameworkGates = frameworkGates.filter(gate => !selectedGates.includes(gate));
272 |         selectedGates.push(...additionalFrameworkGates);
273 |         if (additionalFrameworkGates.length > 0) {
274 |           precedenceUsed.push('framework-gates');
275 |           reasoning += `Framework gates: [${additionalFrameworkGates.join(', ')}]. `;
276 |         }
277 |       }
278 | 
279 |       // Phase 4: Apply exclusions
280 |       if (gateConfiguration.exclude && gateConfiguration.exclude.length > 0) {
281 |         const originalCount = selectedGates.length;
282 |         selectedGates = selectedGates.filter(gate => !gateConfiguration.exclude!.includes(gate));
283 |         if (selectedGates.length < originalCount) {
284 |           precedenceUsed.push('template-exclude');
285 |           reasoning += `Template excludes: [${gateConfiguration.exclude.join(', ')}]. `;
286 |         }
287 |       }
288 |     } else {
289 |       // No template configuration - use standard precedence
290 | 
291 |       // Phase 2: Category gates
292 |       selectedGates.push(...categoryGates);
293 |       if (categoryGates.length > 0) {
294 |         precedenceUsed.push('category-gates');
295 |         reasoning += `Category gates: [${categoryGates.join(', ')}]. `;
296 |       }
297 | 
298 |       // Phase 3: Framework gates
299 |       const additionalFrameworkGates = frameworkGates.filter(gate => !selectedGates.includes(gate));
300 |       selectedGates.push(...additionalFrameworkGates);
301 |       if (additionalFrameworkGates.length > 0) {
302 |         precedenceUsed.push('framework-gates');
303 |         reasoning += `Framework gates: [${additionalFrameworkGates.join(', ')}]. `;
304 |       }
305 |     }
306 | 
307 |     // Phase 5: Fallback if no gates selected
308 |     if (selectedGates.length === 0) {
309 |       selectedGates.push(...fallbackGates);
310 |       precedenceUsed.push('fallback');
311 |       reasoning += `Fallback gates: [${fallbackGates.join(', ')}]. `;
312 |     }
313 | 
314 |     // Remove duplicates (shouldn't happen with our logic, but safety check)
315 |     selectedGates = [...new Set(selectedGates)];
316 | 
317 |     this.logger.info('[GATE PRECEDENCE] Final gate selection:', {
318 |       category,
319 |       selectedGates,
320 |       precedenceUsed,
321 |       reasoning: reasoning.trim()
322 |     });
323 | 
324 |     return {
325 |       selectedGates,
326 |       precedenceUsed,
327 |       reasoning: reasoning.trim()
328 |     };
329 |   }
330 | 
331 |   /**
332 |    * Get fallback category mapping for gate selection
333 |    */
334 |   public static getCategoryGateMapping(): Record<string, string[]> {
335 |     return {
336 |       'analysis': ['research-quality', 'technical-accuracy'],
337 |       'education': ['educational-clarity', 'content-structure'],
338 |       'development': ['code-quality', 'security-awareness'],
339 |       'research': ['research-quality', 'fact-checking'],
340 |       'debugging': ['technical-accuracy', 'problem-solving'],
341 |       'documentation': ['content-structure', 'clarity'],
342 |       'content_processing': ['content-structure', 'format-consistency'],
343 |       'general': ['content-structure']
344 |     };
345 |   }
346 | 
347 |   /**
348 |    * Enhanced gate selection with 5-level precedence including temporary gates
349 |    *
350 |    * Priority order (Phase 3):
351 |    * 1. Temporary gates (highest priority - execution-specific)
352 |    * 2. Explicit template gates
353 |    * 3. Category-based gates
354 |    * 4. Framework-based gates
355 |    * 5. Default fallback gates (lowest priority)
356 |    */
357 |   selectGatesWithEnhancedPrecedence(
358 |     categoryResult: CategoryExtractionResult,
359 |     frameworkGates: string[] = [],
360 |     fallbackGates: string[] = ['content-structure'],
361 |     temporaryGates: string[] = [],
362 |     enhancedConfig?: any
363 |   ): {
364 |     selectedGates: string[];
365 |     precedenceUsed: string[];
366 |     reasoning: string;
367 |     temporaryGatesApplied: string[];
368 |   } {
369 |     const { category, gateConfiguration } = categoryResult;
370 |     const categoryGates = CategoryExtractor.getCategoryGateMapping()[category] || [];
371 | 
372 |     this.logger.debug('[ENHANCED GATE PRECEDENCE] Input for enhanced gate selection:', {
373 |       category,
374 |       templateGates: gateConfiguration,
375 |       categoryGates,
376 |       frameworkGates,
377 |       fallbackGates,
378 |       temporaryGates,
379 |       enhancedConfig
380 |     });
381 | 
382 |     let selectedGates: string[] = [];
383 |     let precedenceUsed: string[] = [];
384 |     let reasoning = '';
385 |     let temporaryGatesApplied: string[] = [];
386 | 
387 |     // Phase 1: Start with temporary gates (highest priority)
388 |     if (temporaryGates.length > 0) {
389 |       selectedGates.push(...temporaryGates);
390 |       precedenceUsed.push('temporary-gates');
391 |       temporaryGatesApplied = [...temporaryGates];
392 |       reasoning += `Temporary gates: [${temporaryGates.join(', ')}]. `;
393 |     }
394 | 
395 |     // Phase 2: Add template gates if specified
396 |     if (gateConfiguration) {
397 |       if (gateConfiguration.include && gateConfiguration.include.length > 0) {
398 |         const additionalTemplateGates = gateConfiguration.include.filter(gate => !selectedGates.includes(gate));
399 |         selectedGates.push(...additionalTemplateGates);
400 |         if (additionalTemplateGates.length > 0) {
401 |           precedenceUsed.push('template-include');
402 |           reasoning += `Template includes: [${additionalTemplateGates.join(', ')}]. `;
403 |         }
404 |       }
405 | 
406 |       // Phase 3: Add category gates if framework_gates is true (default)
407 |       if (gateConfiguration.framework_gates !== false) {
408 |         const additionalCategoryGates = categoryGates.filter(gate => !selectedGates.includes(gate));
409 |         selectedGates.push(...additionalCategoryGates);
410 |         if (additionalCategoryGates.length > 0) {
411 |           precedenceUsed.push('category-gates');
412 |           reasoning += `Category gates: [${additionalCategoryGates.join(', ')}]. `;
413 |         }
414 | 
415 |         // Phase 4: Add framework gates
416 |         const additionalFrameworkGates = frameworkGates.filter(gate => !selectedGates.includes(gate));
417 |         selectedGates.push(...additionalFrameworkGates);
418 |         if (additionalFrameworkGates.length > 0) {
419 |           precedenceUsed.push('framework-gates');
420 |           reasoning += `Framework gates: [${additionalFrameworkGates.join(', ')}]. `;
421 |         }
422 |       }
423 | 
424 |       // Phase 5: Apply exclusions (can remove temporary, template, category, or framework gates)
425 |       if (gateConfiguration.exclude && gateConfiguration.exclude.length > 0) {
426 |         const originalCount = selectedGates.length;
427 |         selectedGates = selectedGates.filter(gate => !gateConfiguration.exclude!.includes(gate));
428 | 
429 |         // Update temporary gates applied if they were excluded
430 |         temporaryGatesApplied = temporaryGatesApplied.filter(gate => !gateConfiguration.exclude!.includes(gate));
431 | 
432 |         if (selectedGates.length < originalCount) {
433 |           precedenceUsed.push('template-exclude');
434 |           reasoning += `Template excludes: [${gateConfiguration.exclude.join(', ')}]. `;
435 |         }
436 |       }
437 |     } else {
438 |       // No template configuration - use standard precedence (skip template level)
439 | 
440 |       // Phase 3: Category gates
441 |       const additionalCategoryGates = categoryGates.filter(gate => !selectedGates.includes(gate));
442 |       selectedGates.push(...additionalCategoryGates);
443 |       if (additionalCategoryGates.length > 0) {
444 |         precedenceUsed.push('category-gates');
445 |         reasoning += `Category gates: [${additionalCategoryGates.join(', ')}]. `;
446 |       }
447 | 
448 |       // Phase 4: Framework gates
449 |       const additionalFrameworkGates = frameworkGates.filter(gate => !selectedGates.includes(gate));
450 |       selectedGates.push(...additionalFrameworkGates);
451 |       if (additionalFrameworkGates.length > 0) {
452 |         precedenceUsed.push('framework-gates');
453 |         reasoning += `Framework gates: [${additionalFrameworkGates.join(', ')}]. `;
454 |       }
455 |     }
456 | 
457 |     // Phase 6: Fallback if no gates selected
458 |     if (selectedGates.length === 0) {
459 |       selectedGates.push(...fallbackGates);
460 |       precedenceUsed.push('fallback');
461 |       reasoning += `Fallback gates: [${fallbackGates.join(', ')}]. `;
462 |     }
463 | 
464 |     // Remove duplicates (shouldn't happen with our logic, but safety check)
465 |     selectedGates = [...new Set(selectedGates)];
466 |     temporaryGatesApplied = [...new Set(temporaryGatesApplied)];
467 | 
468 |     this.logger.info('[ENHANCED GATE PRECEDENCE] Final enhanced gate selection:', {
469 |       category,
470 |       selectedGates,
471 |       precedenceUsed,
472 |       temporaryGatesApplied,
473 |       reasoning: reasoning.trim()
474 |     });
475 | 
476 |     return {
477 |       selectedGates,
478 |       precedenceUsed,
479 |       reasoning: reasoning.trim(),
480 |       temporaryGatesApplied
481 |     };
482 |   }
483 | }
484 | 
485 | /**
486 |  * Convenience function for quick category extraction
487 |  */
488 | export function extractPromptCategory(prompt: any, logger: Logger): CategoryExtractionResult {
489 |   const extractor = new CategoryExtractor(logger);
490 |   return extractor.extractCategory(prompt);
491 | }
```

--------------------------------------------------------------------------------
/server/src/prompts/promptUtils.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import fs from "fs/promises";
  2 | import path from "path";
  3 | import { PromptData, PromptsConfigFile } from "../types.js";
  4 | 
  5 | // Create a simple logger since we can't import from index.ts
  6 | const log = {
  7 |   info: (message: string, ...args: any[]) => {
  8 |     console.log(`[INFO] ${message}`, ...args);
  9 |   },
 10 |   error: (message: string, ...args: any[]) => {
 11 |     console.error(`[ERROR] ${message}`, ...args);
 12 |   },
 13 |   warn: (message: string, ...args: any[]) => {
 14 |     console.warn(`[WARN] ${message}`, ...args);
 15 |   },
 16 | };
 17 | 
 18 | /**
 19 |  * Resolves a prompt file path consistently across the application
 20 |  * @param promptFile The file path from the prompt data
 21 |  * @param configFilePath The path to the config file (used as reference for absolute paths)
 22 |  * @param categoryFolder The path to the category folder (used for relative paths)
 23 |  * @returns The fully resolved path to the prompt file
 24 |  */
 25 | export function resolvePromptFilePath(
 26 |   promptFile: string,
 27 |   configFilePath: string,
 28 |   categoryFolder: string
 29 | ): string {
 30 |   if (promptFile.startsWith("/")) {
 31 |     // Absolute path (relative to config file location)
 32 |     return path.resolve(path.dirname(configFilePath), promptFile.slice(1));
 33 |   } else if (promptFile.includes("/")) {
 34 |     // Path already includes category or sub-path
 35 |     return path.resolve(path.dirname(configFilePath), promptFile);
 36 |   } else {
 37 |     // Simple filename, relative to category folder
 38 |     return path.resolve(categoryFolder, promptFile);
 39 |   }
 40 | }
 41 | 
 42 | /**
 43 |  * Reads a prompt file and returns its content
 44 |  * @param promptFilePath Path to the prompt file
 45 |  * @returns The content of the prompt file
 46 |  */
 47 | export async function readPromptFile(promptFilePath: string): Promise<string> {
 48 |   try {
 49 |     return await fs.readFile(promptFilePath, "utf8");
 50 |   } catch (error) {
 51 |     log.error(`Error reading prompt file ${promptFilePath}:`, error);
 52 |     throw new Error(
 53 |       `Failed to read prompt file: ${
 54 |         error instanceof Error ? error.message : String(error)
 55 |       }`
 56 |     );
 57 |   }
 58 | }
 59 | 
 60 | /**
 61 |  * Parses a prompt file content into sections
 62 |  * @param content The content of the prompt file
 63 |  * @returns An object containing the different sections of the prompt
 64 |  */
 65 | export function parsePromptSections(content: string): Record<string, string> {
 66 |   const sections: Record<string, string> = {};
 67 | 
 68 |   // Extract the title and description (everything before the first ## heading)
 69 |   const titleMatch = content.match(/^# (.+?)(?=\n\n|\n##)/s);
 70 |   if (titleMatch) {
 71 |     sections.title = titleMatch[1].trim();
 72 | 
 73 |     // Extract description (content between title and first ## heading)
 74 |     const descMatch = content.match(/^# .+?\n\n([\s\S]+?)(?=\n## )/s);
 75 |     if (descMatch) {
 76 |       sections.description = descMatch[1].trim();
 77 |     } else {
 78 |       sections.description = "";
 79 |     }
 80 |   }
 81 | 
 82 |   // Extract other sections (## headings)
 83 |   const sectionMatches = content.matchAll(
 84 |     /## ([^\n]+)\n\n([\s\S]+?)(?=\n## |\n# |\n$)/g
 85 |   );
 86 |   for (const match of sectionMatches) {
 87 |     const sectionName = match[1].trim();
 88 |     const sectionContent = match[2].trim();
 89 |     sections[sectionName] = sectionContent;
 90 |   }
 91 | 
 92 |   return sections;
 93 | }
 94 | 
 95 | /**
 96 |  * Modifies a specific section of a prompt markdown file
 97 |  * @param promptId Unique identifier of the prompt to modify
 98 |  * @param sectionName Name of the section to modify (e.g., "title", "description", "System Message", "User Message Template")
 99 |  * @param newContent New content for the specified section
100 |  * @param configPath Path to the promptsConfig.json file
101 |  * @returns Object containing the result of the operation
102 |  */
103 | export async function modifyPromptSection(
104 |   promptId: string,
105 |   sectionName: string,
106 |   newContent: string,
107 |   configPath: string
108 | ): Promise<{
109 |   success: boolean;
110 |   message: string;
111 |   promptData?: PromptData;
112 |   filePath?: string;
113 | }> {
114 |   try {
115 |     const messages: string[] = [];
116 |     // Read the promptsConfig.json file
117 |     const configFilePath = path.resolve(configPath);
118 |     const configContent = await fs.readFile(configFilePath, "utf8");
119 |     const promptsConfig = JSON.parse(configContent) as PromptsConfigFile;
120 | 
121 |     // Find the prompt in all category files
122 |     let prompt: PromptData | null = null;
123 |     let categoryFilePath: string = "";
124 |     let promptIndex: number = -1;
125 |     let promptsFile: any = null;
126 | 
127 |     // Search through each import path
128 |     for (const importPath of promptsConfig.imports) {
129 |       try {
130 |         // Construct the full path to the import file
131 |         const fullImportPath = path.resolve(
132 |           path.dirname(configFilePath),
133 |           importPath
134 |         );
135 | 
136 |         // Check if the file exists
137 |         try {
138 |           await fs.access(fullImportPath);
139 |         } catch (error) {
140 |           log.warn(`Import file not found: ${importPath}. Skipping.`);
141 |           continue;
142 |         }
143 | 
144 |         // Read the file
145 |         const fileContent = await fs.readFile(fullImportPath, "utf8");
146 |         const categoryPromptsFile = JSON.parse(fileContent);
147 | 
148 |         if (
149 |           categoryPromptsFile.prompts &&
150 |           Array.isArray(categoryPromptsFile.prompts)
151 |         ) {
152 |           // Find the prompt in this category file
153 |           const foundIndex = categoryPromptsFile.prompts.findIndex(
154 |             (p: PromptData) => p.id === promptId
155 |           );
156 | 
157 |           if (foundIndex !== -1) {
158 |             prompt = categoryPromptsFile.prompts[foundIndex];
159 |             categoryFilePath = fullImportPath;
160 |             promptIndex = foundIndex;
161 |             promptsFile = categoryPromptsFile;
162 |             messages.push(
163 |               `✅ Found prompt '${promptId}' in category file: ${path.basename(
164 |                 categoryFilePath
165 |               )}`
166 |             );
167 |             break;
168 |           }
169 |         }
170 |       } catch (error) {
171 |         log.error(`Error processing import file ${importPath}:`, error);
172 |       }
173 |     }
174 | 
175 |     // If prompt not found, throw an error
176 |     if (!prompt) {
177 |       return {
178 |         success: false,
179 |         message: `Prompt with ID '${promptId}' not found in any category file`,
180 |       };
181 |     }
182 | 
183 |     // Determine the category folder path
184 |     const categoryFolder = path.dirname(categoryFilePath);
185 | 
186 |     // Get the full path to the prompt file using the new utility function
187 |     const promptFilePath = resolvePromptFilePath(
188 |       prompt.file,
189 |       configFilePath,
190 |       categoryFolder
191 |     );
192 | 
193 |     // Read the prompt file
194 |     const promptContent = await readPromptFile(promptFilePath);
195 | 
196 |     // Parse the prompt sections
197 |     const sections = parsePromptSections(promptContent);
198 | 
199 |     // Check if the section exists
200 |     if (!(sectionName in sections) && sectionName !== "description") {
201 |       return {
202 |         success: false,
203 |         message: `Section '${sectionName}' not found in prompt '${promptId}'`,
204 |       };
205 |     }
206 | 
207 |     // Store the original prompt data for potential rollback
208 |     const originalPrompt = { ...prompt };
209 |     const originalContent = promptContent;
210 | 
211 |     // Modify the section
212 |     if (sectionName === "title") {
213 |       sections.title = newContent;
214 |     } else if (sectionName === "description") {
215 |       sections.description = newContent;
216 |     } else {
217 |       sections[sectionName] = newContent;
218 |     }
219 | 
220 |     // Reconstruct the prompt content
221 |     let newPromptContent = `# ${sections.title}\n\n${sections.description}\n\n`;
222 | 
223 |     // Add other sections
224 |     for (const [name, content] of Object.entries(sections)) {
225 |       if (name !== "title" && name !== "description") {
226 |         newPromptContent += `## ${name}\n\n${content}\n\n`;
227 |       }
228 |     }
229 | 
230 |     // Create the updated prompt
231 |     const updatedPrompt: PromptData = {
232 |       ...originalPrompt,
233 |       name: sectionName === "title" ? newContent : originalPrompt.name,
234 |     };
235 | 
236 |     // Create a copy of the prompts file with the prompt removed
237 |     const updatedPromptsFile = {
238 |       ...promptsFile,
239 |       prompts: [...promptsFile.prompts],
240 |     };
241 |     updatedPromptsFile.prompts.splice(promptIndex, 1);
242 | 
243 |     // Add the updated prompt to the new prompts array
244 |     updatedPromptsFile.prompts.push(updatedPrompt);
245 | 
246 |     // Define the operations and rollbacks for the transaction
247 |     const operations = [
248 |       // 1. Write the updated prompt content to the file
249 |       async () => await safeWriteFile(promptFilePath, newPromptContent),
250 | 
251 |       // 2. Write the updated category file with the prompt removed and added back
252 |       async () =>
253 |         await safeWriteFile(
254 |           categoryFilePath,
255 |           JSON.stringify(updatedPromptsFile, null, 2)
256 |         ),
257 |     ];
258 | 
259 |     const rollbacks = [
260 |       // 1. Restore the original prompt content
261 |       async () => await fs.writeFile(promptFilePath, originalContent, "utf8"),
262 | 
263 |       // 2. Restore the original category file
264 |       async () =>
265 |         await fs.writeFile(
266 |           categoryFilePath,
267 |           JSON.stringify(promptsFile, null, 2),
268 |           "utf8"
269 |         ),
270 |     ];
271 | 
272 |     // Perform the operations as a transaction
273 |     await performTransactionalFileOperations(operations, rollbacks);
274 | 
275 |     messages.push(
276 |       `✅ Updated section '${sectionName}' in markdown file: ${prompt.file}`
277 |     );
278 |     if (sectionName === "title") {
279 |       messages.push(
280 |         `✅ Updated prompt name in category file to '${newContent}'`
281 |       );
282 |     }
283 | 
284 |     return {
285 |       success: true,
286 |       message: messages.join("\n"),
287 |       promptData: updatedPrompt,
288 |       filePath: promptFilePath,
289 |     };
290 |   } catch (error) {
291 |     log.error(`Error in modifyPromptSection:`, error);
292 |     return {
293 |       success: false,
294 |       message: `Failed to modify prompt section: ${
295 |         error instanceof Error ? error.message : String(error)
296 |       }`,
297 |     };
298 |   }
299 | }
300 | 
301 | /**
302 |  * Helper function to perform a series of file operations as a transaction
303 |  * Automatically rolls back all changes if any operation fails
304 |  * @param operations Array of async functions that perform file operations
305 |  * @param rollbacks Array of async functions that undo the operations
306 |  * @returns Result of the last operation if successful
307 |  */
308 | export async function performTransactionalFileOperations<T>(
309 |   operations: Array<() => Promise<any>>,
310 |   rollbacks: Array<() => Promise<any>>
311 | ): Promise<T> {
312 |   // Validate inputs
313 |   if (!operations || !Array.isArray(operations) || operations.length === 0) {
314 |     throw new Error("No operations provided for transaction");
315 |   }
316 | 
317 |   if (!rollbacks || !Array.isArray(rollbacks)) {
318 |     log.warn(
319 |       "No rollbacks provided for transaction - operations cannot be rolled back if they fail"
320 |     );
321 |     rollbacks = [];
322 |   }
323 | 
324 |   // Ensure rollbacks array matches operations array length
325 |   if (rollbacks.length < operations.length) {
326 |     log.warn(
327 |       `Rollbacks array (${rollbacks.length}) is shorter than operations array (${operations.length}) - some operations cannot be rolled back`
328 |     );
329 |     // Fill with dummy rollbacks
330 |     for (let i = rollbacks.length; i < operations.length; i++) {
331 |       rollbacks.push(async () => {
332 |         log.warn(`No rollback defined for operation ${i}`);
333 |       });
334 |     }
335 |   }
336 | 
337 |   let lastSuccessfulIndex = -1;
338 |   let result: any;
339 | 
340 |   try {
341 |     // Perform operations
342 |     for (let i = 0; i < operations.length; i++) {
343 |       if (typeof operations[i] !== "function") {
344 |         throw new Error(`Operation at index ${i} is not a function`);
345 |       }
346 |       result = await operations[i]();
347 |       lastSuccessfulIndex = i;
348 |     }
349 |     return result as T;
350 |   } catch (error) {
351 |     log.error(
352 |       `Transaction failed at operation ${lastSuccessfulIndex + 1}:`,
353 |       error
354 |     );
355 | 
356 |     // Perform rollbacks in reverse order
357 |     for (let i = lastSuccessfulIndex; i >= 0; i--) {
358 |       try {
359 |         if (typeof rollbacks[i] === "function") {
360 |           await rollbacks[i]();
361 |         } else {
362 |           log.warn(`Skipping invalid rollback at index ${i} (not a function)`);
363 |         }
364 |       } catch (rollbackError) {
365 |         log.error(`Error during rollback operation ${i}:`, rollbackError);
366 |         // Continue with other rollbacks even if one fails
367 |       }
368 |     }
369 |     throw error;
370 |   }
371 | }
372 | 
373 | /**
374 |  * Safely writes content to a file by first writing to a temp file, then renaming
375 |  * This ensures the file is either completely written or left unchanged
376 |  * @param filePath Path to the file
377 |  * @param content Content to write
378 |  * @param encoding Optional encoding (defaults to 'utf8')
379 |  */
380 | export async function safeWriteFile(
381 |   filePath: string,
382 |   content: string,
383 |   encoding: BufferEncoding = "utf8"
384 | ): Promise<void> {
385 |   const tempPath = `${filePath}.tmp`;
386 | 
387 |   try {
388 |     // Write to temp file
389 |     await fs.writeFile(tempPath, content, encoding);
390 | 
391 |     // Check if the original file exists
392 |     try {
393 |       await fs.access(filePath);
394 |       // If it exists, make a backup
395 |       const backupPath = `${filePath}.bak`;
396 |       await fs.copyFile(filePath, backupPath);
397 | 
398 |       // Replace the original with the temp file
399 |       await fs.rename(tempPath, filePath);
400 | 
401 |       // Remove the backup
402 |       await fs.unlink(backupPath);
403 |     } catch (error) {
404 |       // File doesn't exist, just rename the temp file
405 |       await fs.rename(tempPath, filePath);
406 |     }
407 |   } catch (error) {
408 |     // Clean up temp file if it exists
409 |     try {
410 |       await fs.unlink(tempPath);
411 |     } catch (cleanupError) {
412 |       // Ignore errors during cleanup
413 |     }
414 |     throw error;
415 |   }
416 | }
417 | 
418 | /**
419 |  * Finds and deletes a prompt file
420 |  * @param promptId Unique identifier of the prompt to delete
421 |  * @param baseDir Base directory to search in (usually the prompts directory)
422 |  * @returns Object containing information about the deletion
423 |  */
424 | export async function findAndDeletePromptFile(
425 |   promptId: string,
426 |   baseDir: string
427 | ): Promise<{
428 |   found: boolean;
429 |   deleted: boolean;
430 |   path?: string;
431 |   error?: string;
432 | }> {
433 |   try {
434 |     // First, find the prompt file
435 |     const findResult = await findPromptFile(promptId, baseDir);
436 | 
437 |     // If the file wasn't found, return the result
438 |     if (!findResult.found) {
439 |       return { found: false, deleted: false };
440 |     }
441 | 
442 |     // Try to delete the file
443 |     try {
444 |       await fs.unlink(findResult.path!);
445 |       log.info(`Successfully deleted markdown file: ${findResult.path}`);
446 |       return { found: true, deleted: true, path: findResult.path };
447 |     } catch (deleteError) {
448 |       const errorMessage = `Error deleting file at ${findResult.path}: ${
449 |         deleteError instanceof Error ? deleteError.message : String(deleteError)
450 |       }`;
451 |       log.error(errorMessage);
452 |       return {
453 |         found: true,
454 |         deleted: false,
455 |         path: findResult.path,
456 |         error: errorMessage,
457 |       };
458 |     }
459 |   } catch (error) {
460 |     const errorMessage = `Error finding and deleting prompt file: ${
461 |       error instanceof Error ? error.message : String(error)
462 |     }`;
463 |     log.error(errorMessage);
464 |     return { found: false, deleted: false, error: errorMessage };
465 |   }
466 | }
467 | 
468 | /**
469 |  * Checks if a prompt file exists and returns its path
470 |  * @param promptId Unique identifier of the prompt to find
471 |  * @param baseDir Base directory to search in (usually the prompts directory)
472 |  * @returns Object containing information about the prompt file
473 |  */
474 | export async function findPromptFile(
475 |   promptId: string,
476 |   baseDir: string
477 | ): Promise<{
478 |   found: boolean;
479 |   path?: string;
480 |   category?: string;
481 |   error?: string;
482 | }> {
483 |   try {
484 |     // Get all category directories
485 |     const categoryDirs = await fs.readdir(baseDir, { withFileTypes: true });
486 | 
487 |     // Filter for directories only
488 |     const categories = categoryDirs
489 |       .filter((dirent) => dirent.isDirectory())
490 |       .map((dirent) => dirent.name);
491 | 
492 |     log.info(
493 |       `Searching for markdown file with ID '${promptId}' in ${categories.length} category folders`
494 |     );
495 | 
496 |     // Possible filenames to look for
497 |     const possibleFilenames = [
498 |       `${promptId}.md`, // Simple ID.md
499 |       `${promptId.replace(/-/g, "_")}.md`, // ID with underscores instead of hyphens
500 |       `${promptId.replace(/_/g, "-")}.md`, // ID with hyphens instead of underscores
501 |     ];
502 | 
503 |     // Search each category directory for the file
504 |     for (const category of categories) {
505 |       const categoryPath = path.join(baseDir, category);
506 | 
507 |       try {
508 |         const files = await fs.readdir(categoryPath);
509 | 
510 |         // Check each possible filename
511 |         for (const filename of possibleFilenames) {
512 |           if (files.includes(filename)) {
513 |             const filePath = path.join(categoryPath, filename);
514 |             log.info(`Found markdown file at: ${filePath}`);
515 |             return { found: true, path: filePath, category };
516 |           }
517 |         }
518 |       } catch (readError) {
519 |         log.warn(
520 |           `Error reading directory ${categoryPath}: ${
521 |             readError instanceof Error ? readError.message : String(readError)
522 |           }`
523 |         );
524 |         // Continue to next category
525 |       }
526 |     }
527 | 
528 |     log.warn(
529 |       `Could not find markdown file for prompt '${promptId}' in any category folder`
530 |     );
531 |     return { found: false };
532 |   } catch (error) {
533 |     const errorMessage = `Error searching for prompt file: ${
534 |       error instanceof Error ? error.message : String(error)
535 |     }`;
536 |     log.error(errorMessage);
537 |     return { found: false, error: errorMessage };
538 |   }
539 | }
540 | 
```

--------------------------------------------------------------------------------
/server/src/execution/context/context-resolver.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Context Resolution System
  3 |  * 
  4 |  * Intelligent context resolution with priority-based fallbacks that replaces
  5 |  * the hardcoded {{previous_message}} pattern with flexible, multi-source context aggregation.
  6 |  * 
  7 |  * Features:
  8 |  * - Priority-based context resolution strategies
  9 |  * - Multi-source context aggregation
 10 |  * - Context validation and sanitization
 11 |  * - Smart fallback context generation
 12 |  * - Context caching for performance
 13 |  */
 14 | 
 15 | import { Logger } from "../../logging/index.js";
 16 | import { PromptArgument } from "../../types/index.js";
 17 | 
 18 | /**
 19 |  * Context source types
 20 |  */
 21 | export type ContextSource = 
 22 |   | 'user_provided'
 23 |   | 'conversation_history'
 24 |   | 'environment_variables'
 25 |   | 'prompt_defaults'
 26 |   | 'system_context'
 27 |   | 'cached_context'
 28 |   | 'generated_placeholder'
 29 |   | 'empty_fallback';
 30 | 
 31 | /**
 32 |  * Context resolution result
 33 |  */
 34 | export interface ContextResolution {
 35 |   value: any;
 36 |   source: ContextSource;
 37 |   confidence: number;
 38 |   metadata: {
 39 |     resolvedAt: number;
 40 |     strategy: string;
 41 |     alternativeValues?: Array<{ value: any; source: ContextSource; confidence: number }>;
 42 |     warnings: string[];
 43 |   };
 44 | }
 45 | 
 46 | /**
 47 |  * Context provider interface
 48 |  */
 49 | export interface ContextProvider {
 50 |   name: string;
 51 |   priority: number;
 52 |   isAvailable: () => boolean;
 53 |   resolve: (key: string, hint?: any) => Promise<ContextResolution | null>;
 54 | }
 55 | 
 56 | /**
 57 |  * Context aggregation options
 58 |  */
 59 | export interface ContextAggregationOptions {
 60 |   preferredSources?: ContextSource[];
 61 |   excludedSources?: ContextSource[];
 62 |   cacheResults?: boolean;
 63 |   includeAlternatives?: boolean;
 64 |   minimumConfidence?: number;
 65 | }
 66 | 
 67 | /**
 68 |  * Context resolver class
 69 |  */
 70 | export class ContextResolver {
 71 |   private logger: Logger;
 72 |   private providers: Map<string, ContextProvider> = new Map();
 73 |   private cache: Map<string, ContextResolution> = new Map();
 74 |   private cacheTimeout: number = 30000; // 30 seconds
 75 |   
 76 |   // Resolution statistics
 77 |   private stats = {
 78 |     totalResolutions: 0,
 79 |     successfulResolutions: 0,
 80 |     cacheHits: 0,
 81 |     cacheMisses: 0,
 82 |     providerUsage: new Map<string, number>(),
 83 |     averageConfidence: 0,
 84 |     averageResolutionTime: 0
 85 |   };
 86 | 
 87 |   constructor(logger: Logger) {
 88 |     this.logger = logger;
 89 |     this.initializeDefaultProviders();
 90 |     this.logger.debug(`ContextResolver initialized with ${this.providers.size} providers`);
 91 |   }
 92 | 
 93 |   /**
 94 |    * Resolve context value using priority-based strategy
 95 |    */
 96 |   async resolveContext(
 97 |     key: string, 
 98 |     hint?: any, 
 99 |     options: ContextAggregationOptions = {}
100 |   ): Promise<ContextResolution> {
101 |     const startTime = Date.now();
102 |     this.stats.totalResolutions++;
103 |     
104 |     this.logger.debug(`Resolving context for key: "${key}"`);
105 |     
106 |     // Check cache first
107 |     if (options.cacheResults !== false) {
108 |       const cached = this.getCachedResolution(key);
109 |       if (cached) {
110 |         this.stats.cacheHits++;
111 |         this.logger.debug(`Context resolved from cache: ${key} -> ${cached.source}`);
112 |         return cached;
113 |       }
114 |     }
115 |     
116 |     this.stats.cacheMisses++;
117 |     
118 |     // Get available providers sorted by priority
119 |     const availableProviders = this.getAvailableProviders(options);
120 |     const alternatives: Array<{ value: any; source: ContextSource; confidence: number }> = [];
121 |     
122 |     // Try each provider in priority order
123 |     for (const provider of availableProviders) {
124 |       try {
125 |         const resolution = await provider.resolve(key, hint);
126 |         if (resolution && this.meetsMinimumConfidence(resolution, options)) {
127 |           
128 |           // Collect alternatives if requested
129 |           if (options.includeAlternatives) {
130 |             // Continue trying other providers for alternatives
131 |             await this.collectAlternatives(key, hint, availableProviders, provider, alternatives);
132 |             resolution.metadata.alternativeValues = alternatives;
133 |           }
134 |           
135 |           // Cache the result
136 |           if (options.cacheResults !== false) {
137 |             this.cacheResolution(key, resolution);
138 |           }
139 |           
140 |           // Update statistics
141 |           this.updateStats(provider.name, resolution, startTime);
142 |           
143 |           this.logger.debug(`Context resolved: ${key} -> ${resolution.source} (confidence: ${resolution.confidence})`);
144 |           return resolution;
145 |         } else if (resolution) {
146 |           alternatives.push({
147 |             value: resolution.value,
148 |             source: resolution.source,
149 |             confidence: resolution.confidence
150 |           });
151 |         }
152 |       } catch (error) {
153 |         this.logger.debug(`Provider ${provider.name} failed for key ${key}:`, error);
154 |         continue;
155 |       }
156 |     }
157 |     
158 |     // If no provider succeeded, create a fallback resolution
159 |     const fallbackResolution = this.createFallbackResolution(key, hint, alternatives);
160 |     
161 |     // Cache fallback if enabled
162 |     if (options.cacheResults !== false) {
163 |       this.cacheResolution(key, fallbackResolution);
164 |     }
165 |     
166 |     this.updateStats('fallback', fallbackResolution, startTime);
167 |     this.logger.debug(`Context resolved using fallback: ${key} -> ${fallbackResolution.source}`);
168 |     
169 |     return fallbackResolution;
170 |   }
171 | 
172 |   /**
173 |    * Register a custom context provider
174 |    */
175 |   registerProvider(provider: ContextProvider): void {
176 |     this.providers.set(provider.name, provider);
177 |     this.stats.providerUsage.set(provider.name, 0);
178 |     this.logger.debug(`Registered context provider: ${provider.name} (priority: ${provider.priority})`);
179 |   }
180 | 
181 |   /**
182 |    * Unregister a context provider
183 |    */
184 |   unregisterProvider(name: string): boolean {
185 |     const removed = this.providers.delete(name);
186 |     this.stats.providerUsage.delete(name);
187 |     if (removed) {
188 |       this.logger.debug(`Unregistered context provider: ${name}`);
189 |     }
190 |     return removed;
191 |   }
192 | 
193 |   /**
194 |    * Initialize default context providers
195 |    */
196 |   private initializeDefaultProviders(): void {
197 |     // Conversation history provider
198 |     this.registerProvider({
199 |       name: 'conversation_history',
200 |       priority: 80,
201 |       isAvailable: () => true,
202 |       resolve: async (key: string, hint?: any): Promise<ContextResolution | null> => {
203 |         if (hint?.conversationHistory && hint.conversationHistory.length > 0) {
204 |           const lastMessage = hint.conversationHistory[hint.conversationHistory.length - 1];
205 |           if (lastMessage?.content) {
206 |             return {
207 |               value: lastMessage.content,
208 |               source: 'conversation_history',
209 |               confidence: 0.8,
210 |               metadata: {
211 |                 resolvedAt: Date.now(),
212 |                 strategy: 'last_message',
213 |                 warnings: []
214 |               }
215 |             };
216 |           }
217 |         }
218 |         return null;
219 |       }
220 |     });
221 | 
222 |     // Environment variables provider
223 |     this.registerProvider({
224 |       name: 'environment_variables',
225 |       priority: 70,
226 |       isAvailable: () => true,
227 |       resolve: async (key: string): Promise<ContextResolution | null> => {
228 |         const envKey = `PROMPT_${key.toUpperCase()}`;
229 |         const value = process.env[envKey];
230 |         if (value) {
231 |           return {
232 |             value,
233 |             source: 'environment_variables',
234 |             confidence: 0.9,
235 |             metadata: {
236 |               resolvedAt: Date.now(),
237 |               strategy: 'env_var',
238 |               warnings: []
239 |             }
240 |           };
241 |         }
242 |         return null;
243 |       }
244 |     });
245 | 
246 |     // Prompt defaults provider
247 |     this.registerProvider({
248 |       name: 'prompt_defaults',
249 |       priority: 60,
250 |       isAvailable: () => true,
251 |       resolve: async (key: string, hint?: any): Promise<ContextResolution | null> => {
252 |         if (hint?.promptDefaults && hint.promptDefaults[key] !== undefined) {
253 |           return {
254 |             value: hint.promptDefaults[key],
255 |             source: 'prompt_defaults',
256 |             confidence: 0.7,
257 |             metadata: {
258 |               resolvedAt: Date.now(),
259 |               strategy: 'prompt_specific',
260 |               warnings: []
261 |             }
262 |           };
263 |         }
264 |         return null;
265 |       }
266 |     });
267 | 
268 |     // System context provider
269 |     this.registerProvider({
270 |       name: 'system_context',
271 |       priority: 50,
272 |       isAvailable: () => true,
273 |       resolve: async (key: string, hint?: any): Promise<ContextResolution | null> => {
274 |         if (hint?.systemContext && hint.systemContext[key] !== undefined) {
275 |           return {
276 |             value: hint.systemContext[key],
277 |             source: 'system_context',
278 |             confidence: 0.6,
279 |             metadata: {
280 |               resolvedAt: Date.now(),
281 |               strategy: 'system_provided',
282 |               warnings: []
283 |             }
284 |           };
285 |         }
286 |         return null;
287 |       }
288 |     });
289 | 
290 |     // Smart placeholder generator
291 |     this.registerProvider({
292 |       name: 'placeholder_generator',
293 |       priority: 30,
294 |       isAvailable: () => true,
295 |       resolve: async (key: string, hint?: any): Promise<ContextResolution | null> => {
296 |         const placeholder = this.generateSmartPlaceholder(key, hint);
297 |         return {
298 |           value: placeholder.value,
299 |           source: 'generated_placeholder',
300 |           confidence: placeholder.confidence,
301 |           metadata: {
302 |             resolvedAt: Date.now(),
303 |             strategy: 'smart_generation',
304 |             warnings: placeholder.warnings
305 |           }
306 |         };
307 |       }
308 |     });
309 |   }
310 | 
311 |   /**
312 |    * Get available providers based on options
313 |    */
314 |   private getAvailableProviders(options: ContextAggregationOptions): ContextProvider[] {
315 |     return Array.from(this.providers.values())
316 |       .filter(provider => {
317 |         // Check if provider is available
318 |         if (!provider.isAvailable()) return false;
319 |         
320 |         // Check preferred sources
321 |         if (options.preferredSources?.length) {
322 |           // This is a simplistic check - in practice you'd map provider names to sources
323 |           const providerSource = this.mapProviderToSource(provider.name);
324 |           if (!options.preferredSources.includes(providerSource)) return false;
325 |         }
326 |         
327 |         // Check excluded sources
328 |         if (options.excludedSources?.length) {
329 |           const providerSource = this.mapProviderToSource(provider.name);
330 |           if (options.excludedSources.includes(providerSource)) return false;
331 |         }
332 |         
333 |         return true;
334 |       })
335 |       .sort((a, b) => b.priority - a.priority); // Higher priority first
336 |   }
337 | 
338 |   /**
339 |    * Map provider name to context source
340 |    */
341 |   private mapProviderToSource(providerName: string): ContextSource {
342 |     const mapping: Record<string, ContextSource> = {
343 |       'conversation_history': 'conversation_history',
344 |       'environment_variables': 'environment_variables',
345 |       'prompt_defaults': 'prompt_defaults',
346 |       'system_context': 'system_context',
347 |       'placeholder_generator': 'generated_placeholder'
348 |     };
349 |     
350 |     return mapping[providerName] || 'system_context';
351 |   }
352 | 
353 |   /**
354 |    * Check if resolution meets minimum confidence
355 |    */
356 |   private meetsMinimumConfidence(resolution: ContextResolution, options: ContextAggregationOptions): boolean {
357 |     if (options.minimumConfidence === undefined) return true;
358 |     return resolution.confidence >= options.minimumConfidence;
359 |   }
360 | 
361 |   /**
362 |    * Collect alternative values from other providers
363 |    */
364 |   private async collectAlternatives(
365 |     key: string,
366 |     hint: any,
367 |     allProviders: ContextProvider[],
368 |     usedProvider: ContextProvider,
369 |     alternatives: Array<{ value: any; source: ContextSource; confidence: number }>
370 |   ): Promise<void> {
371 |     const remainingProviders = allProviders.filter(p => p !== usedProvider);
372 |     
373 |     for (const provider of remainingProviders.slice(0, 3)) { // Limit to 3 alternatives
374 |       try {
375 |         const resolution = await provider.resolve(key, hint);
376 |         if (resolution) {
377 |           alternatives.push({
378 |             value: resolution.value,
379 |             source: resolution.source,
380 |             confidence: resolution.confidence
381 |           });
382 |         }
383 |       } catch (error) {
384 |         // Ignore errors when collecting alternatives
385 |         continue;
386 |       }
387 |     }
388 |   }
389 | 
390 |   /**
391 |    * Generate smart placeholder based on key characteristics
392 |    */
393 |   private generateSmartPlaceholder(
394 |     key: string, 
395 |     hint?: any
396 |   ): { value: string; confidence: number; warnings: string[] } {
397 |     const keyLower = key.toLowerCase();
398 |     const warnings: string[] = [];
399 |     
400 |     // Argument-specific placeholders
401 |     if (hint?.argumentDef) {
402 |       const arg = hint.argumentDef as PromptArgument;
403 |       const description = (arg.description || '').toLowerCase();
404 |       
405 |       if (description.includes('file') || keyLower.includes('file')) {
406 |         return { value: '[File path required]', confidence: 0.4, warnings };
407 |       }
408 |       
409 |       if (description.includes('url') || keyLower.includes('url')) {
410 |         return { value: '[URL required]', confidence: 0.4, warnings };
411 |       }
412 |       
413 |       if (description.includes('number') || keyLower.includes('count')) {
414 |         return { value: '1', confidence: 0.5, warnings };
415 |       }
416 |     }
417 |     
418 |     // Generic semantic placeholders
419 |     if (keyLower.includes('content') || keyLower.includes('text') || keyLower.includes('input')) {
420 |       return { 
421 |         value: '[Content to be provided]', 
422 |         confidence: 0.3, 
423 |         warnings: ['Generic content placeholder - consider providing specific content']
424 |       };
425 |     }
426 |     
427 |     if (keyLower.includes('name') || keyLower.includes('title')) {
428 |       return { value: `[${key} required]`, confidence: 0.3, warnings };
429 |     }
430 |     
431 |     if (keyLower.includes('format') || keyLower.includes('style')) {
432 |       return { value: 'default', confidence: 0.4, warnings };
433 |     }
434 |     
435 |     if (keyLower.includes('language') || keyLower.includes('lang')) {
436 |       return { value: 'en', confidence: 0.4, warnings };
437 |     }
438 |     
439 |     // Ultra-generic fallback
440 |     warnings.push(`No semantic match found for "${key}" - using generic placeholder`);
441 |     return { 
442 |       value: `[${key.replace(/_/g, ' ')} to be specified]`, 
443 |       confidence: 0.2, 
444 |       warnings 
445 |     };
446 |   }
447 | 
448 |   /**
449 |    * Create fallback resolution when no providers succeed
450 |    */
451 |   private createFallbackResolution(
452 |     key: string,
453 |     hint: any,
454 |     alternatives: Array<{ value: any; source: ContextSource; confidence: number }>
455 |   ): ContextResolution {
456 |     // If we have alternatives, use the best one
457 |     if (alternatives.length > 0) {
458 |       const best = alternatives.sort((a, b) => b.confidence - a.confidence)[0];
459 |       return {
460 |         value: best.value,
461 |         source: best.source,
462 |         confidence: best.confidence,
463 |         metadata: {
464 |           resolvedAt: Date.now(),
465 |           strategy: 'best_alternative',
466 |           alternativeValues: alternatives,
467 |           warnings: ['Used alternative resolution after primary strategies failed']
468 |         }
469 |       };
470 |     }
471 |     
472 |     // Last resort: empty fallback
473 |     return {
474 |       value: '',
475 |       source: 'empty_fallback',
476 |       confidence: 0.1,
477 |       metadata: {
478 |         resolvedAt: Date.now(),
479 |         strategy: 'empty_fallback',
480 |         warnings: [`No context available for "${key}" - using empty value`]
481 |       }
482 |     };
483 |   }
484 | 
485 |   /**
486 |    * Get cached resolution if available and not expired
487 |    */
488 |   private getCachedResolution(key: string): ContextResolution | null {
489 |     const cached = this.cache.get(key);
490 |     if (cached && (Date.now() - cached.metadata.resolvedAt) < this.cacheTimeout) {
491 |       return cached;
492 |     } else if (cached) {
493 |       // Remove expired cache entry
494 |       this.cache.delete(key);
495 |     }
496 |     return null;
497 |   }
498 | 
499 |   /**
500 |    * Cache resolution result
501 |    */
502 |   private cacheResolution(key: string, resolution: ContextResolution): void {
503 |     this.cache.set(key, resolution);
504 |     
505 |     // Cleanup old entries periodically
506 |     if (this.cache.size > 1000) {
507 |       const cutoff = Date.now() - this.cacheTimeout;
508 |       for (const [k, v] of this.cache.entries()) {
509 |         if (v.metadata.resolvedAt < cutoff) {
510 |           this.cache.delete(k);
511 |         }
512 |       }
513 |     }
514 |   }
515 | 
516 |   /**
517 |    * Update resolution statistics
518 |    */
519 |   private updateStats(providerName: string, resolution: ContextResolution, startTime: number): void {
520 |     this.stats.successfulResolutions++;
521 |     
522 |     const current = this.stats.providerUsage.get(providerName) || 0;
523 |     this.stats.providerUsage.set(providerName, current + 1);
524 |     
525 |     // Update average confidence
526 |     const totalSuccessful = this.stats.successfulResolutions;
527 |     this.stats.averageConfidence = 
528 |       (this.stats.averageConfidence * (totalSuccessful - 1) + resolution.confidence) / totalSuccessful;
529 |     
530 |     // Update average resolution time
531 |     const resolutionTime = Date.now() - startTime;
532 |     this.stats.averageResolutionTime =
533 |       (this.stats.averageResolutionTime * (totalSuccessful - 1) + resolutionTime) / totalSuccessful;
534 |   }
535 | 
536 |   /**
537 |    * Clear cache
538 |    */
539 |   clearCache(): void {
540 |     this.cache.clear();
541 |     this.logger.debug('Context cache cleared');
542 |   }
543 | 
544 |   /**
545 |    * Get context resolution statistics
546 |    */
547 |   getStats(): typeof this.stats {
548 |     return {
549 |       ...this.stats,
550 |       providerUsage: new Map(this.stats.providerUsage)
551 |     };
552 |   }
553 | 
554 |   /**
555 |    * Reset statistics
556 |    */
557 |   resetStats(): void {
558 |     this.stats = {
559 |       totalResolutions: 0,
560 |       successfulResolutions: 0,
561 |       cacheHits: 0,
562 |       cacheMisses: 0,
563 |       providerUsage: new Map(Array.from(this.providers.keys()).map(name => [name, 0])),
564 |       averageConfidence: 0,
565 |       averageResolutionTime: 0
566 |     };
567 |   }
568 | }
569 | 
570 | /**
571 |  * Factory function to create context resolver
572 |  */
573 | export function createContextResolver(logger: Logger): ContextResolver {
574 |   return new ContextResolver(logger);
575 | }
```

--------------------------------------------------------------------------------
/server/prompts/analysis/advanced_analysis_engine.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Advanced Analysis Engine
  2 | 
  3 | ## Description
  4 | Complex template testing prompt with advanced Nunjucks features including conditionals, loops, inheritance, filters, and multi-format output generation. Designed to stress-test the template engine with maximum complexity.
  5 | 
  6 | ## System Message
  7 | You are an advanced analysis engine capable of processing complex requests with multiple data sources, analysis types, and output formats. Handle all template complexity gracefully and provide structured, comprehensive analysis. This prompt tests advanced template features including nested conditionals, complex loops, filters, and dynamic content generation.
  8 | 
  9 | ## User Message Template
 10 | # 🔍 Advanced Analysis: {{ topic | title if topic else "General Analysis" }}
 11 | 
 12 | ## 🎯 Analysis Configuration
 13 | {% if analysis_type %}
 14 | **Analysis Type**: {{ analysis_type | upper | replace("_", " ") }}
 15 | {% else %}
 16 | **Analysis Type**: COMPREHENSIVE MULTI-DIMENSIONAL ANALYSIS
 17 | {% endif %}
 18 | 
 19 | {% set complexity_score = 0 %}
 20 | {% if sources %}{% set complexity_score = complexity_score + sources|length %}{% endif %}
 21 | {% if focus_areas %}{% set complexity_score = complexity_score + focus_areas|length %}{% endif %}
 22 | {% if constraints %}{% set complexity_score = complexity_score + constraints|length %}{% endif %}
 23 | 
 24 | **Complexity Score**: {{ complexity_score }} 
 25 | {% if complexity_score > 10 %}🔥 MAXIMUM COMPLEXITY{% elif complexity_score > 5 %}⚡ HIGH COMPLEXITY{% else %}📊 STANDARD COMPLEXITY{% endif %}
 26 | 
 27 | {% if sources %}
 28 | ## 📊 Data Sources Strategy
 29 | {% for source in sources %}
 30 | {% set loop_info = loop %}
 31 | {{ loop.index }}. **{{ source | title | replace("_", " ") }}**
 32 |    {% if source == "web" %}
 33 |    - Current information and real-time trends
 34 |    - SEO-optimized content analysis
 35 |    - Social sentiment indicators
 36 |    {% elif source == "papers" %}
 37 |    - Peer-reviewed research and academic insights
 38 |    - Methodological rigor and scientific validation
 39 |    - Historical context and longitudinal studies
 40 |    {% elif source == "news" %}
 41 |    - Breaking developments and current events
 42 |    - Media bias analysis and fact-checking
 43 |    - Timeline construction and event correlation
 44 |    {% elif source == "social" %}
 45 |    - Public opinion and sentiment analysis
 46 |    - Viral trend identification
 47 |    - Demographic and geographic distribution
 48 |    {% elif source == "industry" %}
 49 |    - Market reports and industry intelligence
 50 |    - Competitive landscape analysis
 51 |    - Regulatory and compliance considerations
 52 |    {% elif source == "expert" %}
 53 |    - Professional opinions and expert interviews
 54 |    - Specialized knowledge and insider perspectives
 55 |    - Best practices and lessons learned
 56 |    {% else %}
 57 |    - {{ source | title }} data collection and analysis
 58 |    - Source-specific validation and verification
 59 |    - Integration with primary research methods
 60 |    {% endif %}
 61 |    {% if loop.first %}**PRIMARY SOURCE** - Foundation for analysis{% endif %}
 62 |    {% if loop.last %}**VALIDATION SOURCE** - Final verification and cross-reference{% endif %}
 63 |    {% if loop.length > 3 and loop.index == loop.length // 2 %}**PIVOT SOURCE** - Mid-analysis validation{% endif %}
 64 | {% endfor %}
 65 | 
 66 | ### Source Integration Matrix
 67 | {% for source in sources %}
 68 | {% for other_source in sources %}
 69 | {% if source != other_source %}
 70 | - **{{ source|title }} ↔ {{ other_source|title }}**: {% if source == "web" and other_source == "papers" %}Validate web claims with academic research{% elif source == "news" and other_source == "social" %}Cross-reference news with social sentiment{% else %}Comparative analysis and validation{% endif %}
 71 | {% endif %}
 72 | {% endfor %}
 73 | {% endfor %}
 74 | {% else %}
 75 | ## 📊 Standard Data Sources
 76 | 1. **Web Research** - Current information and trends
 77 | 2. **Academic Papers** - Scholarly perspective and research  
 78 | 3. **News Articles** - Recent developments and context
 79 | 4. **Industry Reports** - Market intelligence and analysis
 80 | {% endif %}
 81 | 
 82 | {% if depth %}
 83 | ## 🎚️ Analysis Depth: {{ depth | title }}
 84 | {% set depth_config = {
 85 |   "surface": {
 86 |     "description": "Quick overview and key highlights",
 87 |     "time_estimate": "15-30 minutes",
 88 |     "output_length": "2-3 pages", 
 89 |     "detail_level": "High-level summary with actionable insights"
 90 |   },
 91 |   "standard": {
 92 |     "description": "Detailed examination of core topics",
 93 |     "time_estimate": "1-2 hours",
 94 |     "output_length": "5-8 pages",
 95 |     "detail_level": "Comprehensive analysis with supporting evidence"
 96 |   },
 97 |   "comprehensive": {
 98 |     "description": "Deep-dive analysis across all dimensions", 
 99 |     "time_estimate": "3-5 hours",
100 |     "output_length": "10-15 pages",
101 |     "detail_level": "Multi-perspective evaluation with detailed frameworks"
102 |   },
103 |   "expert": {
104 |     "description": "Expert-level technical analysis",
105 |     "time_estimate": "6+ hours", 
106 |     "output_length": "15+ pages",
107 |     "detail_level": "Advanced methodology with strategic recommendations"
108 |   }
109 | } %}
110 | 
111 | {% set current_depth = depth_config[depth] if depth in depth_config else depth_config["standard"] %}
112 | 
113 | - **Description**: {{ current_depth.description }}
114 | - **Estimated Time**: {{ current_depth.time_estimate }}
115 | - **Expected Output**: {{ current_depth.output_length }}
116 | - **Detail Level**: {{ current_depth.detail_level }}
117 | 
118 | {% if depth == "expert" %}
119 | ### Expert Analysis Framework
120 | - Advanced statistical analysis and modeling
121 | - Multi-dimensional correlation mapping
122 | - Predictive analytics and scenario planning
123 | - Risk assessment matrices and mitigation strategies
124 | {% endif %}
125 | {% endif %}
126 | 
127 | {% if constraints %}
128 | ## ⚙️ Analysis Constraints & Parameters
129 | {% for key, value in constraints.items() %}
130 | - **{{ key | replace("_", " ") | title }}**: {{ value }}
131 |   {% if key == "time_limit" %}*Prioritizing high-impact insights within timeframe*{% endif %}
132 |   {% if key == "budget" %}*Cost-effective research methods and resource allocation*{% endif %}
133 |   {% if key == "scope" %}*Focused analysis boundaries and exclusion criteria*{% endif %}
134 |   {% if key == "audience" %}*Content and presentation tailored for {{ value }}*{% endif %}
135 | {% endfor %}
136 | 
137 | ### Constraint Impact Assessment
138 | {% if constraints.time_limit %}
139 | ⏱️ **Time Pressure**: Accelerated methodology with focus on critical insights
140 | {% endif %}
141 | {% if constraints.budget %}
142 | 💰 **Budget Optimization**: Prioritized research activities and cost-effective approaches  
143 | {% endif %}
144 | {% if constraints.scope %}
145 | 🎯 **Scope Management**: Clear boundaries prevent scope creep and maintain focus
146 | {% endif %}
147 | {% endif %}
148 | 
149 | {% if focus_areas %}
150 | ## 🔍 Multi-Dimensional Focus Areas
151 | {% for area in focus_areas %}
152 | ### {{ loop.index }}. {{ area | title }} Analysis Framework
153 | {% if area == "technical" %}
154 | #### Technical Deep-Dive
155 | - **Architecture & Design**: System specifications and technical requirements
156 | - **Implementation Details**: Development methodologies and best practices  
157 | - **Performance Metrics**: Benchmarking, optimization, and scalability analysis
158 | - **Technology Stack**: Tools, frameworks, and platform considerations
159 | - **Risk Assessment**: Technical debt, security vulnerabilities, maintenance overhead
160 | {% elif area == "business" %}
161 | #### Business Impact Analysis
162 | - **Market Dynamics**: Competitive landscape and positioning strategies
163 | - **Financial Modeling**: Revenue projections, cost analysis, and ROI calculations
164 | - **Strategic Alignment**: Business objectives and organizational fit
165 | - **Stakeholder Impact**: Customer, partner, and internal team considerations
166 | - **Go-to-Market**: Launch strategies, marketing approaches, and sales enablement
167 | {% elif area == "ethical" %}
168 | #### Ethical Framework Evaluation
169 | - **Moral Implications**: Ethical principles and moral reasoning analysis
170 | - **Stakeholder Impact**: Effects on users, communities, and society
171 | - **Privacy & Rights**: Data protection, consent, and individual autonomy
172 | - **Fairness & Bias**: Algorithmic fairness and discrimination prevention
173 | - **Transparency**: Explainability, accountability, and public discourse
174 | {% elif area == "regulatory" %}
175 | #### Regulatory Compliance Analysis
176 | - **Legal Framework**: Applicable laws, regulations, and compliance requirements
177 | - **Risk Assessment**: Legal exposure, liability, and mitigation strategies
178 | - **Policy Implications**: Government relations and regulatory strategy
179 | - **International Considerations**: Cross-border regulations and harmonization
180 | - **Future Regulations**: Anticipated regulatory changes and preparation strategies
181 | {% elif area == "social" %}
182 | #### Social Impact Assessment
183 | - **Community Effects**: Local and global community implications
184 | - **Cultural Considerations**: Cross-cultural sensitivity and adaptation
185 | - **Public Opinion**: Social acceptance and public discourse analysis
186 | - **Digital Divide**: Accessibility and inclusion considerations
187 | - **Behavioral Change**: Individual and collective behavior modifications
188 | {% elif area == "environmental" %}
189 | #### Environmental Sustainability Analysis
190 | - **Carbon Footprint**: Environmental impact and sustainability metrics
191 | - **Resource Usage**: Energy consumption and resource optimization
192 | - **Lifecycle Assessment**: End-to-end environmental impact evaluation
193 | - **Green Alternatives**: Sustainable approaches and eco-friendly solutions
194 | - **Regulatory Environment**: Environmental regulations and compliance
195 | {% else %}
196 | #### {{ area | title }} Framework
197 | - **Core Principles**: Fundamental concepts and guiding principles
198 | - **Key Considerations**: Critical factors and decision points
199 | - **Impact Assessment**: Quantitative and qualitative impact evaluation
200 | - **Risk Factors**: Potential challenges and mitigation strategies
201 | - **Best Practices**: Industry standards and recommended approaches
202 | {% endif %}
203 | 
204 | {% if not loop.last %}
205 | ---
206 | {% endif %}
207 | {% endfor %}
208 | 
209 | ### Focus Area Integration Matrix
210 | {% for area1 in focus_areas %}
211 | {% for area2 in focus_areas %}
212 | {% if area1 != area2 and loop.index0 < loop.index %}
213 | - **{{ area1|title }} ↔ {{ area2|title }}**: Cross-dimensional analysis and synergy identification
214 | {% endif %}
215 | {% endfor %}
216 | {% endfor %}
217 | {% else %}
218 | ## 🔍 Standard Analysis Framework
219 | 1. **Contextual Overview** - Current state and background analysis
220 | 2. **Trend Identification** - Pattern recognition and trend analysis
221 | 3. **Impact Assessment** - Quantitative and qualitative impact evaluation
222 | 4. **Strategic Implications** - Long-term considerations and planning
223 | 5. **Actionable Recommendations** - Specific next steps and implementation guidance
224 | {% endif %}
225 | 
226 | {% if format %}
227 | ## 📋 Output Format Specification: {{ format | title | replace("_", " ") }}
228 | {% set format_specs = {
229 |   "executive_summary": {
230 |     "structure": "Executive Summary → Key Findings → Strategic Recommendations → Appendices",
231 |     "length": "2-4 pages + supporting materials",
232 |     "audience": "C-level executives, board members, and senior decision makers",
233 |     "style": "Concise, decision-focused, high-level strategic content",
234 |     "sections": ["Executive Overview", "Critical Insights", "Strategic Options", "Resource Requirements", "Timeline & Milestones"]
235 |   },
236 |   "technical_report": {
237 |     "structure": "Technical Overview → Detailed Analysis → Implementation Guide → Technical Appendices",
238 |     "length": "10-20 pages + technical documentation", 
239 |     "audience": "Technical teams, engineers, and implementation specialists",
240 |     "style": "Detailed, implementation-focused, technical depth",
241 |     "sections": ["Technical Architecture", "Detailed Specifications", "Implementation Roadmap", "Technical Risks", "Testing & Validation"]
242 |   },
243 |   "presentation": {
244 |     "structure": "Slide deck with executive summary, detailed findings, and action items",
245 |     "length": "15-25 slides + speaker notes",
246 |     "audience": "Mixed stakeholder groups and meeting presentations", 
247 |     "style": "Visual, presentation-ready, engaging narrative",
248 |     "sections": ["Problem Statement", "Analysis Overview", "Key Findings", "Recommendations", "Next Steps"]
249 |   },
250 |   "research_paper": {
251 |     "structure": "Abstract → Introduction → Literature Review → Analysis → Discussion → Conclusions → References",
252 |     "length": "15-30 pages + extensive bibliography",
253 |     "audience": "Academic researchers, policy makers, and domain experts",
254 |     "style": "Academic rigor, peer-review ready, comprehensive citations",
255 |     "sections": ["Abstract", "Introduction", "Methodology", "Results & Analysis", "Discussion", "Conclusions", "Future Research"]
256 |   }
257 | } %}
258 | 
259 | {% set current_format = format_specs[format] if format in format_specs else format_specs["executive_summary"] %}
260 | 
261 | ### Format Configuration
262 | - **Structure**: {{ current_format.structure }}
263 | - **Expected Length**: {{ current_format.length }}
264 | - **Target Audience**: {{ current_format.audience }}
265 | - **Writing Style**: {{ current_format.style }}
266 | 
267 | ### Content Sections
268 | {% for section in current_format.sections %}
269 | {{ loop.index }}. **{{ section }}**
270 | {% endfor %}
271 | 
272 | ### Presentation Guidelines
273 | {% if format == "executive_summary" %}
274 | - Lead with bottom-line impact and recommendations
275 | - Use bullet points and executive-friendly language
276 | - Include financial implications and resource requirements
277 | - Provide clear decision points and options
278 | {% elif format == "technical_report" %}
279 | - Include detailed technical specifications and diagrams
280 | - Provide step-by-step implementation guidance
281 | - Document technical dependencies and requirements
282 | - Include testing procedures and validation methods
283 | {% elif format == "presentation" %}
284 | - Design slide-ready content with clear headings
285 | - Include data visualizations and infographics
286 | - Provide speaker notes and presentation guidance
287 | - Structure for 30-45 minute presentation window
288 | {% elif format == "research_paper" %}
289 | - Follow academic formatting and citation standards
290 | - Include comprehensive literature review and methodology
291 | - Provide detailed statistical analysis and evidence
292 | - Structure for peer review and academic publication
293 | {% endif %}
294 | {% endif %}
295 | 
296 | {% if previous_context %}
297 | ## 🔗 Building Upon Previous Analysis
298 | **Previous Context Integration:**
299 | {{ previous_context }}
300 | 
301 | ### Continuity Framework
302 | - **Historical Baseline**: Previous findings serve as analytical foundation
303 | - **Evolutionary Analysis**: Changes and developments since last analysis
304 | - **Gap Identification**: Areas requiring additional investigation
305 | - **Trend Validation**: Confirmation or revision of previous predictions
306 | {% endif %}
307 | 
308 | {% if requirements %}
309 | ## ✅ Specific Requirements & Success Criteria
310 | {% for req in requirements %}
311 | {% if req is string %}
312 | {{ loop.index }}. {{ req }}
313 | {% else %}
314 | {{ loop.index }}. **{{ req.category | default("General Requirement") | title }}**: {{ req.description }}
315 |    {% if req.priority %}
316 |    - **Priority Level**: {{ req.priority | upper }}
317 |    {% if req.priority == "critical" %}🔴 CRITICAL - Must be addressed in core analysis
318 |    {% elif req.priority == "high" %}🟡 HIGH - Primary focus area
319 |    {% elif req.priority == "medium" %}🟢 MEDIUM - Important but not critical
320 |    {% else %}⚪ LOW - Include if time/resources permit{% endif %}
321 |    {% endif %}
322 |    {% if req.examples %}
323 |    - **Examples**: {% for ex in req.examples %}{{ ex }}{% if not loop.last %}, {% endif %}{% endfor %}
324 |    {% endif %}
325 |    {% if req.success_criteria %}
326 |    - **Success Criteria**: {{ req.success_criteria }}
327 |    {% endif %}
328 | {% endif %}
329 | {% endfor %}
330 | 
331 | ### Requirements Validation Matrix
332 | {% for req in requirements %}
333 | {% if req is not string and req.priority %}
334 | - **{{ req.category | default("Requirement " + loop.index|string) }}** ({{ req.priority|upper }}): Validation method and acceptance criteria
335 | {% endif %}
336 | {% endfor %}
337 | {% endif %}
338 | 
339 | ---
340 | 
341 | ## 🎯 Analysis Execution Framework
342 | 
343 | ### Phase 1: Foundation & Context
344 | - Establish analytical baseline and context
345 | - Validate scope and constraints alignment
346 | - Confirm data source accessibility and reliability
347 | 
348 | ### Phase 2: Multi-Dimensional Investigation  
349 | {% if focus_areas %}
350 | {% for area in focus_areas %}
351 | - **{{ area|title }} Analysis**: Deep-dive investigation and assessment
352 | {% endfor %}
353 | {% else %}
354 | - Comprehensive investigation across all relevant dimensions
355 | {% endif %}
356 | 
357 | ### Phase 3: Integration & Synthesis
358 | - Cross-dimensional pattern identification
359 | - Insight synthesis and framework development
360 | - Validation against requirements and constraints
361 | 
362 | ### Phase 4: Recommendations & Implementation
363 | - Strategic recommendation development
364 | - Implementation pathway design
365 | - Risk assessment and mitigation planning
366 | 
367 | ---
368 | 
369 | **🚀 Analysis Request Summary:**
370 | - **Topic**: {{ topic }}
371 | - **Complexity**: {% if sources and focus_areas and constraints %}Maximum ({{ complexity_score }} complexity points){% elif focus_areas or constraints %}High{% else %}Standard{% endif %}
372 | - **Expected Deliverable**: {{ format | default("Comprehensive Analysis") | title }}
373 | - **Timeline**: {% if constraints.time_limit %}{{ constraints.time_limit }}{% else %}Standard delivery window{% endif %}
374 | 
375 | {% set template_features_used = [] %}
376 | {% if sources %}{% set _ = template_features_used.append("Dynamic source configuration") %}{% endif %}
377 | {% if focus_areas %}{% set _ = template_features_used.append("Multi-dimensional framework") %}{% endif %}
378 | {% if constraints %}{% set _ = template_features_used.append("Constraint optimization") %}{% endif %}
379 | {% if requirements %}{% set _ = template_features_used.append("Requirements validation") %}{% endif %}
380 | {% if format %}{% set _ = template_features_used.append("Format specialization") %}{% endif %}
381 | 
382 | **🔧 Template Features Active**: {{ template_features_used | join(", ") | default("Standard template rendering") }}
383 | 
384 | ---
385 | 
386 | Please provide a comprehensive analysis following the above specifications. Ensure all requested dimensions are covered, the output matches the specified format requirements, and the analysis demonstrates the full complexity and capability of this advanced template system.
387 | 
```

--------------------------------------------------------------------------------
/docs/prompt-management.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Prompt Management
  2 | 
  3 | This document describes how to manage prompts in the MCP server using the **consolidated prompt management system** through the `prompt_manager` tool and distributed prompts configuration.
  4 | 
  5 | ## Consolidated Architecture Overview
  6 | 
  7 | The MCP server uses **3 consolidated tools** for all prompt management operations:
  8 | 
  9 | - **`prompt_manager`**: Complete lifecycle management with intelligent analysis and filtering
 10 | - **`prompt_engine`**: Execute prompts with framework integration and gate validation
 11 | - **`system_control`**: Framework switching, analytics, and system administration
 12 | 
 13 | **Key Benefits:**
 14 | 
 15 | - **Action-Based Interface**: Single tools with multiple actions instead of separate tools
 16 | - **Intelligent Features**: Type analysis, framework integration, advanced filtering
 17 | - **MCP Protocol Only**: No HTTP API - works through MCP-compatible clients
 18 | 
 19 | ## Distributed Prompts Configuration System
 20 | 
 21 | The server organizes prompts using a distributed configuration system where prompts are organized by category, with each category having its own configuration file.
 22 | 
 23 | ### Key Components
 24 | 
 25 | 1. **promptsConfig.json** - Main configuration file defining categories and imports
 26 | 2. **Category-specific prompts.json files** - Each category has its own prompts.json file
 27 | 3. **Prompt .md files** - Individual prompt templates using Nunjucks templating
 28 | 
 29 | ## Main Configuration (promptsConfig.json)
 30 | 
 31 | The main configuration file defines all available categories and specifies which category-specific prompts.json files to import:
 32 | 
 33 | ```json
 34 | {
 35 |   "categories": [
 36 |     {
 37 |       "id": "general",
 38 |       "name": "General",
 39 |       "description": "General-purpose prompts for everyday tasks"
 40 |     },
 41 |     {
 42 |       "id": "analysis",
 43 |       "name": "Analysis",
 44 |       "description": "Analytical and research-focused prompts"
 45 |     },
 46 |     {
 47 |       "id": "development",
 48 |       "name": "Development",
 49 |       "description": "Software development and coding prompts"
 50 |     }
 51 |     // More categories...
 52 |   ],
 53 |   "imports": [
 54 |     "prompts/general/prompts.json",
 55 |     "prompts/analysis/prompts.json",
 56 |     "prompts/development/prompts.json"
 57 |     // More imports...
 58 |   ]
 59 | }
 60 | ```
 61 | 
 62 | ### Categories
 63 | 
 64 | Each category in the `categories` array has:
 65 | 
 66 | - `id` (string) - Unique identifier for the category
 67 | - `name` (string) - Display name for the category
 68 | - `description` (string) - Description of the category's purpose
 69 | 
 70 | ### Imports
 71 | 
 72 | The `imports` array lists paths to category-specific prompts.json files, relative to the server's working directory.
 73 | 
 74 | ## Category-Specific Prompts Files
 75 | 
 76 | Each category has its own prompts.json file (e.g., `prompts/general/prompts.json`):
 77 | 
 78 | ```json
 79 | {
 80 |   "prompts": [
 81 |     {
 82 |       "id": "content_analysis",
 83 |       "name": "Content Analysis",
 84 |       "category": "analysis",
 85 |       "description": "Systematic analysis of content using structured methodology",
 86 |       "file": "content_analysis.md",
 87 |       "arguments": [
 88 |         {
 89 |           "name": "content",
 90 |           "description": "The content to analyze",
 91 |           "required": true
 92 |         },
 93 |         {
 94 |           "name": "focus",
 95 |           "description": "Specific focus area for analysis",
 96 |           "required": false
 97 |         }
 98 |       ]
 99 |     }
100 |     // More prompts...
101 |   ]
102 | }
103 | ```
104 | 
105 | Each prompt has:
106 | 
107 | - `id` (string) - Unique identifier
108 | - `name` (string) - Display name
109 | - `category` (string) - Category this prompt belongs to
110 | - `description` (string) - What the prompt does
111 | - `file` (string) - Path to .md file with template
112 | - `arguments` (array) - Arguments the prompt accepts
113 | - `isChain` (boolean, optional) - Whether this is a chain prompt
114 | - `chainSteps` (array, optional) - Steps for chain prompts
115 | - `onEmptyInvocation` (string, optional) - Behavior when invoked without arguments
116 | 
117 | ## Consolidated Prompt Management
118 | 
119 | ### prompt_manager Tool Actions
120 | 
121 | The `prompt_manager` tool provides comprehensive prompt lifecycle management through **action-based commands**:
122 | 
123 | #### Core Actions
124 | 
125 | - `list` - List and filter prompts with intelligent search
126 | - `create` - Auto-detect type and create appropriate prompt
127 | - `create_prompt` - Create basic prompt (fast variable substitution)
128 | - `create_template` - Create framework-enhanced template
129 | - `update` - Update existing prompts
130 | - `delete` - Delete prompts with safety checks
131 | 
132 | #### Advanced Actions
133 | 
134 | - `analyze_type` - Analyze prompt and recommend execution type
135 | - `migrate_type` - Convert between prompt types (prompt ↔ template)
136 | - `modify` - Precision editing of specific sections
137 | - `reload` - Trigger hot-reload of prompt system
138 | 
139 | ### Basic Prompt Management
140 | 
141 | #### Listing Prompts
142 | 
143 | ```bash
144 | # List all prompts
145 | prompt_manager list
146 | 
147 | # List prompts in specific category
148 | prompt_manager list filter="category:analysis"
149 | 
150 | # List by execution type
151 | prompt_manager list filter="type:template"
152 | 
153 | # Combined filters
154 | prompt_manager list filter="category:development type:chain"
155 | 
156 | # Intent-based search
157 | prompt_manager list filter="intent:debugging"
158 | ```
159 | 
160 | #### Creating Prompts
161 | 
162 | ```bash
163 | # Auto-detect appropriate type
164 | prompt_manager create name="Data Processor" category="analysis" \
165 |   description="Process and analyze data systematically" \
166 |   content="Analyze {{data}} and provide insights on {{focus_area}}"
167 | 
168 | # Create basic prompt (fast execution)
169 | prompt_manager create_prompt name="Simple Greeting" category="general" \
170 |   description="Basic personalized greeting" \
171 |   content="Hello {{name}}, welcome to {{service}}!" \
172 |   arguments='[{"name":"name","required":true},{"name":"service","required":false}]'
173 | 
174 | # Create framework-enhanced template
175 | prompt_manager create_template name="Research Analysis" category="analysis" \
176 |   description="Comprehensive research analysis using active methodology" \
177 |   content="Research {{topic}} using systematic approach. Focus on {{aspects}}." \
178 |   arguments='[{"name":"topic","required":true},{"name":"aspects","required":false}]'
179 | ```
180 | 
181 | #### Updating Prompts
182 | 
183 | ```bash
184 | # Update prompt content
185 | prompt_manager update id="data_processor" \
186 |   content="Enhanced analysis of {{data}} with focus on {{methodology}}"
187 | 
188 | # Update prompt metadata
189 | prompt_manager update id="greeting_prompt" \
190 |   name="Enhanced Greeting" \
191 |   description="Improved greeting with personalization"
192 | 
193 | # Precision section editing
194 | prompt_manager modify id="analysis_prompt" \
195 |   section="User Message Template" \
196 |   new_content="Analyze {{content}} using {{framework}} methodology"
197 | ```
198 | 
199 | #### Deleting Prompts
200 | 
201 | ```bash
202 | # Delete prompt with safety checks
203 | prompt_manager delete id="old_prompt"
204 | 
205 | # The system will warn if prompt is referenced by chains or other prompts
206 | ```
207 | 
208 | ### Advanced Features
209 | 
210 | #### Type Analysis & Migration
211 | 
212 | ```bash
213 | # Analyze existing prompt for optimization recommendations
214 | prompt_manager analyze_type id="basic_analysis"
215 | # Returns: execution type, framework suitability, improvement suggestions
216 | 
217 | # Convert prompt to framework-enhanced template
218 | prompt_manager migrate_type id="simple_prompt" target_type="template"
219 | 
220 | # Convert template back to basic prompt for speed
221 | prompt_manager migrate_type id="complex_template" target_type="prompt"
222 | ```
223 | 
224 | #### Framework Integration
225 | 
226 | ```bash
227 | # Switch to desired framework before creating templates
228 | system_control switch_framework framework="CAGEERF" reason="Complex analysis needed"
229 | 
230 | # Create framework-aware template
231 | prompt_manager create_template name="Strategic Analysis" category="business" \
232 |   description="CAGEERF-enhanced strategic analysis" \
233 |   content="Analyze {{situation}} using comprehensive structured approach"
234 | 
235 | # Templates automatically use active framework methodology
236 | ```
237 | 
238 | #### Chain Prompt Creation
239 | 
240 | ```bash
241 | # Create multi-step chain prompt
242 | prompt_manager create_template name="Research Workflow" category="research" \
243 |   description="Multi-step research and analysis workflow" \
244 |   content="Research workflow for {{topic}} with comprehensive analysis" \
245 |   chain_steps='[
246 |     {
247 |       "promptId": "data_collection",
248 |       "stepName": "Data Collection",
249 |       "inputMapping": {"topic": "research_topic"},
250 |       "outputMapping": {"collected_data": "step1_output"}
251 |     },
252 |     {
253 |       "promptId": "data_analysis",
254 |       "stepName": "Analysis",
255 |       "inputMapping": {"data": "step1_output"},
256 |       "outputMapping": {"analysis_result": "final_output"}
257 |     }
258 |   ]'
259 | ```
260 | 
261 | ### Intelligent Filtering System
262 | 
263 | The `prompt_manager list` command supports advanced filtering:
264 | 
265 | #### Filter Syntax
266 | 
267 | - **Category**: `category:analysis`, `category:development`
268 | - **Type**: `type:prompt`, `type:template`, `type:chain`
269 | - **Intent**: `intent:debugging`, `intent:analysis`, `intent:creation`
270 | - **Confidence**: `confidence:>80`, `confidence:70-90`
271 | - **Framework**: `framework:CAGEERF`, `framework:ReACT`
272 | 
273 | #### Advanced Examples
274 | 
275 | ```bash
276 | # Find high-confidence templates in analysis category
277 | prompt_manager list filter="category:analysis type:template confidence:>85"
278 | 
279 | # Find debugging-related prompts
280 | prompt_manager list filter="intent:debugging"
281 | 
282 | # Find prompts suitable for current framework
283 | system_control status  # Check active framework
284 | prompt_manager list filter="framework:CAGEERF type:template"
285 | ```
286 | 
287 | ## Advanced Templating with Nunjucks
288 | 
289 | The prompt templating system supports **Nunjucks** for dynamic prompt construction:
290 | 
291 | ### Key Features
292 | 
293 | - **Conditional Logic (`{% if %}`)**: Show/hide content based on arguments
294 | - **Loops (`{% for %}`)**: Iterate over arrays dynamically
295 | - **Standard Placeholders**: `{{variable}}` syntax continues to work
296 | - **Macros (`{% macro %}`)**: Reusable template components
297 | - **Filters (`|`)**: Transform data (upper, lower, default, etc.)
298 | 
299 | ### Template Processing
300 | 
301 | 1. **Nunjucks Rendering**: Process `{% %}` tags and `{{ }}` placeholders
302 | 2. **Text Reference Expansion**: Handle long text references (ref:xyz)
303 | 3. **Framework Enhancement**: Apply active methodology if template type
304 | 
305 | ### Examples
306 | 
307 | #### Conditional Logic
308 | 
309 | ```nunjucks
310 | {% if user_name %}
311 | Hello, {{user_name}}! Thanks for providing your name.
312 | {% else %}
313 | Hello there!
314 | {% endif %}
315 | 
316 | {% if analysis_type == "comprehensive" %}
317 | This requires detailed CAGEERF methodology analysis.
318 | {% elif analysis_type == "quick" %}
319 | Using streamlined ReACT approach.
320 | {% endif %}
321 | ```
322 | 
323 | #### Loops
324 | 
325 | ```nunjucks
326 | Please analyze the following data points:
327 | {% for item in data_list %}
328 | - {{ loop.index }}. {{ item }}
329 | {% endfor %}
330 | ```
331 | 
332 | #### Macros for Reusability
333 | 
334 | ```nunjucks
335 | {% macro analysis_section(title, content, methodology) %}
336 | ## {{ title }}
337 | **Methodology**: {{ methodology }}
338 | **Content**: {{ content }}
339 | {% endmacro %}
340 | 
341 | {{ analysis_section("Market Analysis", market_data, "CAGEERF") }}
342 | {{ analysis_section("Risk Assessment", risk_data, "5W1H") }}
343 | ```
344 | 
345 | #### Filters
346 | 
347 | ```nunjucks
348 | Topic: {{ topic_name | upper }}
349 | Priority: {{ priority_level | default("Medium") }}
350 | Items: {{ item_count | length }} total
351 | Summary: {{ long_text | truncate(100) }}
352 | ```
353 | 
354 | ## Integration with Consolidated Architecture
355 | 
356 | ### MCP Tool Coordination
357 | 
358 | ```bash
359 | # Complete workflow using all 3 tools
360 | system_control status                          # Check system state
361 | system_control switch_framework framework="CAGEERF"  # Set methodology
362 | prompt_manager create_template name="..." category="..." # Create template
363 | prompt_engine >>template_name input="data" gate_validation=true # Execute with gates
364 | system_control analytics                       # Monitor performance
365 | ```
366 | 
367 | ### Framework-Aware Operations
368 | 
369 | ```bash
370 | # Framework affects template creation and execution
371 | system_control list_frameworks                 # See available frameworks
372 | system_control switch_framework framework="ReACT" reason="Problem-solving focus"
373 | 
374 | # Templates created after switching inherit framework
375 | prompt_manager create_template name="Problem Solver" category="analysis"
376 | 
377 | # Execute with framework enhancement
378 | prompt_engine >>problem_solver issue="complex problem" execution_mode="template"
379 | ```
380 | 
381 | ### Performance Monitoring
382 | 
383 | ```bash
384 | # Monitor prompt management operations
385 | system_control analytics include_history=true
386 | # Shows: prompt creation stats, execution statistics, framework usage
387 | 
388 | # Check system health
389 | system_control health
390 | # Includes: prompt loading status, template processing health, framework integration
391 | ```
392 | 
393 | ## File Management
394 | 
395 | ### Automatic File Operations
396 | 
397 | When using `prompt_manager`, the system automatically:
398 | 
399 | 1. **Creates .md files** in appropriate category directories
400 | 2. **Updates prompts.json** in category folders
401 | 3. **Maintains file consistency** across configuration and files
402 | 4. **Triggers hot-reload** to refresh the system
403 | 
404 | ### File Structure
405 | 
406 | ```
407 | prompts/
408 | ├── analysis/
409 | │   ├── prompts.json          # Category prompt registry
410 | │   ├── content_analysis.md   # Individual prompt templates
411 | │   └── research_workflow.md
412 | ├── development/
413 | │   ├── prompts.json
414 | │   ├── code_review.md
415 | │   └── debugging_guide.md
416 | └── promptsConfig.json        # Main configuration
417 | ```
418 | 
419 | ### Generated .md File Structure
420 | 
421 | ```markdown
422 | # Prompt Name
423 | 
424 | ## Description
425 | 
426 | Prompt description explaining purpose and usage
427 | 
428 | ## System Message
429 | 
430 | Optional system message for framework enhancement
431 | 
432 | ## User Message Template
433 | 
434 | Template content with {{variables}} and Nunjucks logic
435 | 
436 | ## Arguments
437 | 
438 | - name: Description (required/optional)
439 | - focus: Analysis focus area (optional)
440 | 
441 | ## Chain Steps (for chain prompts)
442 | 
443 | 1. Step 1: Data Collection
444 | 2. Step 2: Analysis
445 | 3. Step 3: Recommendations
446 | ```
447 | 
448 | ## Troubleshooting
449 | 
450 | ### Common Issues
451 | 
452 | #### Tool Not Found Errors
453 | 
454 | - **Issue**: `create_category tool not found`
455 | - **Solution**: Use `prompt_manager` with action: `prompt_manager create_category`
456 | 
457 | #### Legacy Tool References
458 | 
459 | - **Issue**: Documentation mentions `update_prompt` standalone tool
460 | - **Solution**: Use consolidated tool: `prompt_manager update id="..." content="..."`
461 | 
462 | #### HTTP API Errors
463 | 
464 | - **Issue**: HTTP fetch examples don't work
465 | - **Solution**: MCP server uses MCP protocol only - use MCP-compatible clients
466 | 
467 | #### Framework Integration Issues
468 | 
469 | - **Issue**: Templates not getting framework enhancement
470 | - **Solution**: Verify active framework with `system_control status` and use `create_template` action
471 | 
472 | ### Debug Commands
473 | 
474 | ```bash
475 | # Check system health including prompt loading
476 | system_control health
477 | 
478 | # Verify prompt registration
479 | prompt_manager list
480 | 
481 | # Check framework integration
482 | system_control status
483 | 
484 | # View comprehensive diagnostics
485 | system_control diagnostics
486 | ```
487 | 
488 | ## Best Practices
489 | 
490 | ### Prompt Type Selection
491 | 
492 | - **Basic Prompts**: Use `create_prompt` for simple variable substitution (fastest)
493 | - **Framework Templates**: Use `create_template` for analysis, reasoning, complex tasks
494 | - **Chains**: Provide `chain_steps` array for multi-step workflows - chain status detected automatically
495 | 
496 | ### Framework Integration
497 | 
498 | - Switch to appropriate framework before creating templates
499 | - Use `analyze_type` to get recommendations for existing prompts
500 | - Use `migrate_type` to upgrade prompts for framework enhancement
501 | 
502 | ### Organization
503 | 
504 | - Group related prompts into logical categories
505 | - Use descriptive names and comprehensive descriptions
506 | - Leverage Nunjucks for maintainable, reusable templates
507 | - Test prompts with various argument combinations
508 | 
509 | ### Performance Optimization
510 | 
511 | - Use basic prompts for simple operations (bypasses framework overhead)
512 | - Use templates when methodology enhancement adds value
513 | - Monitor performance with `system_control analytics`
514 | - Consider prompt complexity vs. execution speed trade-offs
515 | 
516 | ## Advanced Workflows
517 | 
518 | ### Template Development Workflow
519 | 
520 | ```bash
521 | # 1. Analyze requirements
522 | prompt_manager analyze_type id="existing_prompt"  # If converting existing
523 | 
524 | # 2. Set appropriate framework
525 | system_control switch_framework framework="CAGEERF"
526 | 
527 | # 3. Create framework-enhanced template
528 | prompt_manager create_template name="Advanced Analysis" category="research"
529 | 
530 | # 4. Test execution with gates
531 | prompt_engine >>advanced_analysis input="test data" gate_validation=true
532 | 
533 | # 5. Monitor performance
534 | system_control analytics
535 | ```
536 | 
537 | ### Chain Development Workflow
538 | 
539 | ```bash
540 | # 1. Create individual step prompts
541 | prompt_manager create_template name="collect_data" category="research"
542 | prompt_manager create_template name="analyze_data" category="research"
543 | prompt_manager create_template name="generate_insights" category="research"
544 | 
545 | # 2. Create chain prompt linking steps
546 | prompt_manager create_template name="research_pipeline" category="research" \
547 |   chain_steps='[{"promptId":"collect_data","stepName":"Collection"}, {"promptId":"analyze_data","stepName":"Analysis"}]'
548 | 
549 | # 3. Execute complete chain with LLM coordination (requires semantic LLM integration)
550 | prompt_engine >>research_pipeline topic="market analysis" llm_driven_execution=true
551 | 
552 | # 4. Monitor chain execution
553 | system_control status  # Check execution state
554 | ```
555 | 
556 | ## Migration from Legacy Tools
557 | 
558 | If you have references to old tool names:
559 | 
560 | | Legacy Tool             | Consolidated Usage                  |
561 | | ----------------------- | ----------------------------------- |
562 | | `create_category`       | `prompt_manager create_category`    |
563 | | `update_prompt`         | `prompt_manager create` or `update` |
564 | | `delete_prompt`         | `prompt_manager delete`             |
565 | | `modify_prompt_section` | `prompt_manager modify`             |
566 | | `reload_prompts`        | `prompt_manager reload`             |
567 | | `listprompts`           | `prompt_manager list`               |
568 | 
569 | **Key Changes:**
570 | 
571 | - **No HTTP API**: Use MCP protocol through compatible clients
572 | - **Action-Based**: Single tools with actions instead of separate tools
573 | - **Enhanced Features**: Type analysis, framework integration, intelligent filtering
574 | - **Consolidated**: 3 tools instead of 24+ legacy tools
575 | 
576 | ---
577 | 
578 | The consolidated prompt management system provides sophisticated prompt lifecycle management while maintaining simplicity and performance. The `prompt_manager` tool offers comprehensive capabilities from basic CRUD operations to advanced features like type analysis, framework integration, and intelligent filtering, all within the efficient 3-tool consolidated architecture.
579 | 
```

--------------------------------------------------------------------------------
/plans/outputschema-realtime-progress-and-validation.md:
--------------------------------------------------------------------------------

```markdown
  1 | # OutputSchema Real-Time Progress & Gate Validation Implementation Plan
  2 | 
  3 | ## Overview
  4 | 
  5 | This plan integrates real-time progress tracking with visual gate validation to create a comprehensive user experience for chain executions and quality gate monitoring. The implementation builds upon the current Option 2 (Minimal Compliance) foundation while adding progressive enhancement capabilities for modern MCP clients.
  6 | 
  7 | ## Core Feature Integration
  8 | 
  9 | ### 1. Real-Time Progress Tracking
 10 | 
 11 | #### Chain Execution Progress
 12 | - **Live Progress Bars**: Visual percentage indicators for overall chain completion
 13 | - **Step-by-Step Status**: Individual step progress with state transitions (pending → running → completed/failed)
 14 | - **Time Analytics**: Real-time ETA calculations based on historical execution patterns
 15 | - **Performance Metrics**: Live memory usage, CPU utilization, and execution speed tracking
 16 | - **Multi-Chain Monitoring**: Concurrent chain execution progress with session isolation
 17 | 
 18 | #### Progress Data Structure
 19 | ```typescript
 20 | interface RealTimeChainProgress extends ChainProgress {
 21 |   // Enhanced progress tracking
 22 |   progressPercentage: number;           // 0-100 overall completion
 23 |   estimatedTimeRemaining: number;       // ETA in milliseconds
 24 |   currentStepProgress: number;          // 0-100 current step completion
 25 | 
 26 |   // Performance metrics
 27 |   performanceMetrics: {
 28 |     memoryUsage: NodeJS.MemoryUsage;
 29 |     executionSpeed: number;             // steps per second
 30 |     resourceUtilization: number;        // 0-1 CPU/memory usage
 31 |   };
 32 | 
 33 |   // Historical context
 34 |   averageStepTime: number;             // milliseconds
 35 |   slowestStepId?: string;
 36 |   fastestStepId?: string;
 37 | }
 38 | ```
 39 | 
 40 | ### 2. Visual Gate Validation
 41 | 
 42 | #### Interactive Validation Display
 43 | - **Real-Time Gate Status**: Live indicators showing gate evaluation progress
 44 | - **Quality Score Visualization**: Graphical representation of validation scores (0-1 range)
 45 | - **Detailed Failure Analysis**: Structured explanations with actionable recommendations
 46 | - **Retry Mechanism Integration**: Visual retry controls with attempt tracking
 47 | - **Validation History**: Historical gate performance with trend analysis
 48 | 
 49 | #### Gate Validation Data Structure
 50 | ```typescript
 51 | interface VisualGateValidation extends GateValidationResult {
 52 |   // Enhanced validation tracking
 53 |   validationProgress: number;          // 0-100 validation completion
 54 |   currentGateIndex: number;            // Which gate is being evaluated
 55 | 
 56 |   // Visual representation data
 57 |   gateStatusMap: Map<string, {
 58 |     status: 'pending' | 'running' | 'passed' | 'failed';
 59 |     score?: number;
 60 |     progressPercentage: number;
 61 |     startTime: number;
 62 |     estimatedCompletion?: number;
 63 |   }>;
 64 | 
 65 |   // Retry mechanism
 66 |   retryAttempts: Array<{
 67 |     attemptNumber: number;
 68 |     timestamp: number;
 69 |     result: 'passed' | 'failed' | 'timeout';
 70 |     improvedGates: string[];           // Gates that passed after retry
 71 |   }>;
 72 | 
 73 |   // User actionable data
 74 |   recommendations: Array<{
 75 |     gateId: string;
 76 |     priority: 'high' | 'medium' | 'low';
 77 |     actionType: 'retry' | 'modify' | 'skip' | 'review';
 78 |     description: string;
 79 |     estimatedFixTime?: number;
 80 |   }>;
 81 | }
 82 | ```
 83 | 
 84 | ## Technical Implementation Strategy
 85 | 
 86 | ### Phase 1: Schema Enhancement (Week 1)
 87 | 
 88 | #### Enhanced OutputSchema Definitions
 89 | ```typescript
 90 | // Extend existing chainProgressSchema
 91 | export const enhancedChainProgressSchema = chainProgressSchema.extend({
 92 |   progressPercentage: z.number().min(0).max(100),
 93 |   estimatedTimeRemaining: z.number().optional(),
 94 |   currentStepProgress: z.number().min(0).max(100),
 95 |   performanceMetrics: z.object({
 96 |     memoryUsage: z.object({
 97 |       heapUsed: z.number(),
 98 |       heapTotal: z.number(),
 99 |       external: z.number()
100 |     }),
101 |     executionSpeed: z.number(),
102 |     resourceUtilization: z.number().min(0).max(1)
103 |   }),
104 |   averageStepTime: z.number(),
105 |   slowestStepId: z.string().optional(),
106 |   fastestStepId: z.string().optional()
107 | });
108 | 
109 | // Enhanced gate validation schema
110 | export const visualGateValidationSchema = gateValidationSchema.extend({
111 |   validationProgress: z.number().min(0).max(100),
112 |   currentGateIndex: z.number(),
113 |   gateStatusMap: z.record(z.object({
114 |     status: z.enum(['pending', 'running', 'passed', 'failed']),
115 |     score: z.number().optional(),
116 |     progressPercentage: z.number().min(0).max(100),
117 |     startTime: z.number(),
118 |     estimatedCompletion: z.number().optional()
119 |   })),
120 |   retryAttempts: z.array(z.object({
121 |     attemptNumber: z.number(),
122 |     timestamp: z.number(),
123 |     result: z.enum(['passed', 'failed', 'timeout']),
124 |     improvedGates: z.array(z.string())
125 |   })),
126 |   recommendations: z.array(z.object({
127 |     gateId: z.string(),
128 |     priority: z.enum(['high', 'medium', 'low']),
129 |     actionType: z.enum(['retry', 'modify', 'skip', 'review']),
130 |     description: z.string(),
131 |     estimatedFixTime: z.number().optional()
132 |   }))
133 | });
134 | ```
135 | 
136 | #### Integration Points
137 | - **ChainSessionManager**: Add progress tracking hooks to existing session management
138 | - **GateEvaluator**: Enhance gate evaluation with progress callbacks
139 | - **FrameworkStateManager**: Add performance metrics collection
140 | - **ResponseFormatter**: Extend formatters to handle enhanced schemas
141 | 
142 | ### Phase 2: Real-Time Infrastructure (Week 2)
143 | 
144 | #### SSE Event Streaming
145 | ```typescript
146 | // New progress event types
147 | export enum ProgressEventType {
148 |   CHAIN_STARTED = 'chain:started',
149 |   CHAIN_PROGRESS = 'chain:progress',
150 |   STEP_STARTED = 'step:started',
151 |   STEP_COMPLETED = 'step:completed',
152 |   GATE_VALIDATION_STARTED = 'gate:validation:started',
153 |   GATE_VALIDATION_PROGRESS = 'gate:validation:progress',
154 |   GATE_VALIDATION_COMPLETED = 'gate:validation:completed',
155 |   EXECUTION_METRICS = 'execution:metrics'
156 | }
157 | 
158 | // Progress event streaming service
159 | export class ProgressEventStreamer {
160 |   private sseConnections: Map<string, Response> = new Map();
161 | 
162 |   broadcast(eventType: ProgressEventType, data: any): void {
163 |     const event = {
164 |       type: eventType,
165 |       timestamp: Date.now(),
166 |       data
167 |     };
168 | 
169 |     this.sseConnections.forEach((response, clientId) => {
170 |       response.write(`data: ${JSON.stringify(event)}\n\n`);
171 |     });
172 |   }
173 | 
174 |   addClient(clientId: string, response: Response): void {
175 |     response.writeHead(200, {
176 |       'Content-Type': 'text/event-stream',
177 |       'Cache-Control': 'no-cache',
178 |       'Connection': 'keep-alive'
179 |     });
180 | 
181 |     this.sseConnections.set(clientId, response);
182 |   }
183 | }
184 | ```
185 | 
186 | #### Chain Execution Integration
187 | ```typescript
188 | // Enhanced ChainOrchestrator with progress tracking
189 | export class EnhancedChainOrchestrator extends ChainOrchestrator {
190 |   private progressStreamer: ProgressEventStreamer;
191 | 
192 |   async executeStep(
193 |     session: ChainExecutionSession,
194 |     stepId: string
195 |   ): Promise<StepExecutionResult> {
196 |     // Emit step start event
197 |     this.progressStreamer.broadcast(ProgressEventType.STEP_STARTED, {
198 |       sessionId: session.sessionId,
199 |       stepId,
200 |       stepName: session.chainDefinition.steps[stepId]?.name,
201 |       progressPercentage: this.calculateOverallProgress(session, stepId)
202 |     });
203 | 
204 |     // Execute step with performance monitoring
205 |     const startTime = Date.now();
206 |     const startMemory = process.memoryUsage();
207 | 
208 |     const result = await super.executeStep(session, stepId);
209 | 
210 |     // Calculate performance metrics
211 |     const executionTime = Date.now() - startTime;
212 |     const endMemory = process.memoryUsage();
213 |     const memoryDelta = endMemory.heapUsed - startMemory.heapUsed;
214 | 
215 |     // Emit progress update
216 |     this.progressStreamer.broadcast(ProgressEventType.CHAIN_PROGRESS, {
217 |       sessionId: session.sessionId,
218 |       currentStep: stepId,
219 |       progressPercentage: this.calculateOverallProgress(session, stepId),
220 |       estimatedTimeRemaining: this.calculateETA(session, stepId),
221 |       performanceMetrics: {
222 |         stepExecutionTime: executionTime,
223 |         memoryDelta,
224 |         currentMemoryUsage: endMemory
225 |       }
226 |     });
227 | 
228 |     return result;
229 |   }
230 | }
231 | ```
232 | 
233 | ### Phase 3: Gate Validation Enhancement (Week 3)
234 | 
235 | #### Enhanced Gate Evaluation
236 | ```typescript
237 | export class VisualGateEvaluator extends BaseGateEvaluator {
238 |   private progressStreamer: ProgressEventStreamer;
239 | 
240 |   async evaluateGates(
241 |     content: string,
242 |     gates: GateDefinition[],
243 |     context: EvaluationContext
244 |   ): Promise<VisualGateValidation> {
245 |     const sessionId = context.sessionId || 'anonymous';
246 | 
247 |     // Initialize gate status map
248 |     const gateStatusMap = new Map();
249 |     gates.forEach((gate, index) => {
250 |       gateStatusMap.set(gate.id, {
251 |         status: 'pending',
252 |         progressPercentage: 0,
253 |         startTime: 0
254 |       });
255 |     });
256 | 
257 |     // Emit validation start event
258 |     this.progressStreamer.broadcast(ProgressEventType.GATE_VALIDATION_STARTED, {
259 |       sessionId,
260 |       totalGates: gates.length,
261 |       gateStatusMap: Object.fromEntries(gateStatusMap)
262 |     });
263 | 
264 |     const results: GateEvaluationResult[] = [];
265 |     const retryAttempts: Array<any> = [];
266 | 
267 |     for (let i = 0; i < gates.length; i++) {
268 |       const gate = gates[i];
269 | 
270 |       // Update gate status to running
271 |       gateStatusMap.set(gate.id, {
272 |         status: 'running',
273 |         progressPercentage: 0,
274 |         startTime: Date.now()
275 |       });
276 | 
277 |       // Emit progress update
278 |       this.progressStreamer.broadcast(ProgressEventType.GATE_VALIDATION_PROGRESS, {
279 |         sessionId,
280 |         currentGateIndex: i,
281 |         currentGateId: gate.id,
282 |         overallProgress: (i / gates.length) * 100,
283 |         gateStatusMap: Object.fromEntries(gateStatusMap)
284 |       });
285 | 
286 |       // Evaluate gate with progress callbacks
287 |       const result = await this.evaluateGateWithProgress(gate, content, context, (progress) => {
288 |         gateStatusMap.set(gate.id, {
289 |           status: 'running',
290 |           progressPercentage: progress,
291 |           startTime: gateStatusMap.get(gate.id)!.startTime
292 |         });
293 | 
294 |         this.progressStreamer.broadcast(ProgressEventType.GATE_VALIDATION_PROGRESS, {
295 |           sessionId,
296 |           currentGateIndex: i,
297 |           currentGateId: gate.id,
298 |           currentGateProgress: progress,
299 |           overallProgress: ((i + progress/100) / gates.length) * 100,
300 |           gateStatusMap: Object.fromEntries(gateStatusMap)
301 |         });
302 |       });
303 | 
304 |       // Update final status
305 |       gateStatusMap.set(gate.id, {
306 |         status: result.passed ? 'passed' : 'failed',
307 |         progressPercentage: 100,
308 |         startTime: gateStatusMap.get(gate.id)!.startTime,
309 |         score: result.score
310 |       });
311 | 
312 |       results.push(result);
313 | 
314 |       // Handle retry logic if gate failed
315 |       if (!result.passed && gate.allowRetry) {
316 |         const retryResult = await this.handleGateRetry(gate, content, context, retryAttempts);
317 |         if (retryResult) {
318 |           gateStatusMap.set(gate.id, {
319 |             status: 'passed',
320 |             progressPercentage: 100,
321 |             startTime: gateStatusMap.get(gate.id)!.startTime,
322 |             score: retryResult.score
323 |           });
324 |           results[results.length - 1] = retryResult;
325 |         }
326 |       }
327 |     }
328 | 
329 |     // Generate recommendations
330 |     const recommendations = this.generateActionableRecommendations(results, gates);
331 | 
332 |     // Emit final validation complete event
333 |     this.progressStreamer.broadcast(ProgressEventType.GATE_VALIDATION_COMPLETED, {
334 |       sessionId,
335 |       overallResult: results.every(r => r.passed),
336 |       totalTime: Date.now() - (gateStatusMap.values().next().value?.startTime || 0),
337 |       recommendations
338 |     });
339 | 
340 |     return {
341 |       ...this.consolidateResults(results),
342 |       validationProgress: 100,
343 |       currentGateIndex: gates.length - 1,
344 |       gateStatusMap: Object.fromEntries(gateStatusMap),
345 |       retryAttempts,
346 |       recommendations
347 |     };
348 |   }
349 | }
350 | ```
351 | 
352 | ### Phase 4: Client Integration (Week 4)
353 | 
354 | #### WebUI Components
355 | ```typescript
356 | // React component for chain progress visualization
357 | export const ChainProgressTracker: React.FC<{
358 |   sessionId: string;
359 |   onComplete?: (result: ChainExecutionResult) => void;
360 | }> = ({ sessionId, onComplete }) => {
361 |   const [progress, setProgress] = useState<RealTimeChainProgress | null>(null);
362 |   const [gateValidation, setGateValidation] = useState<VisualGateValidation | null>(null);
363 | 
364 |   useEffect(() => {
365 |     // Connect to SSE stream
366 |     const eventSource = new EventSource(`/api/progress/stream/${sessionId}`);
367 | 
368 |     eventSource.addEventListener('chain:progress', (event) => {
369 |       const data = JSON.parse(event.data);
370 |       setProgress(data);
371 |     });
372 | 
373 |     eventSource.addEventListener('gate:validation:progress', (event) => {
374 |       const data = JSON.parse(event.data);
375 |       setGateValidation(data);
376 |     });
377 | 
378 |     return () => eventSource.close();
379 |   }, [sessionId]);
380 | 
381 |   return (
382 |     <div className="chain-progress-tracker">
383 |       <ChainProgressBar progress={progress} />
384 |       <StepStatusIndicators steps={progress?.steps || []} />
385 |       <GateValidationDisplay validation={gateValidation} />
386 |       <PerformanceMetrics metrics={progress?.performanceMetrics} />
387 |     </div>
388 |   );
389 | };
390 | ```
391 | 
392 | #### MCP Client Integration
393 | ```typescript
394 | // Enhanced MCP client with progress tracking
395 | export class ProgressAwareMCPClient extends MCPClient {
396 |   private progressCallbacks: Map<string, (progress: any) => void> = new Map();
397 | 
398 |   async executeChainWithProgress(
399 |     chainId: string,
400 |     args: any,
401 |     onProgress?: (progress: RealTimeChainProgress) => void,
402 |     onGateValidation?: (validation: VisualGateValidation) => void
403 |   ): Promise<ToolResponse> {
404 |     const sessionId = generateSessionId();
405 | 
406 |     // Register progress callbacks
407 |     if (onProgress) {
408 |       this.progressCallbacks.set(`${sessionId}:progress`, onProgress);
409 |     }
410 |     if (onGateValidation) {
411 |       this.progressCallbacks.set(`${sessionId}:gate`, onGateValidation);
412 |     }
413 | 
414 |     // Execute chain with enhanced response parsing
415 |     const response = await this.callTool('prompt_engine', {
416 |       command: `>>${chainId}`,
417 |       ...args,
418 |       sessionOptions: {
419 |         sessionId,
420 |         trackProgress: true,
421 |         enableGateVisualization: true
422 |       }
423 |     });
424 | 
425 |     // Parse structured content for progress data
426 |     if (response.structuredContent?.chainProgress) {
427 |       onProgress?.(response.structuredContent.chainProgress);
428 |     }
429 | 
430 |     if (response.structuredContent?.gateValidation) {
431 |       onGateValidation?.(response.structuredContent.gateValidation);
432 |     }
433 | 
434 |     return response;
435 |   }
436 | }
437 | ```
438 | 
439 | ### Phase 5: Backward Compatibility & Progressive Enhancement
440 | 
441 | #### Compatibility Strategy
442 | ```typescript
443 | // Feature detection and graceful degradation
444 | export class ProgressCompatibilityLayer {
445 |   static detectClientCapabilities(request: Request): ClientCapabilities {
446 |     const userAgent = request.headers['user-agent'] || '';
447 |     const acceptHeader = request.headers.accept || '';
448 | 
449 |     return {
450 |       supportsSSE: acceptHeader.includes('text/event-stream'),
451 |       supportsStructuredOutput: request.headers['x-mcp-structured'] === 'true',
452 |       supportsProgressTracking: request.headers['x-progress-tracking'] === 'true',
453 |       clientType: this.identifyClientType(userAgent)
454 |     };
455 |   }
456 | 
457 |   static adaptResponse(
458 |     response: ToolResponse,
459 |     capabilities: ClientCapabilities
460 |   ): ToolResponse {
461 |     if (!capabilities.supportsStructuredOutput) {
462 |       // Return Option 2 minimal compliance response
463 |       return {
464 |         content: response.content,
465 |         isError: response.isError
466 |       };
467 |     }
468 | 
469 |     if (!capabilities.supportsProgressTracking) {
470 |       // Remove progress-specific structured data
471 |       const { chainProgress, gateValidation, ...otherData } = response.structuredContent || {};
472 |       return {
473 |         ...response,
474 |         structuredContent: otherData
475 |       };
476 |     }
477 | 
478 |     return response; // Full enhanced response
479 |   }
480 | }
481 | ```
482 | 
483 | ## Implementation Benefits
484 | 
485 | ### User Experience Enhancement
486 | - **Visual Feedback**: Clear progress indicators reduce uncertainty during long-running operations
487 | - **Error Understanding**: Detailed gate validation results help users understand and fix issues
488 | - **Performance Insights**: Real-time metrics help users optimize their chains and prompts
489 | - **Professional Interface**: Modern UI components suitable for enterprise environments
490 | 
491 | ### Developer Benefits
492 | - **Debugging Capabilities**: Detailed progress tracking aids in identifying bottlenecks
493 | - **Performance Optimization**: Real-time metrics enable performance tuning
494 | - **Quality Assurance**: Enhanced gate validation improves output quality
495 | - **Extensibility**: Modular design allows easy addition of new progress types
496 | 
497 | ### System Integration
498 | - **Backward Compatible**: Maintains Option 2 minimal compliance as foundation
499 | - **Progressive Enhancement**: Advanced features only activate for capable clients
500 | - **Scalable Architecture**: Event-driven design supports multiple concurrent clients
501 | - **Future-Proof**: Extensible schema design accommodates future enhancements
502 | 
503 | ## Success Metrics
504 | 
505 | ### Technical Metrics
506 | - **Performance Impact**: < 5% overhead for progress tracking
507 | - **Memory Usage**: < 10MB additional memory for progress state
508 | - **Response Time**: < 100ms additional latency for enhanced responses
509 | - **Compatibility**: 100% backward compatibility maintained
510 | 
511 | ### User Experience Metrics
512 | - **Progress Clarity**: Users report clear understanding of execution status
513 | - **Error Resolution**: Reduced time to fix gate validation failures
514 | - **Perceived Performance**: Improved user satisfaction with long-running operations
515 | - **Adoption Rate**: Percentage of clients utilizing enhanced features
516 | 
517 | ## Risk Mitigation
518 | 
519 | ### Performance Risks
520 | - **Mitigation**: Configurable progress granularity (can reduce update frequency)
521 | - **Monitoring**: Real-time performance impact measurement
522 | - **Fallback**: Automatic degradation to minimal compliance if performance degrades
523 | 
524 | ### Compatibility Risks
525 | - **Mitigation**: Comprehensive client capability detection
526 | - **Testing**: Automated testing with various client types
527 | - **Documentation**: Clear migration guides for client implementations
528 | 
529 | ### Implementation Complexity
530 | - **Mitigation**: Phased rollout with incremental feature addition
531 | - **Testing**: Extensive integration testing at each phase
532 | - **Documentation**: Detailed implementation guides and examples
533 | 
534 | This implementation plan provides a comprehensive foundation for real-time progress tracking and visual gate validation while maintaining the stability and compatibility of the existing system.
```

--------------------------------------------------------------------------------
/server/tests/scripts/integration-server-startup.js:
--------------------------------------------------------------------------------

```javascript
  1 | #!/usr/bin/env node
  2 | /**
  3 |  * Server Startup Integration Tests - Node.js Script Version
  4 |  * Tests extracted from GitHub Actions inline scripts
  5 |  */
  6 | 
  7 | async function runServerStartupIntegrationTests() {
  8 |   // Global timeout for entire test suite
  9 |   const globalTimeout = setTimeout(() => {
 10 |     console.error('❌ Integration tests timed out after 2 minutes - forcing exit');
 11 |     console.log('💀 Global timeout triggered - forcing immediate process exit...');
 12 |     process.exit(1);
 13 |   }, 120000); // 2 minutes
 14 | 
 15 |   try {
 16 |     console.log('🧪 Running Server Startup Integration tests...');
 17 |     console.log('📋 Testing full server initialization sequence and error recovery');
 18 | 
 19 |     // Import modules
 20 |     const { Application } = await import('../../dist/runtime/application.js');
 21 |     const { createSimpleLogger } = await import('../../dist/logging/index.js');
 22 |     const { globalResourceTracker } = await import('../../dist/utils/global-resource-tracker.js');
 23 | 
 24 |     let logger, orchestrator;
 25 | 
 26 |     // Timeout wrapper for individual operations
 27 |     async function runWithTimeout(operation, timeoutMs = 10000, operationName = 'operation') {
 28 |       return Promise.race([
 29 |         operation(),
 30 |         new Promise((_, reject) =>
 31 |           setTimeout(() => reject(new Error(`${operationName} timed out after ${timeoutMs}ms`)), timeoutMs)
 32 |         )
 33 |       ]);
 34 |     }
 35 | 
 36 |     // Setup for each test - reuse orchestrator to prevent multiple full startups
 37 |     function setupTest() {
 38 |       if (!logger) {
 39 |         logger = createSimpleLogger();
 40 |       }
 41 |       if (!orchestrator) {
 42 |         orchestrator = new Application(logger);
 43 |       }
 44 |       return orchestrator;
 45 |     }
 46 | 
 47 |     // Simple assertion helpers
 48 |     function assertEqual(actual, expected, testName) {
 49 |       const actualStr = JSON.stringify(actual);
 50 |       const expectedStr = JSON.stringify(expected);
 51 |       if (actualStr === expectedStr) {
 52 |         console.log(`✅ ${testName}: PASSED`);
 53 |         return true;
 54 |       } else {
 55 |         console.error(`❌ ${testName}: FAILED`);
 56 |         console.error(`   Expected: ${expectedStr}`);
 57 |         console.error(`   Actual:   ${actualStr}`);
 58 |         return false;
 59 |       }
 60 |     }
 61 | 
 62 |     function assertTruthy(value, testName) {
 63 |       if (value) {
 64 |         console.log(`✅ ${testName}: PASSED`);
 65 |         return true;
 66 |       } else {
 67 |         console.error(`❌ ${testName}: FAILED - Expected truthy value, got: ${value}`);
 68 |         return false;
 69 |       }
 70 |     }
 71 | 
 72 |     function assertType(value, expectedType, testName) {
 73 |       if (typeof value === expectedType) {
 74 |         console.log(`✅ ${testName}: PASSED`);
 75 |         return true;
 76 |       } else {
 77 |         console.error(`❌ ${testName}: FAILED - Expected type ${expectedType}, got: ${typeof value}`);
 78 |         return false;
 79 |       }
 80 |     }
 81 | 
 82 |     function assertHasProperty(obj, property, testName) {
 83 |       if (obj && typeof obj === 'object' && property in obj) {
 84 |         console.log(`✅ ${testName}: PASSED`);
 85 |         return true;
 86 |       } else {
 87 |         console.error(`❌ ${testName}: FAILED - Object does not have property: ${property}`);
 88 |         return false;
 89 |       }
 90 |     }
 91 | 
 92 |     function assertGreaterThan(actual, expected, testName) {
 93 |       if (actual > expected) {
 94 |         console.log(`✅ ${testName}: PASSED (${actual} > ${expected})`);
 95 |         return true;
 96 |       } else {
 97 |         console.error(`❌ ${testName}: FAILED (${actual} <= ${expected})`);
 98 |         return false;
 99 |       }
100 |     }
101 | 
102 |     function assertGreaterThanOrEqual(actual, expected, testName) {
103 |       if (actual >= expected) {
104 |         console.log(`✅ ${testName}: PASSED (${actual} >= ${expected})`);
105 |         return true;
106 |       } else {
107 |         console.error(`❌ ${testName}: FAILED (${actual} < ${expected})`);
108 |         return false;
109 |       }
110 |     }
111 | 
112 |     function assertLessThan(actual, expected, testName) {
113 |       if (actual < expected) {
114 |         console.log(`✅ ${testName}: PASSED (${actual} < ${expected})`);
115 |         return true;
116 |       } else {
117 |         console.error(`❌ ${testName}: FAILED (${actual} >= ${expected})`);
118 |         return false;
119 |       }
120 |     }
121 | 
122 |     function assertIsArray(value, testName) {
123 |       if (Array.isArray(value)) {
124 |         console.log(`✅ ${testName}: PASSED`);
125 |         return true;
126 |       } else {
127 |         console.error(`❌ ${testName}: FAILED - Expected array, got: ${typeof value}`);
128 |         return false;
129 |       }
130 |     }
131 | 
132 |     let testResults = [];
133 | 
134 |     // Test 1: Full Server Initialization Sequence
135 |     console.log('🔍 Test 1: Full Server Initialization Sequence');
136 | 
137 |     setupTest();
138 | 
139 |     try {
140 |       // Step 1: Load Configuration
141 |       await runWithTimeout(() => orchestrator.loadConfiguration(), 5000, 'Configuration loading');
142 |       testResults.push(assertTruthy(orchestrator.config, 'Configuration loaded'));
143 |       testResults.push(assertTruthy(orchestrator.config !== null, 'Configuration not null'));
144 | 
145 |       // Step 2: Load Prompts Data
146 |       await runWithTimeout(() => orchestrator.loadPromptsData(), 10000, 'Prompts data loading');
147 |       const promptsCount = orchestrator.promptsData ? orchestrator.promptsData.length : 0;
148 |       testResults.push(assertGreaterThanOrEqual(promptsCount, 0, 'Prompts data loaded or initialized'));
149 | 
150 |       // Step 3: Initialize Modules
151 |       await runWithTimeout(() => orchestrator.initializeModules(), 8000, 'Module initialization');
152 |       testResults.push(assertTruthy(orchestrator.mcpToolsManager, 'MCP tools manager initialized'));
153 |       testResults.push(assertTruthy(orchestrator.mcpToolsManager !== null, 'MCP tools manager not null'));
154 | 
155 |       // Step 4: Get Diagnostic Info
156 |       const healthInfo = await runWithTimeout(() => orchestrator.getDiagnosticInfo(), 3000, 'Diagnostic info retrieval');
157 |       testResults.push(assertTruthy(healthInfo, 'Health info retrieved'));
158 |       testResults.push(assertType(healthInfo, 'object', 'Health info is object'));
159 |       testResults.push(assertGreaterThan(Object.keys(healthInfo).length, 0, 'Health info has properties'));
160 | 
161 |     } catch (error) {
162 |       console.error(`❌ Full initialization sequence failed: ${error.message}`);
163 |       testResults.push(false);
164 |     }
165 | 
166 |     // Test 2: Configuration Loading
167 |     console.log('🔍 Test 2: Configuration Loading');
168 | 
169 |     // Reuse the already configured orchestrator from Test 1
170 |     try {
171 |       // Configuration already loaded in Test 1, just verify it exists
172 | 
173 |       testResults.push(assertTruthy(orchestrator.config, 'Configuration object exists'));
174 |       testResults.push(assertHasProperty(orchestrator.config, 'server', 'Config has server property'));
175 | 
176 |       if (orchestrator.config && orchestrator.config.server) {
177 |         testResults.push(assertHasProperty(orchestrator.config.server, 'name', 'Server config has name'));
178 |         testResults.push(assertHasProperty(orchestrator.config.server, 'version', 'Server config has version'));
179 |         testResults.push(assertType(orchestrator.config.server.name, 'string', 'Server name is string'));
180 |         testResults.push(assertGreaterThan(orchestrator.config.server.name.length, 0, 'Server name not empty'));
181 |       } else {
182 |         testResults.push(false);
183 |         testResults.push(false);
184 |         testResults.push(false);
185 |         testResults.push(false);
186 |       }
187 |     } catch (error) {
188 |       console.error(`❌ Configuration loading failed: ${error.message}`);
189 |       testResults.push(false);
190 |       testResults.push(false);
191 |       testResults.push(false);
192 |       testResults.push(false);
193 |       testResults.push(false);
194 |       testResults.push(false);
195 |     }
196 | 
197 |     // Test 3: Prompts Data Loading
198 |     console.log('🔍 Test 3: Prompts Data Loading');
199 | 
200 |     // Reuse the already initialized orchestrator from Test 1
201 |     try {
202 |       // Prompts data already loaded in Test 1, just verify it exists
203 | 
204 |       testResults.push(assertTruthy(orchestrator.promptsData !== undefined, 'Prompts data property exists'));
205 | 
206 |       const promptsDataIsValid = Array.isArray(orchestrator.promptsData) || orchestrator.promptsData === null;
207 |       testResults.push(assertTruthy(promptsDataIsValid, 'Prompts data is array or null'));
208 | 
209 |       if (orchestrator.promptsData && orchestrator.promptsData.length > 0) {
210 |         const firstPrompt = orchestrator.promptsData[0];
211 |         testResults.push(assertHasProperty(firstPrompt, 'id', 'First prompt has id'));
212 |         testResults.push(assertHasProperty(firstPrompt, 'name', 'First prompt has name'));
213 |       } else {
214 |         // If no prompts, that's still valid
215 |         testResults.push(assertTruthy(true, 'Empty prompts handled gracefully'));
216 |         testResults.push(assertTruthy(true, 'Empty prompts handled gracefully'));
217 |       }
218 |     } catch (error) {
219 |       console.error(`❌ Prompts data loading failed: ${error.message}`);
220 |       testResults.push(false);
221 |       testResults.push(false);
222 |       testResults.push(false);
223 |       testResults.push(false);
224 |     }
225 | 
226 |     // Test 4: Module Initialization
227 |     console.log('🔍 Test 4: Module Initialization');
228 | 
229 |     // Reuse the already initialized orchestrator from Test 1
230 |     try {
231 |       // Modules already initialized in Test 1, just verify they exist
232 | 
233 |       testResults.push(assertTruthy(orchestrator.mcpToolsManager, 'MCP tools manager initialized'));
234 |       testResults.push(assertTruthy(orchestrator.mcpToolsManager !== null, 'MCP tools manager not null'));
235 |     } catch (error) {
236 |       console.error(`❌ Module initialization failed: ${error.message}`);
237 |       testResults.push(false);
238 |       testResults.push(false);
239 |     }
240 | 
241 |     // Test 5: Health Diagnostics
242 |     console.log('🔍 Test 5: Health Diagnostics');
243 | 
244 |     // Reuse the already initialized orchestrator from Test 1
245 |     try {
246 |       // Get fresh diagnostic info from the already initialized orchestrator
247 |       const healthInfo = await runWithTimeout(() => orchestrator.getDiagnosticInfo(), 3000, 'Health diagnostics');
248 | 
249 |       testResults.push(assertTruthy(healthInfo, 'Health info exists'));
250 |       testResults.push(assertType(healthInfo, 'object', 'Health info is object'));
251 | 
252 |       const diagnosticKeys = Object.keys(healthInfo);
253 |       testResults.push(assertGreaterThan(diagnosticKeys.length, 0, 'Health info has diagnostic keys'));
254 | 
255 |       const hasRelevantKeys = diagnosticKeys.some(key =>
256 |         key.includes('status') ||
257 |         key.includes('config') ||
258 |         key.includes('prompts') ||
259 |         key.includes('tools')
260 |       );
261 |       testResults.push(assertTruthy(hasRelevantKeys, 'Health info contains relevant diagnostic keys'));
262 | 
263 |       // Test partial initialization health info
264 |       const partialOrchestrator = new Application(logger);
265 |       await partialOrchestrator.loadConfiguration();
266 | 
267 |       const partialHealthInfo = await partialOrchestrator.getDiagnosticInfo();
268 |       testResults.push(assertTruthy(partialHealthInfo, 'Partial health info exists'));
269 |       testResults.push(assertType(partialHealthInfo, 'object', 'Partial health info is object'));
270 | 
271 |       // Clean up partial orchestrator
272 |       try {
273 |         await partialOrchestrator.shutdown();
274 |         partialOrchestrator.cleanup();
275 |       } catch (error) {
276 |         console.warn('⚠️ Warning: Error cleaning up partialOrchestrator:', error.message);
277 |       }
278 | 
279 |     } catch (error) {
280 |       console.error(`❌ Health diagnostics failed: ${error.message}`);
281 |       testResults.push(false);
282 |       testResults.push(false);
283 |       testResults.push(false);
284 |       testResults.push(false);
285 |       testResults.push(false);
286 |       testResults.push(false);
287 |     }
288 | 
289 |     // Test 6: Error Recovery
290 |     console.log('🔍 Test 6: Error Recovery');
291 | 
292 |     try {
293 |       // Test configuration loading errors
294 |       const failingOrchestrator = new Application(logger);
295 | 
296 |       const originalLoadConfig = failingOrchestrator.loadConfiguration;
297 |       failingOrchestrator.loadConfiguration = async () => {
298 |         throw new Error('Mock config error');
299 |       };
300 | 
301 |       let configErrorThrown = false;
302 |       try {
303 |         await failingOrchestrator.loadConfiguration();
304 |       } catch (error) {
305 |         if (error.message === 'Mock config error') {
306 |           configErrorThrown = true;
307 |         }
308 |       }
309 | 
310 |       testResults.push(assertTruthy(configErrorThrown, 'Configuration loading error handled'));
311 |       testResults.push(assertTruthy(failingOrchestrator.config === undefined, 'Config remains undefined after error'));
312 | 
313 |       // Test module initialization errors
314 |       const moduleFailOrchestrator = new Application(logger);
315 |       await moduleFailOrchestrator.loadConfiguration();
316 |       await moduleFailOrchestrator.loadPromptsData();
317 | 
318 |       moduleFailOrchestrator.initializeModules = async () => {
319 |         throw new Error('Mock module error');
320 |       };
321 | 
322 |       let moduleErrorThrown = false;
323 |       try {
324 |         await moduleFailOrchestrator.initializeModules();
325 |       } catch (error) {
326 |         if (error.message === 'Mock module error') {
327 |           moduleErrorThrown = true;
328 |         }
329 |       }
330 | 
331 |       testResults.push(assertTruthy(moduleErrorThrown, 'Module initialization error handled'));
332 | 
333 |       // Clean up error recovery test instances
334 |       try {
335 |         await failingOrchestrator.shutdown();
336 |         failingOrchestrator.cleanup();
337 |       } catch (error) {
338 |         console.warn('⚠️ Warning: Error cleaning up failingOrchestrator:', error.message);
339 |       }
340 | 
341 |       try {
342 |         await moduleFailOrchestrator.shutdown();
343 |         moduleFailOrchestrator.cleanup();
344 |       } catch (error) {
345 |         console.warn('⚠️ Warning: Error cleaning up moduleFailOrchestrator:', error.message);
346 |       }
347 | 
348 |     } catch (error) {
349 |       console.error(`❌ Error recovery test failed: ${error.message}`);
350 |       testResults.push(false);
351 |       testResults.push(false);
352 |       testResults.push(false);
353 |     }
354 | 
355 |     // Test 7: Performance Validation
356 |     console.log('🔍 Test 7: Performance Validation');
357 | 
358 |     setupTest();
359 |     try {
360 |       const start = Date.now();
361 | 
362 |       await orchestrator.loadConfiguration();
363 |       await orchestrator.loadPromptsData();
364 |       await orchestrator.initializeModules();
365 | 
366 |       const duration = Date.now() - start;
367 | 
368 |       testResults.push(assertLessThan(duration, 10000, 'Initialization completes within 10 seconds'));
369 | 
370 |       // Test step timing
371 |       const timings = {};
372 | 
373 |       const timingOrchestrator = new Application(logger);
374 | 
375 |       let stepStart = Date.now();
376 |       await timingOrchestrator.loadConfiguration();
377 |       timings.config = Date.now() - stepStart;
378 | 
379 |       stepStart = Date.now();
380 |       await timingOrchestrator.loadPromptsData();
381 |       timings.prompts = Date.now() - stepStart;
382 | 
383 |       stepStart = Date.now();
384 |       await timingOrchestrator.initializeModules();
385 |       timings.modules = Date.now() - stepStart;
386 | 
387 |       testResults.push(assertLessThan(timings.config, 5000, 'Configuration loading under 5 seconds'));
388 |       testResults.push(assertLessThan(timings.prompts, 5000, 'Prompts loading under 5 seconds'));
389 |       testResults.push(assertLessThan(timings.modules, 5000, 'Module initialization under 5 seconds'));
390 | 
391 |       console.log(`📊 Initialization timings - Config: ${timings.config}ms, Prompts: ${timings.prompts}ms, Modules: ${timings.modules}ms`);
392 | 
393 |       // Clean up timing orchestrator
394 |       try {
395 |         await timingOrchestrator.shutdown();
396 |         timingOrchestrator.cleanup();
397 |       } catch (error) {
398 |         console.warn('⚠️ Warning: Error cleaning up timingOrchestrator:', error.message);
399 |       }
400 | 
401 |     } catch (error) {
402 |       console.error(`❌ Performance validation failed: ${error.message}`);
403 |       testResults.push(false);
404 |       testResults.push(false);
405 |       testResults.push(false);
406 |       testResults.push(false);
407 |     }
408 | 
409 |     // Results Summary
410 |     const passedTests = testResults.filter(result => result).length;
411 |     const totalTests = testResults.length;
412 | 
413 |     console.log('\n📊 Server Startup Integration Tests Summary:');
414 |     console.log(`   ✅ Passed: ${passedTests}/${totalTests} tests`);
415 |     console.log(`   📊 Success Rate: ${((passedTests/totalTests)*100).toFixed(1)}%`);
416 | 
417 |     // Cleanup: Properly shutdown Application instances to prevent hanging processes
418 |     if (orchestrator) {
419 |       try {
420 |         await orchestrator.shutdown();
421 |         orchestrator.cleanup();
422 |       } catch (error) {
423 |         console.warn('⚠️ Warning: Error during orchestrator cleanup:', error.message);
424 |       }
425 |     }
426 | 
427 |     // Check for remaining resources before exit
428 |     console.log('\n🔍 Checking for remaining global resources...');
429 |     globalResourceTracker.logDiagnostics();
430 |     const cleared = globalResourceTracker.emergencyCleanup();
431 |     if (cleared > 0) {
432 |       console.log(`💀 Emergency cleanup cleared ${cleared} additional resources`);
433 |     }
434 | 
435 |     if (passedTests === totalTests) {
436 |       console.log('🎉 All Server Startup Integration tests passed!');
437 |       // Emergency process exit to prevent hanging due to global Node.js resources
438 |       console.log('💀 Forcing process exit to prevent hanging from global timers...');
439 |       setTimeout(() => process.exit(0), 100); // Small delay to ensure log output
440 |       return true;
441 |     } else {
442 |       console.error('❌ Some Server Startup Integration tests failed');
443 |       // Emergency process exit for failure case as well
444 |       console.log('💀 Forcing process exit to prevent hanging from global timers...');
445 |       setTimeout(() => process.exit(1), 100); // Small delay to ensure log output
446 |       return false;
447 |     }
448 | 
449 |   } catch (error) {
450 |     console.error('❌ Server Startup Integration tests failed with error:', error.message);
451 |     if (error.stack) {
452 |       console.error('Stack trace:', error.stack);
453 |     }
454 |     // Emergency process exit for error case as well
455 |     console.log('💀 Forcing process exit due to test error to prevent hanging from global timers...');
456 |     setTimeout(() => process.exit(1), 100); // Small delay to ensure log output
457 |     return false;
458 |   } finally {
459 |     // Clear the global timeout
460 |     clearTimeout(globalTimeout);
461 | 
462 |     // Emergency cleanup: Ensure all Application instances are properly shut down
463 |     if (typeof orchestrator !== 'undefined' && orchestrator) {
464 |       try {
465 |         await orchestrator.shutdown();
466 |         orchestrator.cleanup();
467 |       } catch (error) {
468 |         console.warn('⚠️ Emergency cleanup warning:', error.message);
469 |       }
470 |     }
471 |   }
472 | }
473 | 
474 | // Run the tests
475 | if (import.meta.url === `file://${process.argv[1]}`) {
476 |   runServerStartupIntegrationTests().catch(error => {
477 |     console.error('❌ Test execution failed:', error);
478 |     process.exit(1);
479 |   });
480 | }
481 | 
482 | export { runServerStartupIntegrationTests };
```
Page 10/18FirstPrevNextLast