This is page 15 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/runtime/application.ts: -------------------------------------------------------------------------------- ```typescript 1 | /** 2 | * Application Runtime Management 3 | * Manages application lifecycle, module coordination, and system health 4 | * 5 | * This is the streamlined version of the original ApplicationOrchestrator, 6 | * focused on runtime concerns while delegating execution to the execution engine. 7 | */ 8 | 9 | import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; 10 | import { promises as fs } from "fs"; 11 | import path from "path"; 12 | import { fileURLToPath } from "url"; 13 | 14 | // Import all module managers 15 | import { ApiManager, createApiManager } from "../api/index.js"; 16 | import { ConfigManager } from "../config/index.js"; 17 | import { 18 | createFrameworkStateManager, 19 | FrameworkStateManager, 20 | } from "../frameworks/framework-state-manager.js"; 21 | import { 22 | createLogger, 23 | EnhancedLoggingConfig, 24 | Logger, 25 | } from "../logging/index.js"; 26 | import { createMcpToolsManager, McpToolsManager } from "../mcp-tools/index.js"; 27 | import { createToolDescriptionManager, ToolDescriptionManager } from "../mcp-tools/tool-description-manager.js"; 28 | import { PromptManager } from "../prompts/index.js"; 29 | import { 30 | ServerManager, 31 | startMcpServer, 32 | createTransportManager, 33 | TransportManager, 34 | } from "../server/index.js"; 35 | import { TextReferenceManager } from "../text-references/index.js"; 36 | 37 | // Import execution modules 38 | import { 39 | ConversationManager, 40 | createConversationManager, 41 | } from "../text-references/conversation.js"; 42 | // REMOVED: ExecutionCoordinator and GateEvaluator imports - modular chain and gate systems removed 43 | 44 | // Phase 1: Framework capabilities now integrated into base components 45 | // No separate framework observers needed - functionality moved to enhanced FileObserver and HotReloadManager 46 | 47 | // Import startup management 48 | import { ServerRootDetector } from "./startup.js"; 49 | 50 | // Import types 51 | import { Category, ConvertedPrompt, PromptData } from "../types/index.js"; 52 | // Import chain utilities 53 | import { isChainPrompt } from "../utils/chainUtils.js"; 54 | 55 | /** 56 | * Application Runtime class 57 | * Coordinates all modules and manages application lifecycle 58 | */ 59 | export class Application { 60 | private logger: Logger; 61 | private configManager: ConfigManager; 62 | private textReferenceManager: TextReferenceManager; 63 | private conversationManager: ConversationManager; 64 | private promptManager: PromptManager; 65 | // REMOVED: executionCoordinator - modular chain system removed 66 | // REMOVED: gateEvaluator - gate evaluation system removed 67 | private mcpToolsManager: McpToolsManager; 68 | private toolDescriptionManager: ToolDescriptionManager; 69 | private frameworkStateManager: FrameworkStateManager; 70 | private transportManager: TransportManager; 71 | private apiManager?: ApiManager; 72 | private serverManager?: ServerManager; 73 | // Phase 1: Framework capabilities integrated into base components 74 | // No separate framework observers needed 75 | 76 | // MCP Server instance 77 | private mcpServer: McpServer; 78 | 79 | // Application data 80 | private _promptsData: PromptData[] = []; 81 | private _categories: Category[] = []; 82 | private _convertedPrompts: ConvertedPrompt[] = []; 83 | 84 | // Performance monitoring 85 | private memoryOptimizationInterval?: NodeJS.Timeout; 86 | 87 | // Server root detector 88 | private serverRootDetector: ServerRootDetector; 89 | 90 | // Debug output control 91 | private debugOutput: boolean; 92 | 93 | /** 94 | * Conditional debug logging to prevent output flood during tests 95 | */ 96 | private debugLog(message: string, ...args: any[]): void { 97 | if (this.debugOutput) { 98 | console.error(`DEBUG: ${message}`, ...args); 99 | } 100 | } 101 | 102 | constructor(logger?: Logger) { 103 | // Will be initialized in startup() if not provided 104 | this.logger = logger || (null as any); 105 | this.configManager = null as any; 106 | this.textReferenceManager = null as any; 107 | this.conversationManager = null as any; 108 | this.promptManager = null as any; 109 | // REMOVED: executionCoordinator - modular chain system removed 110 | // REMOVED: gateEvaluator - gate evaluation system removed 111 | this.mcpToolsManager = null as any; 112 | this.toolDescriptionManager = null as any; 113 | this.frameworkStateManager = null as any; 114 | this.transportManager = null as any; 115 | this.mcpServer = null as any; 116 | // Phase 1: Framework capabilities integrated into base components 117 | // Phase 3 consensus observer removed 118 | this.serverRootDetector = new ServerRootDetector(); 119 | 120 | // Initialize debug output control - suppress in test environments 121 | this.debugOutput = !this.isTestEnvironment(); 122 | } 123 | 124 | /** 125 | * Detect if running in test environment to suppress debug output 126 | */ 127 | private isTestEnvironment(): boolean { 128 | return ( 129 | process.env.NODE_ENV === 'test' || 130 | process.argv.includes('--suppress-debug') || 131 | process.argv.includes('--test-mode') || 132 | // Detect GitHub Actions CI environment 133 | process.env.GITHUB_ACTIONS === 'true' || 134 | process.env.CI === 'true' || 135 | // Detect common test runner patterns 136 | process.argv.some(arg => arg.includes('test') || arg.includes('jest') || arg.includes('mocha')) || 137 | // Detect if called from integration test scripts 138 | process.argv[1]?.includes('tests/scripts/') 139 | ); 140 | } 141 | 142 | /** 143 | * Initialize all modules in the correct order 144 | */ 145 | async startup(): Promise<void> { 146 | try { 147 | // Phase 1: Core Foundation 148 | this.debugLog("Starting Phase 1 - Core Foundation..."); 149 | await this.initializeFoundation(); 150 | this.debugLog("Phase 1 completed successfully"); 151 | 152 | // Phase 2: Data Loading and Processing 153 | this.debugLog("Starting Phase 2 - Data Loading and Processing..."); 154 | await this.loadAndProcessData(); 155 | this.debugLog("Phase 2 completed successfully"); 156 | 157 | // Phase 3: Module Initialization 158 | this.debugLog("Starting Phase 3 - Module Initialization..."); 159 | await this.initializeModulesPrivate(); 160 | this.debugLog("Phase 3 completed successfully"); 161 | 162 | // Phase 4: Server Setup and Startup 163 | this.debugLog("Starting Phase 4 - Server Setup and Startup..."); 164 | // Check if this is a startup test mode 165 | const args = process.argv.slice(2); 166 | const isStartupTest = args.includes("--startup-test"); 167 | await this.startServer(isStartupTest); 168 | this.debugLog("Phase 4 completed successfully"); 169 | console.error( 170 | "DEBUG: All startup phases completed, server should be running..." 171 | ); 172 | 173 | this.logger.info("Application startup completed successfully"); 174 | } catch (error) { 175 | if (this.logger) { 176 | this.logger.error("Error during application startup:", error); 177 | } else { 178 | console.error("Error during application startup:", error); 179 | } 180 | throw error; 181 | } 182 | } 183 | 184 | /** 185 | * Public test methods for GitHub Actions compatibility 186 | */ 187 | async loadConfiguration(): Promise<void> { 188 | await this.initializeFoundation(); 189 | } 190 | 191 | async loadPromptsData(): Promise<void> { 192 | await this.loadAndProcessData(); 193 | } 194 | 195 | // Make initializeModules public for testing 196 | async initializeModules(): Promise<void> { 197 | return this.initializeModulesPrivate(); 198 | } 199 | 200 | // Expose data for testing 201 | get config() { 202 | return this.configManager?.getConfig(); 203 | } 204 | 205 | get promptsData() { 206 | return this._promptsData; 207 | } 208 | 209 | get convertedPrompts() { 210 | return this._convertedPrompts; 211 | } 212 | 213 | get categories() { 214 | return this._categories; 215 | } 216 | 217 | /** 218 | * Phase 1: Initialize foundation (configuration, logging, basic services) 219 | */ 220 | private async initializeFoundation(): Promise<void> { 221 | // Determine server root directory robustly 222 | const serverRoot = await this.serverRootDetector.determineServerRoot(); 223 | this.debugLog("Server root detected:", serverRoot); 224 | 225 | // Initialize configuration manager using the detected server root 226 | this.debugLog("About to call path.join with serverRoot:", serverRoot); 227 | const CONFIG_FILE = path.join(serverRoot, "config.json"); 228 | this.debugLog("Config file path:", CONFIG_FILE); 229 | this.debugLog("About to create ConfigManager with CONFIG_FILE:", CONFIG_FILE); 230 | try { 231 | this.configManager = new ConfigManager(CONFIG_FILE); 232 | this.debugLog("ConfigManager created successfully"); 233 | } catch (error) { 234 | this.debugLog("ConfigManager creation failed:", error); 235 | throw error; 236 | } 237 | this.debugLog("About to load config"); 238 | try { 239 | await this.configManager.loadConfig(); 240 | this.debugLog("Config loaded successfully"); 241 | } catch (error) { 242 | this.debugLog("Config loading failed:", error); 243 | throw error; 244 | } 245 | 246 | // Determine transport from command line arguments 247 | const args = process.argv.slice(2); 248 | this.debugLog("Args:", args); 249 | const transport = TransportManager.determineTransport( 250 | args, 251 | this.configManager 252 | ); 253 | this.debugLog("Transport determined:", transport); 254 | 255 | // Check verbosity flags for conditional logging 256 | const isVerbose = 257 | args.includes("--verbose") || args.includes("--debug-startup"); 258 | const isQuiet = args.includes("--quiet"); 259 | this.debugLog("Verbose:", isVerbose, "Quiet:", isQuiet); 260 | 261 | // Initialize enhanced logger with config-based settings 262 | this.debugLog("About to create enhanced logger"); 263 | const loggingConfig = this.configManager.getLoggingConfig(); 264 | const logDirectory = path.isAbsolute(loggingConfig.directory) 265 | ? loggingConfig.directory 266 | : path.resolve(serverRoot, loggingConfig.directory); 267 | const logFile = path.join(logDirectory, "mcp-server.log"); 268 | 269 | // Ensure log directory exists 270 | try { 271 | await fs.mkdir(logDirectory, { recursive: true }); 272 | console.error(`DEBUG: Log directory ensured: ${logDirectory}`); 273 | } catch (error) { 274 | console.error( 275 | `DEBUG: Failed to create log directory ${logDirectory}:`, 276 | error 277 | ); 278 | } 279 | 280 | const enhancedLoggerConfig: EnhancedLoggingConfig = { 281 | logFile, 282 | transport, 283 | enableDebug: isVerbose, 284 | configuredLevel: loggingConfig.level, 285 | }; 286 | 287 | this.logger = createLogger(enhancedLoggerConfig); 288 | 289 | // Initialize log file 290 | await (this.logger as any).initLogFile(); 291 | this.debugLog("Enhanced logger created and initialized"); 292 | 293 | // Only show startup messages if not in quiet mode 294 | if (!isQuiet) { 295 | this.debugLog("About to call logger.info - Starting MCP..."); 296 | this.logger.info("Starting MCP Claude Prompts Server..."); 297 | this.debugLog("First logger.info completed"); 298 | this.logger.info(`Transport: ${transport}`); 299 | this.debugLog("Second logger.info completed"); 300 | } 301 | 302 | // Verbose mode shows detailed configuration info 303 | if (isVerbose) { 304 | this.debugLog("About to call verbose logger.info calls"); 305 | this.logger.info(`Server root: ${serverRoot}`); 306 | this.logger.info(`Config file: ${CONFIG_FILE}`); 307 | this.logger.debug(`Command line args: ${JSON.stringify(args)}`); 308 | this.logger.debug(`Process working directory: ${process.cwd()}`); 309 | this.debugLog("Verbose logger.info calls completed"); 310 | } 311 | 312 | // Initialize text reference manager 313 | this.debugLog("About to create TextReferenceManager"); 314 | this.textReferenceManager = new TextReferenceManager(this.logger); 315 | this.debugLog("TextReferenceManager created"); 316 | 317 | // Initialize conversation manager 318 | this.debugLog("About to create ConversationManager"); 319 | try { 320 | this.conversationManager = createConversationManager(this.logger); 321 | this.debugLog("ConversationManager created successfully"); 322 | } catch (error) { 323 | this.debugLog("ConversationManager creation failed:", error); 324 | throw error; 325 | } 326 | this.debugLog("ConversationManager created"); 327 | 328 | // Create MCP server 329 | this.debugLog("About to get config"); 330 | const config = this.configManager.getConfig(); 331 | this.debugLog("Config retrieved successfully"); 332 | this.debugLog("About to create McpServer"); 333 | this.mcpServer = new McpServer({ 334 | name: config.server.name, 335 | version: config.server.version, 336 | capabilities: { 337 | prompts: { listChanged: true }, 338 | tools: { listChanged: true }, 339 | }, 340 | }); 341 | this.debugLog("McpServer created successfully"); 342 | 343 | // Only log completion in verbose mode 344 | if (isVerbose) { 345 | this.debugLog("About to log foundation initialized"); 346 | this.logger.info("Foundation modules initialized"); 347 | this.debugLog("Foundation initialized log completed"); 348 | } 349 | this.debugLog("initializeFoundation completed successfully"); 350 | } 351 | 352 | /** 353 | * Phase 2: Load and process prompt data 354 | */ 355 | private async loadAndProcessData(): Promise<void> { 356 | // Check verbosity flags for conditional logging 357 | const args = process.argv.slice(2); 358 | const isVerbose = 359 | args.includes("--verbose") || args.includes("--debug-startup"); 360 | const isQuiet = args.includes("--quiet"); 361 | 362 | // Initialize prompt manager 363 | this.promptManager = new PromptManager( 364 | this.logger, 365 | this.textReferenceManager, 366 | this.configManager, 367 | this.mcpServer 368 | ); 369 | 370 | // Load and convert prompts with enhanced path resolution 371 | const config = this.configManager.getConfig(); 372 | 373 | // ENHANCED: Allow direct prompts config path override via environment variable 374 | // This bypasses server root detection issues entirely and is perfect for Claude Desktop 375 | let PROMPTS_FILE: string; 376 | 377 | if (process.env.MCP_PROMPTS_CONFIG_PATH) { 378 | PROMPTS_FILE = process.env.MCP_PROMPTS_CONFIG_PATH; 379 | if (isVerbose) { 380 | this.logger.info( 381 | "🎯 Using MCP_PROMPTS_CONFIG_PATH environment variable override" 382 | ); 383 | } 384 | } else { 385 | // Fallback to ConfigManager's getPromptsFilePath() method 386 | PROMPTS_FILE = this.configManager.getPromptsFilePath(); 387 | if (isVerbose) { 388 | this.logger.info("📁 Using config-based prompts file path resolution"); 389 | } 390 | } 391 | 392 | // Enhanced logging for prompt loading pipeline (verbose mode only) 393 | if (isVerbose) { 394 | this.logger.info("=== PROMPT LOADING PIPELINE START ==="); 395 | this.logger.info(`Config prompts.file setting: "${config.prompts.file}"`); 396 | if (process.env.MCP_PROMPTS_CONFIG_PATH) { 397 | this.logger.info( 398 | `🎯 MCP_PROMPTS_CONFIG_PATH override: "${process.env.MCP_PROMPTS_CONFIG_PATH}"` 399 | ); 400 | } else { 401 | this.logger.info( 402 | `Config manager base directory: "${path.dirname( 403 | this.configManager.getPromptsFilePath() 404 | )}"` 405 | ); 406 | } 407 | this.logger.info(`✅ Final PROMPTS_FILE path: "${PROMPTS_FILE}"`); 408 | 409 | // Add additional diagnostic information 410 | this.logger.info("=== PATH RESOLUTION DIAGNOSTICS ==="); 411 | this.logger.info(`process.cwd(): ${process.cwd()}`); 412 | this.logger.info(`process.argv[0]: ${process.argv[0]}`); 413 | this.logger.info(`process.argv[1]: ${process.argv[1] || "undefined"}`); 414 | this.logger.info( 415 | `__filename equivalent: ${fileURLToPath(import.meta.url)}` 416 | ); 417 | this.logger.info( 418 | `Config file path: ${(this.configManager as any).configPath}` 419 | ); 420 | this.logger.info( 421 | `MCP_PROMPTS_CONFIG_PATH: ${ 422 | process.env.MCP_PROMPTS_CONFIG_PATH || "undefined" 423 | }` 424 | ); 425 | this.logger.info( 426 | `MCP_SERVER_ROOT: ${process.env.MCP_SERVER_ROOT || "undefined"}` 427 | ); 428 | this.logger.info( 429 | `PROMPTS_FILE is absolute: ${path.isAbsolute(PROMPTS_FILE)}` 430 | ); 431 | this.logger.info( 432 | `PROMPTS_FILE normalized: ${path.normalize(PROMPTS_FILE)}` 433 | ); 434 | } 435 | 436 | // Validate that we're using absolute paths (critical for Claude Desktop) 437 | if (!path.isAbsolute(PROMPTS_FILE)) { 438 | if (isVerbose) { 439 | this.logger.error( 440 | `⚠️ CRITICAL: PROMPTS_FILE is not absolute: ${PROMPTS_FILE}` 441 | ); 442 | this.logger.error( 443 | `This will cause issues with Claude Desktop execution!` 444 | ); 445 | } 446 | // Convert to absolute path as fallback 447 | // Use serverRoot which is determined earlier and more reliable for constructing the absolute path 448 | const serverRoot = await this.serverRootDetector.determineServerRoot(); // Ensure serverRoot is available 449 | const absolutePromptsFile = path.resolve(serverRoot, PROMPTS_FILE); 450 | if (isVerbose) { 451 | this.logger.info( 452 | `🔧 Converting to absolute path: ${absolutePromptsFile}` 453 | ); 454 | } 455 | PROMPTS_FILE = absolutePromptsFile; 456 | } 457 | 458 | // Verify the file exists before attempting to load 459 | try { 460 | const fs = await import("fs/promises"); 461 | await fs.access(PROMPTS_FILE); 462 | if (isVerbose) { 463 | this.logger.info( 464 | `✓ Prompts configuration file exists: ${PROMPTS_FILE}` 465 | ); 466 | } 467 | } catch (error) { 468 | this.logger.error( 469 | `✗ Prompts configuration file NOT FOUND: ${PROMPTS_FILE}` 470 | ); 471 | if (isVerbose) { 472 | this.logger.error(`File access error:`, error); 473 | 474 | // Provide additional troubleshooting information 475 | this.logger.error("=== TROUBLESHOOTING INFORMATION ==="); 476 | this.logger.error(`Is path absolute? ${path.isAbsolute(PROMPTS_FILE)}`); 477 | this.logger.error(`Normalized path: ${path.normalize(PROMPTS_FILE)}`); 478 | this.logger.error(`Path exists check: ${PROMPTS_FILE}`); 479 | } 480 | 481 | throw new Error(`Prompts configuration file not found: ${PROMPTS_FILE}`); 482 | } 483 | 484 | try { 485 | this.logger.info("Initiating prompt loading and conversion..."); 486 | // Pass path.dirname(PROMPTS_FILE) as the basePath for resolving relative prompt file paths 487 | const result = await this.promptManager.loadAndConvertPrompts( 488 | PROMPTS_FILE, 489 | path.dirname(PROMPTS_FILE) 490 | ); 491 | 492 | this._promptsData = result.promptsData; 493 | this._categories = result.categories; 494 | this._convertedPrompts = result.convertedPrompts; 495 | 496 | this.logger.info("=== PROMPT LOADING RESULTS ==="); 497 | this.logger.info( 498 | `✓ Loaded ${this._promptsData.length} prompts from ${this._categories.length} categories` 499 | ); 500 | this.logger.info( 501 | `✓ Converted ${this._convertedPrompts.length} prompts to MCP format` 502 | ); 503 | 504 | // Log category breakdown 505 | if (this._categories.length > 0) { 506 | this.logger.info("Categories loaded:"); 507 | this._categories.forEach((category) => { 508 | const categoryPrompts = this._promptsData.filter( 509 | (p) => p.category === category.id 510 | ); 511 | this.logger.info( 512 | ` - ${category.name} (${category.id}): ${categoryPrompts.length} prompts` 513 | ); 514 | }); 515 | } else { 516 | this.logger.warn("⚠ No categories were loaded!"); 517 | } 518 | 519 | this.logger.info("=== PROMPT LOADING PIPELINE END ==="); 520 | 521 | // Propagate updated data to other relevant managers 522 | if (this.mcpToolsManager) { 523 | this.mcpToolsManager.updateData( 524 | this._promptsData, 525 | this._convertedPrompts, 526 | this.categories 527 | ); 528 | } 529 | // REMOVED: ExecutionCoordinator prompts update - modular chain system removed 530 | if (this.apiManager) { 531 | // apiManager might not exist for stdio 532 | this.apiManager.updateData( 533 | this._promptsData, 534 | this._categories, 535 | this.convertedPrompts 536 | ); 537 | } 538 | 539 | // CRUCIAL STEP: Re-register all prompts with the McpServer using the newly loaded data 540 | if (this.promptManager && this.mcpServer) { 541 | this.logger.info( 542 | "🔄 Re-registering all prompts with MCP server after hot-reload..." 543 | ); 544 | const registeredCount = await this.promptManager.registerAllPrompts( 545 | this.convertedPrompts 546 | ); 547 | this.logger.info( 548 | `✅ Successfully re-registered ${registeredCount} prompts.` 549 | ); 550 | } else { 551 | this.logger.warn( 552 | "⚠️ PromptManager or McpServer not available, skipping re-registration of prompts after hot-reload." 553 | ); 554 | } 555 | } catch (error) { 556 | this.logger.error("✗ PROMPT LOADING FAILED:"); 557 | this.logger.error("Error details:", error); 558 | this.logger.error( 559 | "Stack trace:", 560 | error instanceof Error ? error.stack : "No stack trace available" 561 | ); 562 | throw error; 563 | } 564 | } 565 | 566 | /** 567 | * Phase 3: Initialize remaining modules with loaded data 568 | */ 569 | private async initializeModulesPrivate(): Promise<void> { 570 | // Check verbosity flags for conditional logging 571 | const args = process.argv.slice(2); 572 | const isVerbose = 573 | args.includes("--verbose") || args.includes("--debug-startup"); 574 | 575 | // REMOVED: Gate evaluator and ExecutionCoordinator initialization - modular systems removed 576 | 577 | // Initialize Framework State Manager (for framework switching) 578 | if (isVerbose) 579 | this.logger.info("🔄 Initializing Framework State Manager..."); 580 | const frameworkStateRoot = 581 | typeof this.configManager.getServerRoot === 'function' 582 | ? this.configManager.getServerRoot() 583 | : path.dirname(this.configManager.getConfigPath()); 584 | this.frameworkStateManager = await createFrameworkStateManager( 585 | this.logger, 586 | frameworkStateRoot 587 | ); 588 | 589 | // Validation: Ensure FrameworkStateManager was created successfully 590 | if (!this.frameworkStateManager) { 591 | throw new Error( 592 | "Failed to initialize FrameworkStateManager - required for framework switching" 593 | ); 594 | } 595 | if (isVerbose) 596 | this.logger.info("✅ FrameworkStateManager initialized successfully"); 597 | 598 | // Debug: Log chain prompt availability 599 | const chainCount = this._convertedPrompts.filter((p) => 600 | isChainPrompt(p) 601 | ).length; 602 | if (isVerbose) 603 | this.logger.info( 604 | `🔗 Chain prompts available: ${chainCount}/${this._convertedPrompts.length} total prompts` 605 | ); 606 | if (chainCount > 0 && isVerbose) { 607 | const chainNames = this._convertedPrompts 608 | .filter((p) => isChainPrompt(p)) 609 | .map((p) => p.id) 610 | .join(", "); 611 | this.logger.info(`🔗 Available chains: ${chainNames}`); 612 | } 613 | 614 | // Phase 2: Workflow registration removed - chains handle all multi-step execution 615 | 616 | // Initialize MCP tools manager 617 | if (isVerbose) this.logger.info("🔄 Initializing MCP tools manager..."); 618 | this.mcpToolsManager = await createMcpToolsManager( 619 | this.logger, 620 | this.mcpServer, 621 | this.promptManager, 622 | this.configManager, 623 | () => this.fullServerRefresh(), 624 | (reason: string) => this.restartServer(reason) 625 | // Phase 3: Removed executionCoordinator - chains now use LLM-driven execution 626 | ); 627 | 628 | // Update MCP tools manager with current data 629 | if (isVerbose) this.logger.info("🔄 Updating MCP tools manager data..."); 630 | this.mcpToolsManager.updateData( 631 | this._promptsData, 632 | this._convertedPrompts, 633 | this.categories 634 | ); 635 | 636 | // Connect Framework State Manager to MCP Tools Manager 637 | if (isVerbose) this.logger.info("🔄 Connecting Framework State Manager..."); 638 | this.mcpToolsManager.setFrameworkStateManager(this.frameworkStateManager); 639 | 640 | // Initialize and connect Framework Manager 641 | if (isVerbose) this.logger.info("🔄 Initializing Framework Manager..."); 642 | await this.mcpToolsManager.setFrameworkManager(); 643 | 644 | // Initialize Tool Description Manager 645 | if (isVerbose) this.logger.info("🔄 Initializing Tool Description Manager..."); 646 | this.toolDescriptionManager = createToolDescriptionManager(this.logger, this.configManager); 647 | await this.toolDescriptionManager.initialize(); 648 | 649 | // Connect Tool Description Manager to MCP Tools Manager 650 | if (isVerbose) this.logger.info("🔄 Connecting Tool Description Manager to MCP Tools..."); 651 | this.mcpToolsManager.setToolDescriptionManager(this.toolDescriptionManager); 652 | 653 | // REMOVED: ConsolidatedPromptEngine to ExecutionCoordinator wiring - ExecutionCoordinator removed 654 | 655 | // Register all MCP tools 656 | if (isVerbose) this.logger.info("🔄 Registering all MCP tools..."); 657 | await this.mcpToolsManager.registerAllTools(); 658 | 659 | // Register all prompts 660 | if (isVerbose) this.logger.info("🔄 Registering all prompts..."); 661 | await this.promptManager.registerAllPrompts(this._convertedPrompts); 662 | 663 | this.logger.info("All modules initialized successfully"); 664 | 665 | // REMOVED: ExecutionCoordinator stats collection - modular chain system removed 666 | } 667 | 668 | // Phase 2: Workflow registration completely removed - chains handle all multi-step execution 669 | 670 | /** 671 | * Phase 4: Setup and start the server 672 | */ 673 | private async startServer(isStartupTest: boolean = false): Promise<void> { 674 | console.error("DEBUG: startServer() - Determining transport..."); 675 | // Determine transport 676 | const args = process.argv.slice(2); 677 | const transport = TransportManager.determineTransport( 678 | args, 679 | this.configManager 680 | ); 681 | console.error("DEBUG: startServer() - Transport determined:", transport); 682 | 683 | console.error("DEBUG: startServer() - Creating transport manager..."); 684 | // Create transport manager 685 | this.transportManager = createTransportManager( 686 | this.logger, 687 | this.configManager, 688 | this.mcpServer, 689 | transport 690 | ); 691 | console.error("DEBUG: startServer() - Transport manager created"); 692 | 693 | console.error("DEBUG: startServer() - Checking if SSE transport..."); 694 | // Create API manager for SSE transport 695 | if (this.transportManager.isSse()) { 696 | console.error("DEBUG: startServer() - Creating API manager for SSE..."); 697 | this.apiManager = createApiManager( 698 | this.logger, 699 | this.configManager, 700 | this.promptManager, 701 | this.mcpToolsManager 702 | ); 703 | console.error("DEBUG: startServer() - API manager created"); 704 | 705 | console.error("DEBUG: startServer() - Updating API manager data..."); 706 | // Update API manager with current data 707 | this.apiManager.updateData( 708 | this._promptsData, 709 | this._categories, 710 | this.convertedPrompts 711 | ); 712 | console.error("DEBUG: startServer() - API manager data updated"); 713 | } else { 714 | console.error( 715 | "DEBUG: startServer() - Using STDIO transport (no API manager needed)" 716 | ); 717 | } 718 | 719 | // Phase 1: Framework capabilities integrated into base components 720 | console.error( 721 | "DEBUG: startServer() - Framework capabilities integrated into base components" 722 | ); 723 | 724 | if (isStartupTest) { 725 | console.error( 726 | "DEBUG: startServer() - Skipping MCP server startup (test mode)" 727 | ); 728 | // Create a mock server manager for health validation 729 | this.serverManager = { 730 | shutdown: () => console.error("DEBUG: Mock server shutdown"), 731 | getStatus: () => ({ running: true, transport: "stdio" }), 732 | isRunning: () => true, 733 | } as any; 734 | console.error("DEBUG: startServer() - Mock server manager created"); 735 | } else { 736 | console.error("DEBUG: startServer() - About to start MCP server..."); 737 | // Start the server 738 | this.serverManager = await startMcpServer( 739 | this.logger, 740 | this.configManager, 741 | this.transportManager, 742 | this.apiManager 743 | ); 744 | console.error("DEBUG: startServer() - MCP server started"); 745 | } 746 | 747 | this.logger.info("Server started successfully"); 748 | console.error("DEBUG: startServer() - Server startup completed"); 749 | } 750 | 751 | /** 752 | * Switch to a different framework by ID (CAGEERF, ReACT, 5W1H, etc.) 753 | * Core functionality: Allow switching between frameworks to guide the system 754 | */ 755 | async switchFramework( 756 | frameworkId: string 757 | ): Promise<{ success: boolean; message: string }> { 758 | // Phase 1: Framework switching simplified - basic support only 759 | 760 | try { 761 | this.logger.info( 762 | `Framework switching to ${frameworkId} (Phase 1 basic support)` 763 | ); 764 | const result = { 765 | success: true, 766 | message: `Switched to ${frameworkId}`, 767 | newFramework: frameworkId, 768 | previousFramework: "basic", 769 | }; 770 | 771 | if (result.success) { 772 | this.logger.info(`🔄 Framework switched to: ${result.newFramework}`); 773 | return { 774 | success: true, 775 | message: `Successfully switched from ${result.previousFramework} to ${result.newFramework}`, 776 | }; 777 | } else { 778 | this.logger.warn(`❌ Framework switch failed: ${result.message}`); 779 | return { 780 | success: false, 781 | message: result.message || "Unknown error during framework switch", 782 | }; 783 | } 784 | } catch (error) { 785 | this.logger.error("Framework switch error:", error); 786 | return { 787 | success: false, 788 | message: `Error switching framework: ${ 789 | error instanceof Error ? error.message : String(error) 790 | }`, 791 | }; 792 | } 793 | } 794 | 795 | /** 796 | * Get current framework information 797 | */ 798 | getCurrentFrameworkInfo(): { 799 | id: string; 800 | name: string; 801 | availableFrameworks: string[]; 802 | isHealthy: boolean; 803 | } { 804 | // Phase 1: Framework status simplified - basic support only 805 | const status = { 806 | currentFramework: "basic", 807 | currentFrameworkName: "Basic Framework", 808 | isHealthy: true, 809 | }; 810 | const available = ["basic"]; 811 | 812 | return { 813 | id: status.currentFramework, 814 | name: status.currentFrameworkName, 815 | availableFrameworks: available, 816 | isHealthy: status.isHealthy, 817 | }; 818 | } 819 | 820 | /** 821 | * Graceful shutdown 822 | */ 823 | async shutdown(): Promise<void> { 824 | try { 825 | if (this.logger) { 826 | this.logger.info("Initiating application shutdown..."); 827 | } 828 | 829 | // Phase 1: Stop server and transport layers 830 | if (this.serverManager) { 831 | if (this.logger) { 832 | this.logger.debug("Shutting down server manager..."); 833 | } 834 | this.serverManager.shutdown(); 835 | } 836 | 837 | // Phase 2: Stop transport layer (if it has shutdown method) 838 | if (this.transportManager && 'shutdown' in this.transportManager && typeof (this.transportManager as any).shutdown === 'function') { 839 | if (this.logger) { 840 | this.logger.debug("Shutting down transport manager..."); 841 | } 842 | try { 843 | await (this.transportManager as any).shutdown(); 844 | } catch (error) { 845 | this.logger?.warn("Error shutting down transport manager:", error); 846 | } 847 | } 848 | 849 | // Phase 3: Stop monitoring and resource-intensive components (if they have shutdown method) 850 | if (this.frameworkStateManager && 'shutdown' in this.frameworkStateManager && typeof (this.frameworkStateManager as any).shutdown === 'function') { 851 | if (this.logger) { 852 | this.logger.debug("Shutting down framework state manager..."); 853 | } 854 | try { 855 | await (this.frameworkStateManager as any).shutdown(); 856 | } catch (error) { 857 | this.logger?.warn("Error shutting down framework state manager:", error); 858 | } 859 | } 860 | 861 | // Phase 4: Stop file watchers and hot-reload systems (if they have shutdown method) 862 | if (this.promptManager && 'shutdown' in this.promptManager && typeof (this.promptManager as any).shutdown === 'function') { 863 | if (this.logger) { 864 | this.logger.debug("Shutting down prompt manager..."); 865 | } 866 | try { 867 | await (this.promptManager as any).shutdown(); 868 | } catch (error) { 869 | this.logger?.warn("Error shutting down prompt manager:", error); 870 | } 871 | } 872 | 873 | // Phase 5: Stop API and MCP tools (if they have shutdown method) 874 | if (this.apiManager && 'shutdown' in this.apiManager && typeof (this.apiManager as any).shutdown === 'function') { 875 | if (this.logger) { 876 | this.logger.debug("Shutting down API manager..."); 877 | } 878 | try { 879 | await (this.apiManager as any).shutdown(); 880 | } catch (error) { 881 | this.logger?.warn("Error shutting down API manager:", error); 882 | } 883 | } 884 | 885 | if (this.mcpToolsManager && 'shutdown' in this.mcpToolsManager && typeof (this.mcpToolsManager as any).shutdown === 'function') { 886 | if (this.logger) { 887 | this.logger.debug("Shutting down MCP tools manager..."); 888 | } 889 | try { 890 | await (this.mcpToolsManager as any).shutdown(); 891 | } catch (error) { 892 | this.logger?.warn("Error shutting down MCP tools manager:", error); 893 | } 894 | } 895 | 896 | // Phase 6: Stop conversation and text reference managers (if they have shutdown method) 897 | if (this.conversationManager && 'shutdown' in this.conversationManager && typeof (this.conversationManager as any).shutdown === 'function') { 898 | if (this.logger) { 899 | this.logger.debug("Shutting down conversation manager..."); 900 | } 901 | try { 902 | await (this.conversationManager as any).shutdown(); 903 | } catch (error) { 904 | this.logger?.warn("Error shutting down conversation manager:", error); 905 | } 906 | } 907 | 908 | if (this.textReferenceManager && 'shutdown' in this.textReferenceManager && typeof (this.textReferenceManager as any).shutdown === 'function') { 909 | if (this.logger) { 910 | this.logger.debug("Shutting down text reference manager..."); 911 | } 912 | try { 913 | await (this.textReferenceManager as any).shutdown(); 914 | } catch (error) { 915 | this.logger?.warn("Error shutting down text reference manager:", error); 916 | } 917 | } 918 | 919 | // Phase 6: Clean up internal timers 920 | this.cleanup(); 921 | 922 | if (this.logger) { 923 | this.logger.info("Application shutdown completed successfully"); 924 | } 925 | } catch (error) { 926 | if (this.logger) { 927 | this.logger.error("Error during shutdown:", error); 928 | } else { 929 | console.error("Error during shutdown (logger not available):", error); 930 | } 931 | throw error; 932 | } 933 | } 934 | 935 | /** 936 | * Perform a full server refresh (hot-reload). 937 | * This reloads all prompts from disk and updates all relevant modules. 938 | */ 939 | public async fullServerRefresh(): Promise<void> { 940 | this.logger.info( 941 | "🔥 Application: Starting full server refresh (hot-reload)..." 942 | ); 943 | try { 944 | // Step 1: Reload all prompt data from disk by re-running the data loading phase. 945 | // This updates the application's internal state with the latest file contents. 946 | await this.loadAndProcessData(); 947 | this.logger.info("✅ Data reloaded and processed from disk."); 948 | 949 | // Step 2: Framework hot-reload integration now handled by enhanced base components 950 | this.logger.info( 951 | "✅ Framework capabilities integrated into base components" 952 | ); 953 | 954 | // Step 2.5: Phase 2 - Simple framework switching status check 955 | const switchingStatus = { 956 | currentFramework: "basic", 957 | currentFrameworkName: "Basic Framework", 958 | enabledFrameworks: 1, 959 | availableFrameworks: 1, 960 | }; 961 | this.logger.info( 962 | `✅ Framework switching system ready: ${switchingStatus.currentFrameworkName} active ` + 963 | `(${switchingStatus.enabledFrameworks}/${switchingStatus.availableFrameworks} frameworks available)` 964 | ); 965 | 966 | // Phase 3 complexity removed - focusing on simple framework switching instead of multi-framework consensus 967 | 968 | // Step 3: Propagate the new data to all dependent modules. 969 | // This ensures all parts of the application are synchronized with the new state. 970 | // REMOVED: ExecutionCoordinator prompts update - modular chain system removed 971 | 972 | if (this.mcpToolsManager) { 973 | this.mcpToolsManager.updateData( 974 | this._promptsData, 975 | this._convertedPrompts, 976 | this.categories 977 | ); 978 | this.logger.info("✅ McpToolsManager updated with new data."); 979 | } 980 | 981 | if (this.apiManager) { 982 | // The API manager is only available for the SSE transport. 983 | this.apiManager.updateData( 984 | this._promptsData, 985 | this._categories, 986 | this.convertedPrompts 987 | ); 988 | this.logger.info("✅ ApiManager updated with new data."); 989 | } 990 | 991 | // Step 4: Notify MCP clients that the prompt list has changed (proper hot-reload) 992 | // This follows MCP protocol - clients will re-query the server for the updated list 993 | await this.promptManager.notifyPromptsListChanged(); 994 | this.logger.info( 995 | "✅ Prompts list_changed notification sent to MCP clients." 996 | ); 997 | 998 | // Step 5: Phase 2 - Workflow registration removed 999 | 1000 | this.logger.info("🚀 Full server refresh completed successfully."); 1001 | } catch (error) { 1002 | this.logger.error("❌ Error during full server refresh:", error); 1003 | // Re-throw the error so the caller can handle it appropriately. 1004 | throw error; 1005 | } 1006 | } 1007 | 1008 | /** 1009 | * Restart the application by shutting down and exiting with a restart code. 1010 | * Relies on a process manager (e.g., PM2) to restart the process. 1011 | */ 1012 | public async restartServer(reason: string = "Manual restart"): Promise<void> { 1013 | this.logger.info(`🚨 Initiating server restart. Reason: ${reason}`); 1014 | try { 1015 | // Ensure all current operations are gracefully shut down. 1016 | await this.shutdown(); 1017 | this.logger.info( 1018 | "✅ Server gracefully shut down. Exiting with restart code." 1019 | ); 1020 | } catch (error) { 1021 | this.logger.error("❌ Error during pre-restart shutdown:", error); 1022 | } finally { 1023 | // Exit with a specific code that a process manager can detect. 1024 | process.exit(100); 1025 | } 1026 | } 1027 | 1028 | /** 1029 | * Get application status 1030 | */ 1031 | getStatus(): { 1032 | running: boolean; 1033 | transport?: string; 1034 | promptsLoaded: number; 1035 | categoriesLoaded: number; 1036 | serverStatus?: any; 1037 | executionCoordinator?: { 1038 | totalExecutions: number; 1039 | promptExecutions: number; 1040 | chainExecutions: number; 1041 | // workflowExecutions: number; // Phase 2: removed, workflows tracked as advanced chains 1042 | successRate: number; 1043 | }; 1044 | } { 1045 | // REMOVED: ExecutionCoordinator status - providing default execution status 1046 | const executionCoordinatorStatus = { 1047 | totalExecutions: 0, 1048 | promptExecutions: 0, 1049 | chainExecutions: 0, 1050 | successRate: 1.0, 1051 | }; 1052 | 1053 | return { 1054 | running: this.serverManager?.isRunning() || false, 1055 | transport: this.transportManager?.getTransportType(), 1056 | promptsLoaded: this._promptsData.length, 1057 | categoriesLoaded: this._categories.length, 1058 | serverStatus: this.serverManager?.getStatus(), 1059 | executionCoordinator: executionCoordinatorStatus, 1060 | }; 1061 | } 1062 | 1063 | /** 1064 | * Get all module instances (for debugging/testing) 1065 | */ 1066 | getModules() { 1067 | return { 1068 | logger: this.logger, 1069 | configManager: this.configManager, 1070 | promptManager: this.promptManager, 1071 | textReferenceManager: this.textReferenceManager, 1072 | conversationManager: this.conversationManager, 1073 | // REMOVED: executionCoordinator and gateEvaluator - modular systems removed 1074 | mcpToolsManager: this.mcpToolsManager, 1075 | apiManager: this.apiManager, 1076 | serverManager: this.serverManager, 1077 | }; 1078 | } 1079 | 1080 | /** 1081 | * Validate application health - comprehensive health check 1082 | */ 1083 | validateHealth(): { 1084 | healthy: boolean; 1085 | modules: { 1086 | foundation: boolean; 1087 | dataLoaded: boolean; 1088 | modulesInitialized: boolean; 1089 | serverRunning: boolean; 1090 | }; 1091 | details: { 1092 | promptsLoaded: number; 1093 | categoriesLoaded: number; 1094 | serverStatus?: any; 1095 | moduleStatus: Record<string, boolean>; 1096 | }; 1097 | issues: string[]; 1098 | } { 1099 | const issues: string[] = []; 1100 | const moduleStatus: Record<string, boolean> = {}; 1101 | 1102 | // Check foundation modules 1103 | const foundationHealthy = !!( 1104 | this.logger && 1105 | this.configManager && 1106 | this.textReferenceManager 1107 | ); 1108 | moduleStatus.foundation = foundationHealthy; 1109 | if (!foundationHealthy) { 1110 | issues.push("Foundation modules not properly initialized"); 1111 | } 1112 | 1113 | // Check data loading 1114 | const dataLoaded = 1115 | this._promptsData.length > 0 && this._categories.length > 0; 1116 | moduleStatus.dataLoaded = dataLoaded; 1117 | if (!dataLoaded) { 1118 | issues.push("Prompt data not loaded or empty"); 1119 | } 1120 | 1121 | // Check module initialization 1122 | const modulesInitialized = !!( 1123 | this.promptManager && 1124 | // REMOVED: this.executionCoordinator && this.gateEvaluator - modular systems removed 1125 | this.mcpToolsManager 1126 | ); 1127 | moduleStatus.modulesInitialized = modulesInitialized; 1128 | moduleStatus.serverRunning = !!( 1129 | this.serverManager && this.transportManager 1130 | ); 1131 | 1132 | moduleStatus.configManager = !!this.configManager; 1133 | moduleStatus.logger = !!this.logger; 1134 | moduleStatus.promptManager = !!this.promptManager; 1135 | moduleStatus.textReferenceManager = !!this.textReferenceManager; 1136 | moduleStatus.conversationManager = !!this.conversationManager; 1137 | // REMOVED: moduleStatus for executionCoordinator and gateEvaluator - modular systems removed 1138 | moduleStatus.mcpToolsManager = !!this.mcpToolsManager; 1139 | moduleStatus.transportManager = !!this.transportManager; 1140 | moduleStatus.apiManager = !!this.apiManager; 1141 | moduleStatus.serverManager = !!this.serverManager; 1142 | 1143 | // Check overall health 1144 | const isHealthy = 1145 | foundationHealthy && 1146 | dataLoaded && 1147 | modulesInitialized && 1148 | moduleStatus.serverRunning && 1149 | issues.length === 0; 1150 | 1151 | return { 1152 | healthy: isHealthy, 1153 | modules: { 1154 | foundation: foundationHealthy, 1155 | dataLoaded, 1156 | modulesInitialized, 1157 | serverRunning: moduleStatus.serverRunning, 1158 | }, 1159 | details: { 1160 | promptsLoaded: this._promptsData.length, 1161 | categoriesLoaded: this._categories.length, 1162 | serverStatus: this.serverManager?.getStatus(), 1163 | moduleStatus, 1164 | }, 1165 | issues, 1166 | }; 1167 | } 1168 | 1169 | /** 1170 | * Get performance metrics for monitoring 1171 | */ 1172 | getPerformanceMetrics(): { 1173 | uptime: number; 1174 | memoryUsage: NodeJS.MemoryUsage; 1175 | process: { 1176 | pid: number; 1177 | nodeVersion: string; 1178 | platform: string; 1179 | arch: string; 1180 | }; 1181 | application: { 1182 | promptsLoaded: number; 1183 | categoriesLoaded: number; 1184 | serverConnections?: number; 1185 | }; 1186 | executionCoordinator?: { 1187 | statistics: any; 1188 | }; 1189 | } { 1190 | // REMOVED: ExecutionCoordinator metrics - providing default metrics 1191 | const executionCoordinatorMetrics = { 1192 | statistics: { 1193 | totalExecutions: 0, 1194 | promptExecutions: 0, 1195 | chainExecutions: 0, 1196 | successRate: 1.0, 1197 | averageExecutionTime: 0, 1198 | failedExecutions: 0, 1199 | }, 1200 | }; 1201 | 1202 | return { 1203 | uptime: process.uptime(), 1204 | memoryUsage: process.memoryUsage(), 1205 | process: { 1206 | pid: process.pid, 1207 | nodeVersion: process.version, 1208 | platform: process.platform, 1209 | arch: process.arch, 1210 | }, 1211 | application: { 1212 | promptsLoaded: this._promptsData.length, 1213 | categoriesLoaded: this._categories.length, 1214 | serverConnections: this.transportManager?.isSse() 1215 | ? this.transportManager.getActiveConnectionsCount() 1216 | : undefined, 1217 | }, 1218 | executionCoordinator: executionCoordinatorMetrics, 1219 | }; 1220 | } 1221 | 1222 | /** 1223 | * Cleanup resources and stop timers 1224 | */ 1225 | cleanup(): void { 1226 | if (this.memoryOptimizationInterval) { 1227 | clearInterval(this.memoryOptimizationInterval); 1228 | this.memoryOptimizationInterval = undefined; 1229 | this.logger.debug("Memory optimization timer stopped"); 1230 | } 1231 | } 1232 | 1233 | /** 1234 | * Emergency diagnostic information for troubleshooting 1235 | */ 1236 | getDiagnosticInfo(): { 1237 | timestamp: string; 1238 | health: ReturnType<Application["validateHealth"]>; 1239 | performance: ReturnType<Application["getPerformanceMetrics"]>; 1240 | configuration: { 1241 | transport: string; 1242 | configLoaded: boolean; 1243 | }; 1244 | errors: string[]; 1245 | } { 1246 | const errors: string[] = []; 1247 | 1248 | try { 1249 | // Collect any recent errors or issues 1250 | if (!this.mcpServer) { 1251 | errors.push("MCP Server instance not available"); 1252 | } 1253 | 1254 | if (this._promptsData.length === 0) { 1255 | errors.push("No prompts loaded"); 1256 | } 1257 | 1258 | if (this._categories.length === 0) { 1259 | errors.push("No categories loaded"); 1260 | } 1261 | 1262 | return { 1263 | timestamp: new Date().toISOString(), 1264 | health: this.validateHealth(), 1265 | performance: this.getPerformanceMetrics(), 1266 | configuration: { 1267 | transport: this.transportManager?.getTransportType() || "unknown", 1268 | configLoaded: !!this.configManager, 1269 | }, 1270 | errors, 1271 | }; 1272 | } catch (error) { 1273 | errors.push( 1274 | `Error collecting diagnostic info: ${ 1275 | error instanceof Error ? error.message : String(error) 1276 | }` 1277 | ); 1278 | 1279 | return { 1280 | timestamp: new Date().toISOString(), 1281 | health: { 1282 | healthy: false, 1283 | modules: { 1284 | foundation: false, 1285 | dataLoaded: false, 1286 | modulesInitialized: false, 1287 | serverRunning: false, 1288 | }, 1289 | details: { promptsLoaded: 0, categoriesLoaded: 0, moduleStatus: {} }, 1290 | issues: ["Failed to collect health information"], 1291 | }, 1292 | performance: { 1293 | uptime: process.uptime(), 1294 | memoryUsage: process.memoryUsage(), 1295 | process: { 1296 | pid: process.pid, 1297 | nodeVersion: process.version, 1298 | platform: process.platform, 1299 | arch: process.arch, 1300 | }, 1301 | application: { promptsLoaded: 0, categoriesLoaded: 0 }, 1302 | }, 1303 | configuration: { 1304 | transport: "unknown", 1305 | configLoaded: false, 1306 | }, 1307 | errors, 1308 | }; 1309 | } 1310 | } 1311 | } 1312 | 1313 | /** 1314 | * Create and configure an application runtime 1315 | */ 1316 | export function createApplication(): Application { 1317 | return new Application(); 1318 | } 1319 | 1320 | /** 1321 | * Main application entry point 1322 | */ 1323 | export async function startApplication(): Promise<Application> { 1324 | const application = createApplication(); 1325 | await application.startup(); 1326 | return application; 1327 | } 1328 | ``` -------------------------------------------------------------------------------- /plans/symbolic-command-language-implementation.md: -------------------------------------------------------------------------------- ```markdown 1 | # Symbolic Command Language Implementation Plan 2 | 3 | **Status**: Planning Phase 4 | **Created**: 2025-10-19 5 | **Last Updated**: 2025-10-19 6 | **Priority**: High 7 | **Complexity**: Medium-High 8 | 9 | ## Executive Summary 10 | 11 | Enhance the parser system to support intuitive symbolic operators for dynamic prompt composition, eliminating the need for explicit template files for common workflow patterns like chaining, quality gates, and framework selection. 12 | 13 | **Core Vision**: Transform `>>content_analysis {{content}} --> deep_analysis --> notes = "comprehensive"` into a first-class command syntax. 14 | 15 | ## Problem Statement 16 | 17 | ### Current Limitations 18 | 19 | 1. **Template File Dependency**: Creating multi-step workflows requires: 20 | - Creating markdown template file (e.g., `/prompts/analysis/notes.md`) 21 | - Defining step-by-step instructions 22 | - Manually managing context propagation 23 | - Updating `prompts.json` registry 24 | 25 | 2. **Workflow Rigidity**: 26 | - Fixed execution sequences 27 | - No ad-hoc composition 28 | - Limited dynamic behavior 29 | - Verbose syntax for simple patterns 30 | 31 | 3. **Implicit Quality Control**: 32 | - Gates must be predefined 33 | - No inline validation criteria 34 | - Difficult to express expected outcomes 35 | 36 | 4. **Framework Selection Friction**: 37 | - Requires explicit `system_control` tool call 38 | - Persists globally (can affect other executions) 39 | - No scoped/temporary framework application 40 | 41 | ### User Pain Points 42 | 43 | **Example Current Workflow**: 44 | ```bash 45 | # Step 1: Create template file 46 | cat > prompts/analysis/my_research.md <<EOF 47 | # Research Workflow 48 | {{steps definition...}} 49 | EOF 50 | 51 | # Step 2: Register in prompts.json 52 | # Edit prompts/analysis/prompts.json manually 53 | 54 | # Step 3: Execute 55 | >>my_research topic="AI trends" 56 | ``` 57 | 58 | **Desired Workflow**: 59 | ```bash 60 | # Single command - no template needed 61 | >>web_search "AI trends" --> deep_analysis --> synthesis_report = "actionable insights" 62 | ``` 63 | 64 | ## Proposed Solution: Symbolic Command Language 65 | 66 | ### Operator Catalog 67 | 68 | #### 1. Chain Operator: `-->` (Sequential Execution) 69 | 70 | **Purpose**: Compose prompts into sequential workflows without template files 71 | 72 | **Syntax**: 73 | ```bash 74 | >>prompt1 args --> prompt2 --> prompt3 75 | ``` 76 | 77 | **Examples**: 78 | ```bash 79 | # Simple chain 80 | >>content_analysis {{content}} --> deep_analysis --> note_refinement 81 | 82 | # With arguments 83 | >>web_search query="AI ethics" --> summarize depth="comprehensive" --> translate language="spanish" 84 | 85 | # Multi-step research 86 | >>literature_review topic="quantum computing" --> gap_analysis --> research_proposal 87 | ``` 88 | 89 | **Execution Behavior**: 90 | - Each step receives previous step's output as input 91 | - Automatic variable mapping: `step1_result`, `step2_result`, etc. 92 | - Context preservation across chain 93 | - Session state management via ChainSessionManager 94 | - Gate validation at each step (if enabled) 95 | 96 | **Implementation Mapping**: 97 | - Integrates with existing `ChainExecutor` 98 | - Dynamically generates chain step definitions 99 | - Uses Nunjucks template variables for context passing 100 | 101 | #### 2. Quality Gate Operator: `=` (Validation Criteria) 102 | 103 | **Purpose**: Inline quality validation without predefined gate definitions 104 | 105 | **Syntax**: 106 | ```bash 107 | >>prompt args = "validation criteria" 108 | ``` 109 | 110 | **Examples**: 111 | ```bash 112 | # Code quality validation 113 | >>code_review target="app.ts" = "no type errors, 80% test coverage, follows style guide" 114 | 115 | # Research depth validation 116 | >>deep_research topic="climate change" = "minimum 10 academic sources, peer-reviewed, published after 2020" 117 | 118 | # Content completeness 119 | >>documentation topic="API" = "includes examples, covers error cases, has diagrams" 120 | 121 | # Chain with final gate 122 | >>analysis --> synthesis --> report = "executive summary included, data visualizations present" 123 | ``` 124 | 125 | **Execution Behavior**: 126 | - Parses criteria string into validation requirements 127 | - Creates temporary gate definition with LLM-based evaluation 128 | - Applies gate after execution completes 129 | - Returns pass/fail status with detailed reasoning 130 | - Optional retry on failure (configurable) 131 | 132 | **Implementation Details**: 133 | ```typescript 134 | // Generated temporary gate structure 135 | { 136 | type: 'quality', 137 | name: 'inline_gate_<hash>', 138 | description: 'Inline validation criteria', 139 | criteria: [ 140 | "no type errors", 141 | "80% test coverage", 142 | "follows style guide" 143 | ], 144 | scope: 'execution', 145 | temporary: true 146 | } 147 | ``` 148 | 149 | #### 3. Framework Selector: `@` (Methodology) 150 | 151 | **Purpose**: Apply specific framework/methodology for single execution 152 | 153 | **Syntax**: 154 | ```bash 155 | @FRAMEWORK >>prompt args 156 | ``` 157 | 158 | **Examples**: 159 | ```bash 160 | # CAGEERF for strategic thinking 161 | @CAGEERF >>product_roadmap feature="user_authentication" 162 | 163 | # ReACT for debugging 164 | @ReACT >>debug_issue error="memory_leak" logs="{{logs}}" 165 | 166 | # 5W1H for requirements 167 | @5W1H >>requirements_gathering stakeholder="product_manager" 168 | 169 | # SCAMPER for innovation 170 | @SCAMPER >>brainstorm_features product="smartwatch" 171 | 172 | # Framework with chain 173 | @CAGEERF >>strategic_analysis --> implementation_plan --> risk_assessment 174 | ``` 175 | 176 | **Execution Behavior**: 177 | - Temporarily switches to specified framework 178 | - Applies framework-specific system prompt enhancements 179 | - Executes prompt with framework context 180 | - Automatically reverts to default framework after execution 181 | - Framework name case-insensitive (CAGEERF = cageerf = CaGeErF) 182 | 183 | **Supported Frameworks**: 184 | - `CAGEERF`: Context → Analysis → Goals → Execution → Evaluation → Refinement → Framework 185 | - `ReACT`: Reasoning and Acting for systematic problem-solving 186 | - `5W1H`: Who, What, When, Where, Why, How analysis 187 | - `SCAMPER`: Substitute, Combine, Adapt, Modify, Put to other use, Eliminate, Reverse 188 | 189 | #### 4. Parallel Execution: `+` (Concurrent Analysis) 190 | 191 | **Purpose**: Execute multiple prompts concurrently and aggregate results 192 | 193 | **Syntax**: 194 | ```bash 195 | >>prompt1 args + prompt2 args + prompt3 args 196 | ``` 197 | 198 | **Examples**: 199 | ```bash 200 | # Multi-perspective analysis 201 | >>market_analysis product="X" + competitive_analysis product="X" + user_research product="X" 202 | 203 | # Parallel research 204 | >>academic_search topic="AI" + news_search topic="AI" + patent_search topic="AI" 205 | 206 | # Diverse evaluations 207 | >>code_review_security + code_review_performance + code_review_maintainability 208 | ``` 209 | 210 | **Execution Behavior**: 211 | - Execute all prompts concurrently (true parallelization) 212 | - Aggregate results into unified response 213 | - Include execution time comparison 214 | - Merge metadata from all executions 215 | 216 | **Implementation Notes**: 217 | - Uses `Promise.all()` for concurrent execution 218 | - Each prompt gets independent execution context 219 | - Results combined with section headers 220 | - Useful for independent analyses that don't depend on each other 221 | 222 | #### 5. Conditional Execution: `?` (Decision Branching) 223 | 224 | **Purpose**: Branch execution based on output evaluation 225 | 226 | **Syntax**: 227 | ```bash 228 | >>prompt args ? "condition" : alternative_prompt 229 | ``` 230 | 231 | **Examples**: 232 | ```bash 233 | # Error-aware workflow 234 | >>code_analysis file="app.ts" ? "errors found" : comprehensive_review 235 | 236 | # Complexity-based routing 237 | >>analyze_complexity code="{{code}}" ? "complexity > 10" : simple_refactor : complex_redesign 238 | 239 | # Adaptive research depth 240 | >>initial_research topic="{{topic}}" ? "sufficient depth" : deep_research 241 | ``` 242 | 243 | **Execution Behavior**: 244 | - Execute initial prompt 245 | - LLM evaluates condition against output 246 | - If condition true: execute conditional prompt 247 | - If condition false: execute alternative (or stop) 248 | - Return combined execution path metadata 249 | 250 | **Implementation Complexity**: Phase 3 (advanced feature) 251 | 252 | ### Operator Precedence & Composition 253 | 254 | #### Precedence Rules (Highest to Lowest) 255 | 256 | 1. **`@` Framework** - Applies to entire execution scope 257 | 2. **`?` Conditional** - Determines execution path 258 | 3. **`+` Parallel** - Execution strategy 259 | 4. **`-->` Chain** - Sequential composition 260 | 5. **`=` Gate** - Final validation 261 | 262 | #### Complex Composition Examples 263 | 264 | ```bash 265 | # Framework + Chain + Gate 266 | @CAGEERF >>strategic_analysis topic="market_expansion" --> implementation_roadmap --> risk_assessment = "comprehensive coverage, realistic timelines" 267 | 268 | # Parallel + Chain + Gate 269 | >>market_research + competitive_analysis + user_survey --> synthesis_report = "actionable recommendations" 270 | 271 | # Framework + Conditional + Chain 272 | @ReACT >>diagnose_issue logs="{{logs}}" ? "root cause identified" : deep_investigation --> fix_implementation 273 | 274 | # Full composition 275 | @CAGEERF >>requirement_gathering + technical_feasibility --> architecture_design = "scalable, maintainable" --> implementation_plan 276 | ``` 277 | 278 | #### Parsing Order 279 | 280 | ``` 281 | Input: @CAGEERF >>analysis {{content}} --> synthesis --> notes = "comprehensive" 282 | 283 | Parse Tree: 284 | ├── Framework Operator: @CAGEERF (scope: entire execution) 285 | ├── Chain Operator: --> (3 steps) 286 | │ ├── Step 1: analysis {{content}} 287 | │ ├── Step 2: synthesis 288 | │ └── Step 3: notes 289 | └── Gate Operator: = "comprehensive" (validation on final output) 290 | ``` 291 | 292 | ## Technical Architecture 293 | 294 | ### Phase 1: Foundation - Symbolic Parser (Week 1) 295 | 296 | #### New Files Structure 297 | 298 | ``` 299 | server/src/execution/parsers/ 300 | ├── symbolic-command-parser.ts # Main symbolic parser 301 | ├── operators/ 302 | │ ├── index.ts # Operator exports 303 | │ ├── chain-operator.ts # --> implementation 304 | │ ├── gate-operator.ts # = implementation 305 | │ ├── framework-operator.ts # @ implementation 306 | │ ├── parallel-operator.ts # + implementation 307 | │ └── conditional-operator.ts # ? implementation 308 | └── types/ 309 | ├── operator-types.ts # Operator interfaces 310 | └── parse-result-extensions.ts # Extended CommandParseResult 311 | ``` 312 | 313 | #### Core Type Definitions 314 | 315 | ```typescript 316 | // server/src/execution/parsers/types/operator-types.ts 317 | 318 | /** 319 | * Chain operator representing sequential execution 320 | */ 321 | export interface ChainOperator { 322 | type: 'chain'; 323 | steps: ChainStep[]; 324 | contextPropagation: 'automatic' | 'manual'; 325 | } 326 | 327 | export interface ChainStep { 328 | promptId: string; 329 | args: string; 330 | position: number; 331 | variableName: string; // e.g., "step1_result" 332 | } 333 | 334 | /** 335 | * Quality gate operator for inline validation 336 | */ 337 | export interface GateOperator { 338 | type: 'gate'; 339 | criteria: string; 340 | parsedCriteria: string[]; // Split by commas/logical separators 341 | scope: 'execution' | 'step' | 'chain'; 342 | retryOnFailure: boolean; 343 | maxRetries: number; 344 | } 345 | 346 | /** 347 | * Framework selector operator 348 | */ 349 | export interface FrameworkOperator { 350 | type: 'framework'; 351 | frameworkId: string; 352 | normalizedId: string; // Uppercased for validation 353 | temporary: boolean; // Always true for @ operator 354 | scopeType: 'execution' | 'chain'; 355 | } 356 | 357 | /** 358 | * Parallel execution operator 359 | */ 360 | export interface ParallelOperator { 361 | type: 'parallel'; 362 | prompts: ParallelPrompt[]; 363 | aggregationStrategy: 'merge' | 'compare' | 'summarize'; 364 | } 365 | 366 | export interface ParallelPrompt { 367 | promptId: string; 368 | args: string; 369 | position: number; 370 | } 371 | 372 | /** 373 | * Conditional execution operator 374 | */ 375 | export interface ConditionalOperator { 376 | type: 'conditional'; 377 | condition: string; 378 | conditionType: 'presence' | 'comparison' | 'pattern'; 379 | trueBranch: string; // Prompt ID for true path 380 | falseBranch?: string; // Prompt ID for false path (optional) 381 | } 382 | 383 | /** 384 | * Unified operator container 385 | */ 386 | export type SymbolicOperator = 387 | | ChainOperator 388 | | GateOperator 389 | | FrameworkOperator 390 | | ParallelOperator 391 | | ConditionalOperator; 392 | 393 | /** 394 | * Operator detection result 395 | */ 396 | export interface OperatorDetectionResult { 397 | hasOperators: boolean; 398 | operatorTypes: string[]; // ['chain', 'gate', 'framework'] 399 | operators: SymbolicOperator[]; 400 | parseComplexity: 'simple' | 'moderate' | 'complex'; 401 | } 402 | ``` 403 | 404 | #### Extended CommandParseResult 405 | 406 | ```typescript 407 | // server/src/execution/parsers/types/parse-result-extensions.ts 408 | 409 | import { SymbolicOperator, OperatorDetectionResult } from './operator-types.js'; 410 | 411 | export interface SymbolicCommandParseResult extends CommandParseResult { 412 | format: 'simple' | 'json' | 'symbolic' | 'chain'; 413 | operators?: OperatorDetectionResult; 414 | executionPlan?: ExecutionPlan; 415 | } 416 | 417 | /** 418 | * Execution plan generated from operators 419 | */ 420 | export interface ExecutionPlan { 421 | steps: ExecutionStep[]; 422 | frameworkOverride?: string; 423 | finalValidation?: GateOperator; 424 | estimatedComplexity: number; // 1-10 scale 425 | requiresSessionState: boolean; 426 | } 427 | 428 | export interface ExecutionStep { 429 | stepNumber: number; 430 | type: 'prompt' | 'gate' | 'framework_switch' | 'parallel_group'; 431 | promptId?: string; 432 | args?: string; 433 | dependencies: number[]; // Step numbers this depends on 434 | outputVariable: string; // e.g., "step1_result" 435 | } 436 | ``` 437 | 438 | #### Symbolic Parser Implementation 439 | 440 | ```typescript 441 | // server/src/execution/parsers/symbolic-command-parser.ts 442 | 443 | import { Logger } from "../../logging/index.js"; 444 | import { PromptData } from "../../types/index.js"; 445 | import { ValidationError } from "../../utils/index.js"; 446 | import { 447 | SymbolicCommandParseResult, 448 | OperatorDetectionResult, 449 | SymbolicOperator 450 | } from "./types/index.js"; 451 | 452 | export class SymbolicCommandParser { 453 | private logger: Logger; 454 | 455 | // Operator detection patterns 456 | private readonly OPERATOR_PATTERNS = { 457 | chain: /-->/g, 458 | gate: /\s*=\s*["'](.+?)["']\s*$/, 459 | framework: /^@([A-Za-z0-9]+)\s+/, 460 | parallel: /\s*\+\s*/g, 461 | conditional: /\s*\?\s*["'](.+?)["']\s*:\s*(\w+)/ 462 | }; 463 | 464 | constructor(logger: Logger) { 465 | this.logger = logger; 466 | } 467 | 468 | /** 469 | * Detect symbolic operators in command 470 | */ 471 | public detectOperators(command: string): OperatorDetectionResult { 472 | const operators: SymbolicOperator[] = []; 473 | const operatorTypes: string[] = []; 474 | 475 | // Detect framework operator (@) 476 | const frameworkMatch = command.match(this.OPERATOR_PATTERNS.framework); 477 | if (frameworkMatch) { 478 | operatorTypes.push('framework'); 479 | operators.push({ 480 | type: 'framework', 481 | frameworkId: frameworkMatch[1], 482 | normalizedId: frameworkMatch[1].toUpperCase(), 483 | temporary: true, 484 | scopeType: 'execution' 485 | }); 486 | } 487 | 488 | // Detect chain operator (-->) 489 | const chainMatches = command.match(this.OPERATOR_PATTERNS.chain); 490 | if (chainMatches && chainMatches.length > 0) { 491 | operatorTypes.push('chain'); 492 | operators.push(this.parseChainOperator(command)); 493 | } 494 | 495 | // Detect gate operator (=) 496 | const gateMatch = command.match(this.OPERATOR_PATTERNS.gate); 497 | if (gateMatch) { 498 | operatorTypes.push('gate'); 499 | operators.push({ 500 | type: 'gate', 501 | criteria: gateMatch[1], 502 | parsedCriteria: this.parseCriteria(gateMatch[1]), 503 | scope: 'execution', 504 | retryOnFailure: true, 505 | maxRetries: 1 506 | }); 507 | } 508 | 509 | // Detect parallel operator (+) 510 | const parallelMatches = command.match(this.OPERATOR_PATTERNS.parallel); 511 | if (parallelMatches && parallelMatches.length > 0 && !chainMatches) { 512 | operatorTypes.push('parallel'); 513 | operators.push(this.parseParallelOperator(command)); 514 | } 515 | 516 | // Detect conditional operator (?) 517 | const conditionalMatch = command.match(this.OPERATOR_PATTERNS.conditional); 518 | if (conditionalMatch) { 519 | operatorTypes.push('conditional'); 520 | operators.push({ 521 | type: 'conditional', 522 | condition: conditionalMatch[1], 523 | conditionType: 'presence', 524 | trueBranch: conditionalMatch[2], 525 | falseBranch: undefined 526 | }); 527 | } 528 | 529 | const complexity = this.calculateComplexity(operators); 530 | 531 | return { 532 | hasOperators: operators.length > 0, 533 | operatorTypes, 534 | operators, 535 | parseComplexity: complexity 536 | }; 537 | } 538 | 539 | /** 540 | * Parse chain operator into structured steps 541 | */ 542 | private parseChainOperator(command: string): ChainOperator { 543 | // Remove framework operator if present 544 | let cleanCommand = command.replace(this.OPERATOR_PATTERNS.framework, ''); 545 | 546 | // Remove gate operator if present 547 | cleanCommand = cleanCommand.replace(this.OPERATOR_PATTERNS.gate, ''); 548 | 549 | // Split by chain operator 550 | const stepStrings = cleanCommand.split('-->').map(s => s.trim()); 551 | 552 | const steps = stepStrings.map((stepStr, index) => { 553 | // Parse each step (format: >>prompt_name args or just prompt_name) 554 | const stepMatch = stepStr.match(/^(?:>>)?([a-zA-Z0-9_-]+)(?:\s+(.*))?$/); 555 | 556 | if (!stepMatch) { 557 | throw new ValidationError(`Invalid chain step format: ${stepStr}`); 558 | } 559 | 560 | return { 561 | promptId: stepMatch[1], 562 | args: stepMatch[2] || '', 563 | position: index, 564 | variableName: `step${index + 1}_result` 565 | }; 566 | }); 567 | 568 | return { 569 | type: 'chain', 570 | steps, 571 | contextPropagation: 'automatic' 572 | }; 573 | } 574 | 575 | /** 576 | * Parse parallel operator into concurrent prompts 577 | */ 578 | private parseParallelOperator(command: string): ParallelOperator { 579 | const promptStrings = command.split('+').map(s => s.trim()); 580 | 581 | const prompts = promptStrings.map((promptStr, index) => { 582 | const promptMatch = promptStr.match(/^(?:>>)?([a-zA-Z0-9_-]+)(?:\s+(.*))?$/); 583 | 584 | if (!promptMatch) { 585 | throw new ValidationError(`Invalid parallel prompt format: ${promptStr}`); 586 | } 587 | 588 | return { 589 | promptId: promptMatch[1], 590 | args: promptMatch[2] || '', 591 | position: index 592 | }; 593 | }); 594 | 595 | return { 596 | type: 'parallel', 597 | prompts, 598 | aggregationStrategy: 'merge' 599 | }; 600 | } 601 | 602 | /** 603 | * Parse gate criteria into individual requirements 604 | */ 605 | private parseCriteria(criteriaString: string): string[] { 606 | // Split by common delimiters 607 | return criteriaString 608 | .split(/,|and|\||;/) 609 | .map(c => c.trim()) 610 | .filter(c => c.length > 0); 611 | } 612 | 613 | /** 614 | * Calculate parse complexity based on operators 615 | */ 616 | private calculateComplexity(operators: SymbolicOperator[]): 'simple' | 'moderate' | 'complex' { 617 | if (operators.length === 0) return 'simple'; 618 | if (operators.length === 1) return 'simple'; 619 | if (operators.length === 2) return 'moderate'; 620 | return 'complex'; 621 | } 622 | 623 | /** 624 | * Generate execution plan from operators 625 | */ 626 | public generateExecutionPlan( 627 | operators: OperatorDetectionResult, 628 | basePromptId: string, 629 | baseArgs: string 630 | ): ExecutionPlan { 631 | const steps: ExecutionStep[] = []; 632 | let frameworkOverride: string | undefined; 633 | let finalValidation: GateOperator | undefined; 634 | 635 | // Extract framework override 636 | const frameworkOp = operators.operators.find(op => op.type === 'framework'); 637 | if (frameworkOp && frameworkOp.type === 'framework') { 638 | frameworkOverride = frameworkOp.normalizedId; 639 | } 640 | 641 | // Extract final gate 642 | const gateOp = operators.operators.find(op => op.type === 'gate'); 643 | if (gateOp && gateOp.type === 'gate') { 644 | finalValidation = gateOp; 645 | } 646 | 647 | // Build execution steps based on operator types 648 | const chainOp = operators.operators.find(op => op.type === 'chain'); 649 | if (chainOp && chainOp.type === 'chain') { 650 | // Chain execution 651 | chainOp.steps.forEach((step, index) => { 652 | steps.push({ 653 | stepNumber: index + 1, 654 | type: 'prompt', 655 | promptId: step.promptId, 656 | args: step.args, 657 | dependencies: index > 0 ? [index] : [], 658 | outputVariable: step.variableName 659 | }); 660 | }); 661 | } else { 662 | // Single prompt execution 663 | steps.push({ 664 | stepNumber: 1, 665 | type: 'prompt', 666 | promptId: basePromptId, 667 | args: baseArgs, 668 | dependencies: [], 669 | outputVariable: 'result' 670 | }); 671 | } 672 | 673 | return { 674 | steps, 675 | frameworkOverride, 676 | finalValidation, 677 | estimatedComplexity: operators.operators.length, 678 | requiresSessionState: steps.length > 1 679 | }; 680 | } 681 | } 682 | 683 | export function createSymbolicCommandParser(logger: Logger): SymbolicCommandParser { 684 | return new SymbolicCommandParser(logger); 685 | } 686 | ``` 687 | 688 | ### Phase 2: Operator Executors (Week 2) 689 | 690 | #### Chain Operator Execution 691 | 692 | ```typescript 693 | // server/src/execution/operators/chain-executor.ts 694 | 695 | import { ChainOperator, ChainStep } from "../parsers/types/operator-types.js"; 696 | import { ChainExecutor } from "../../mcp-tools/prompt-engine/core/executor.js"; 697 | 698 | export class ChainOperatorExecutor { 699 | private chainExecutor: ChainExecutor; 700 | 701 | constructor(chainExecutor: ChainExecutor) { 702 | this.chainExecutor = chainExecutor; 703 | } 704 | 705 | /** 706 | * Execute chain operator by generating dynamic chain definition 707 | */ 708 | async execute( 709 | chainOp: ChainOperator, 710 | initialContext: Record<string, any> 711 | ): Promise<any> { 712 | // Convert chain operator to chain execution format 713 | const chainSteps = chainOp.steps.map(step => ({ 714 | prompt: step.promptId, 715 | arguments: this.parseStepArguments(step.args, initialContext) 716 | })); 717 | 718 | // Generate temporary chain prompt definition 719 | const chainPrompt = this.generateChainPrompt(chainSteps); 720 | 721 | // Execute using existing ChainExecutor 722 | return await this.chainExecutor.executeChain({ 723 | promptId: '__dynamic_chain__', 724 | promptArgs: initialContext, 725 | convertedPrompt: chainPrompt, 726 | chainGateIds: [], 727 | chainExecutionId: `chain_${Date.now()}` 728 | }, { 729 | enableGates: true, 730 | session_id: `symbolic_${Date.now()}` 731 | }); 732 | } 733 | 734 | private parseStepArguments( 735 | argsString: string, 736 | context: Record<string, any> 737 | ): Record<string, any> { 738 | // Parse argument string into object 739 | // Support both "key=value" and template variables "{{var}}" 740 | const args: Record<string, any> = {}; 741 | 742 | // Simple parsing - can be enhanced 743 | const kvPairs = argsString.match(/(\w+)="([^"]*)"/g); 744 | if (kvPairs) { 745 | kvPairs.forEach(pair => { 746 | const [key, value] = pair.split('='); 747 | args[key] = value.replace(/"/g, ''); 748 | }); 749 | } else if (argsString.trim()) { 750 | // Single argument, map to 'content' or 'input' 751 | args.content = argsString.trim(); 752 | } 753 | 754 | return args; 755 | } 756 | 757 | private generateChainPrompt(steps: any[]): any { 758 | // Generate ConvertedPrompt structure 759 | return { 760 | id: '__dynamic_chain__', 761 | name: 'Dynamic Chain', 762 | type: 'chain', 763 | steps: steps, 764 | metadata: { 765 | generatedFrom: 'symbolic_operator', 766 | timestamp: new Date().toISOString() 767 | } 768 | }; 769 | } 770 | } 771 | ``` 772 | 773 | #### Gate Operator Execution 774 | 775 | ```typescript 776 | // server/src/execution/operators/gate-executor.ts 777 | 778 | import { GateOperator } from "../parsers/types/operator-types.js"; 779 | import { LightweightGateSystem } from "../../gates/core/index.js"; 780 | import type { TemporaryGateDefinition } from "../../gates/core/temporary-gate-registry.js"; 781 | 782 | export class GateOperatorExecutor { 783 | private gateSystem: LightweightGateSystem; 784 | 785 | constructor(gateSystem: LightweightGateSystem) { 786 | this.gateSystem = gateSystem; 787 | } 788 | 789 | /** 790 | * Execute gate operator by creating temporary gate and validating 791 | */ 792 | async execute( 793 | gateOp: GateOperator, 794 | executionResult: any, 795 | executionId: string 796 | ): Promise<{ 797 | passed: boolean; 798 | gateResults: any; 799 | retryRequired: boolean; 800 | }> { 801 | // Generate temporary gate definition 802 | const gateDefinition: TemporaryGateDefinition = { 803 | name: `inline_gate_${Date.now()}`, 804 | type: 'quality', 805 | scope: gateOp.scope, 806 | description: `Inline validation: ${gateOp.criteria}`, 807 | guidance: this.generateGateGuidance(gateOp.parsedCriteria), 808 | pass_criteria: gateOp.parsedCriteria 809 | }; 810 | 811 | // Register temporary gate 812 | const gateId = await this.gateSystem.registerTemporaryGate( 813 | gateDefinition, 814 | executionId 815 | ); 816 | 817 | // Evaluate gate 818 | const gateResults = await this.gateSystem.evaluateGates( 819 | [gateId], 820 | executionResult 821 | ); 822 | 823 | const passed = gateResults.every((r: any) => r.passed); 824 | const retryRequired = !passed && gateOp.retryOnFailure; 825 | 826 | return { 827 | passed, 828 | gateResults, 829 | retryRequired 830 | }; 831 | } 832 | 833 | private generateGateGuidance(criteria: string[]): string { 834 | return `Evaluate the output against these criteria:\n${criteria.map((c, i) => `${i + 1}. ${c}`).join('\n')}`; 835 | } 836 | } 837 | ``` 838 | 839 | #### Framework Operator Execution 840 | 841 | ```typescript 842 | // server/src/execution/operators/framework-executor.ts 843 | 844 | import { FrameworkOperator } from "../parsers/types/operator-types.js"; 845 | import { FrameworkStateManager } from "../../frameworks/framework-state-manager.js"; 846 | 847 | export class FrameworkOperatorExecutor { 848 | private frameworkStateManager: FrameworkStateManager; 849 | private originalFramework: string | null = null; 850 | 851 | constructor(frameworkStateManager: FrameworkStateManager) { 852 | this.frameworkStateManager = frameworkStateManager; 853 | } 854 | 855 | /** 856 | * Apply framework override before execution 857 | */ 858 | async applyFrameworkOverride(frameworkOp: FrameworkOperator): Promise<void> { 859 | // Store original framework 860 | const currentFramework = this.frameworkStateManager.getCurrentFramework(); 861 | this.originalFramework = currentFramework.frameworkId; 862 | 863 | // Temporarily switch to requested framework 864 | await this.frameworkStateManager.switchFramework( 865 | frameworkOp.normalizedId, 866 | `Symbolic operator: temporary framework switch` 867 | ); 868 | } 869 | 870 | /** 871 | * Restore original framework after execution 872 | */ 873 | async restoreFramework(): Promise<void> { 874 | if (this.originalFramework) { 875 | await this.frameworkStateManager.switchFramework( 876 | this.originalFramework, 877 | `Restoring framework after symbolic operator execution` 878 | ); 879 | this.originalFramework = null; 880 | } 881 | } 882 | 883 | /** 884 | * Execute with framework context (try-finally pattern) 885 | */ 886 | async executeWithFramework<T>( 887 | frameworkOp: FrameworkOperator, 888 | executionFn: () => Promise<T> 889 | ): Promise<T> { 890 | try { 891 | await this.applyFrameworkOverride(frameworkOp); 892 | return await executionFn(); 893 | } finally { 894 | await this.restoreFramework(); 895 | } 896 | } 897 | } 898 | ``` 899 | 900 | ### Phase 3: Integration (Week 3) 901 | 902 | #### UnifiedCommandParser Enhancement 903 | 904 | ```typescript 905 | // Additions to server/src/execution/parsers/unified-command-parser.ts 906 | 907 | import { SymbolicCommandParser } from './symbolic-command-parser.js'; 908 | import { SymbolicCommandParseResult } from './types/parse-result-extensions.js'; 909 | 910 | export class UnifiedCommandParser { 911 | private symbolicParser: SymbolicCommandParser; 912 | 913 | // ... existing code ... 914 | 915 | private initializeStrategies(): ParsingStrategy[] { 916 | return [ 917 | this.createSymbolicCommandStrategy(), // NEW - Highest priority 918 | this.createSimpleCommandStrategy(), 919 | this.createJsonCommandStrategy() 920 | ]; 921 | } 922 | 923 | /** 924 | * NEW: Symbolic command strategy (highest priority) 925 | */ 926 | private createSymbolicCommandStrategy(): ParsingStrategy { 927 | return { 928 | name: 'symbolic', 929 | confidence: 0.95, 930 | canHandle: (command: string) => { 931 | // Detect any symbolic operators 932 | return /-->|=\s*["']|^@[A-Za-z0-9]+|\+|[\?]/.test(command); 933 | }, 934 | parse: (command: string): SymbolicCommandParseResult | null => { 935 | try { 936 | // Detect operators 937 | const operators = this.symbolicParser.detectOperators(command); 938 | 939 | if (!operators.hasOperators) { 940 | return null; // Fallback to other strategies 941 | } 942 | 943 | // Extract base prompt ID (first prompt in chain/composition) 944 | let basePromptId: string; 945 | let baseArgs: string; 946 | 947 | // Remove framework prefix if present 948 | let cleanCommand = command.replace(/^@[A-Za-z0-9]+\s+/, ''); 949 | 950 | // Remove gate suffix if present 951 | cleanCommand = cleanCommand.replace(/\s*=\s*["'].+["']\s*$/, ''); 952 | 953 | // Extract first prompt 954 | const firstPromptMatch = cleanCommand.match(/^(?:>>)?([a-zA-Z0-9_-]+)(?:\s+([^-]*))?/); 955 | if (!firstPromptMatch) { 956 | return null; 957 | } 958 | 959 | basePromptId = firstPromptMatch[1]; 960 | baseArgs = firstPromptMatch[2] || ''; 961 | 962 | // Generate execution plan 963 | const executionPlan = this.symbolicParser.generateExecutionPlan( 964 | operators, 965 | basePromptId, 966 | baseArgs 967 | ); 968 | 969 | return { 970 | promptId: basePromptId, 971 | rawArgs: baseArgs, 972 | format: 'symbolic', 973 | confidence: 0.95, 974 | operators: operators, 975 | executionPlan: executionPlan, 976 | metadata: { 977 | originalCommand: command, 978 | parseStrategy: 'symbolic', 979 | detectedFormat: `Symbolic (${operators.operatorTypes.join(', ')})`, 980 | warnings: [] 981 | } 982 | }; 983 | } catch (error) { 984 | this.logger.error('Symbolic parsing failed:', error); 985 | return null; // Fallback to other strategies 986 | } 987 | } 988 | }; 989 | } 990 | } 991 | ``` 992 | 993 | #### ConsolidatedPromptEngine Integration 994 | 995 | ```typescript 996 | // Additions to server/src/mcp-tools/prompt-engine/core/engine.ts 997 | 998 | import { ChainOperatorExecutor } from '../../../execution/operators/chain-executor.js'; 999 | import { GateOperatorExecutor } from '../../../execution/operators/gate-executor.js'; 1000 | import { FrameworkOperatorExecutor } from '../../../execution/operators/framework-executor.js'; 1001 | 1002 | export class ConsolidatedPromptEngine { 1003 | private chainOperatorExecutor: ChainOperatorExecutor; 1004 | private gateOperatorExecutor: GateOperatorExecutor; 1005 | private frameworkOperatorExecutor: FrameworkOperatorExecutor; 1006 | 1007 | // ... existing code ... 1008 | 1009 | async execute(command: string, options: any = {}): Promise<ToolResponse> { 1010 | // Parse command (now includes symbolic operators) 1011 | const parseResult = await this.parsingSystem.commandParser.parseCommand( 1012 | command, 1013 | this.promptsData 1014 | ); 1015 | 1016 | // Check if symbolic operators detected 1017 | if (parseResult.format === 'symbolic' && parseResult.executionPlan) { 1018 | return await this.executeSymbolicCommand(parseResult, options); 1019 | } 1020 | 1021 | // ... existing execution logic ... 1022 | } 1023 | 1024 | /** 1025 | * NEW: Execute command with symbolic operators 1026 | */ 1027 | private async executeSymbolicCommand( 1028 | parseResult: SymbolicCommandParseResult, 1029 | options: any 1030 | ): Promise<ToolResponse> { 1031 | const { executionPlan, operators } = parseResult; 1032 | let result: any; 1033 | 1034 | try { 1035 | // Step 1: Apply framework override if present 1036 | const frameworkOp = operators?.operators.find(op => op.type === 'framework'); 1037 | if (frameworkOp && frameworkOp.type === 'framework') { 1038 | return await this.frameworkOperatorExecutor.executeWithFramework( 1039 | frameworkOp, 1040 | async () => { 1041 | // Execute chain or single prompt within framework context 1042 | return await this.executeWithinFramework(parseResult, options); 1043 | } 1044 | ); 1045 | } 1046 | 1047 | // Step 2: Execute without framework override 1048 | result = await this.executeWithinFramework(parseResult, options); 1049 | 1050 | return result; 1051 | } catch (error) { 1052 | this.logger.error('Symbolic command execution failed:', error); 1053 | throw error; 1054 | } 1055 | } 1056 | 1057 | /** 1058 | * Execute chain or single prompt (with or without framework context) 1059 | */ 1060 | private async executeWithinFramework( 1061 | parseResult: SymbolicCommandParseResult, 1062 | options: any 1063 | ): Promise<ToolResponse> { 1064 | const { executionPlan, operators } = parseResult; 1065 | let result: any; 1066 | 1067 | // Check for chain operator 1068 | const chainOp = operators?.operators.find(op => op.type === 'chain'); 1069 | 1070 | if (chainOp && chainOp.type === 'chain') { 1071 | // Execute chain 1072 | result = await this.chainOperatorExecutor.execute( 1073 | chainOp, 1074 | parseResult.rawArgs ? { content: parseResult.rawArgs } : {} 1075 | ); 1076 | } else { 1077 | // Execute single prompt (existing logic) 1078 | result = await this.executeSinglePrompt(parseResult, options); 1079 | } 1080 | 1081 | // Step 3: Apply gate validation if present 1082 | const gateOp = operators?.operators.find(op => op.type === 'gate'); 1083 | if (gateOp && gateOp.type === 'gate') { 1084 | const gateResult = await this.gateOperatorExecutor.execute( 1085 | gateOp, 1086 | result, 1087 | `exec_${Date.now()}` 1088 | ); 1089 | 1090 | // Attach gate results to response 1091 | result.gateValidation = gateResult; 1092 | 1093 | // Handle retry if needed 1094 | if (gateResult.retryRequired) { 1095 | this.logger.warn('Gate validation failed, retry required'); 1096 | // Could implement retry logic here 1097 | } 1098 | } 1099 | 1100 | return result; 1101 | } 1102 | } 1103 | ``` 1104 | 1105 | ## Implementation Phases 1106 | 1107 | ### Phase 1: Foundation (Week 1) - Chain Operator Only 1108 | 1109 | **Goals**: 1110 | - ✅ Implement symbolic parser foundation 1111 | - ✅ Chain operator (`-->`) detection and parsing 1112 | - ✅ Integration with existing ChainExecutor 1113 | - ✅ Comprehensive tests 1114 | 1115 | **Deliverables**: 1116 | - `symbolic-command-parser.ts` 1117 | - `chain-operator.ts` 1118 | - `chain-executor.ts` (operator executor) 1119 | - Test suite for chain operator 1120 | - Documentation: basic chaining examples 1121 | 1122 | **Success Criteria**: 1123 | ```bash 1124 | # Must work: 1125 | >>content_analysis {{content}} --> deep_analysis --> notes 1126 | >>web_search "AI trends" --> summarize --> translate language="spanish" 1127 | ``` 1128 | 1129 | ### Phase 2: Quality Gates (Week 2) - Gate Operator 1130 | 1131 | **Goals**: 1132 | - ✅ Gate operator (`=`) detection and parsing 1133 | - ✅ Temporary gate definition generation 1134 | - ✅ LLM-based validation execution 1135 | - ✅ Retry logic implementation 1136 | 1137 | **Deliverables**: 1138 | - `gate-operator.ts` 1139 | - `gate-executor.ts` 1140 | - Gate criteria parsing logic 1141 | - Test suite for gate operator 1142 | - Documentation: inline quality validation 1143 | 1144 | **Success Criteria**: 1145 | ```bash 1146 | # Must work: 1147 | >>code_review target="app.ts" = "no type errors, 80% coverage" 1148 | >>deep_research topic="AI" --> synthesis = "comprehensive, actionable" 1149 | ``` 1150 | 1151 | ### Phase 3: Framework & Advanced (Week 3) 1152 | 1153 | **Goals**: 1154 | - ✅ Framework operator (`@`) implementation 1155 | - ✅ Temporary framework switching 1156 | - ✅ Parallel operator (`+`) foundation 1157 | - ✅ Complex composition support 1158 | 1159 | **Deliverables**: 1160 | - `framework-operator.ts` 1161 | - `framework-executor.ts` 1162 | - `parallel-operator.ts` (basic version) 1163 | - Combined operator tests 1164 | - Documentation: advanced compositions 1165 | 1166 | **Success Criteria**: 1167 | ```bash 1168 | # Must work: 1169 | @CAGEERF >>strategic_planning project="feature_x" 1170 | @ReACT >>debug_issue error="memory_leak" --> fix_implementation 1171 | >>market_analysis + competitive_analysis + user_research 1172 | ``` 1173 | 1174 | ### Phase 4: Polish & Documentation (Week 4) 1175 | 1176 | **Goals**: 1177 | - ✅ Comprehensive documentation 1178 | - ✅ Error message improvements 1179 | - ✅ Performance optimization 1180 | - ✅ Example library 1181 | 1182 | **Deliverables**: 1183 | - `/docs/symbolic-command-language.md` 1184 | - `/docs/operator-reference.md` 1185 | - `/docs/chaining-examples.md` 1186 | - Performance benchmarks 1187 | - User migration guide 1188 | 1189 | ## Testing Strategy 1190 | 1191 | ### Unit Tests 1192 | 1193 | ```typescript 1194 | // tests/unit/symbolic-parser.test.ts 1195 | 1196 | describe('SymbolicCommandParser', () => { 1197 | describe('Chain Operator Detection', () => { 1198 | it('should detect simple chain', () => { 1199 | const parser = createSymbolicCommandParser(logger); 1200 | const result = parser.detectOperators('>>step1 --> step2 --> step3'); 1201 | 1202 | expect(result.hasOperators).toBe(true); 1203 | expect(result.operatorTypes).toContain('chain'); 1204 | expect(result.operators[0].type).toBe('chain'); 1205 | expect(result.operators[0].steps).toHaveLength(3); 1206 | }); 1207 | 1208 | it('should parse chain with arguments', () => { 1209 | const parser = createSymbolicCommandParser(logger); 1210 | const result = parser.detectOperators( 1211 | '>>analyze content="{{text}}" --> summarize depth="detailed"' 1212 | ); 1213 | 1214 | const chainOp = result.operators[0]; 1215 | expect(chainOp.steps[0].promptId).toBe('analyze'); 1216 | expect(chainOp.steps[0].args).toBe('content="{{text}}"'); 1217 | expect(chainOp.steps[1].promptId).toBe('summarize'); 1218 | expect(chainOp.steps[1].args).toBe('depth="detailed"'); 1219 | }); 1220 | }); 1221 | 1222 | describe('Gate Operator Detection', () => { 1223 | it('should detect gate criteria', () => { 1224 | const parser = createSymbolicCommandParser(logger); 1225 | const result = parser.detectOperators( 1226 | '>>code_review target="app.ts" = "no errors, 80% coverage"' 1227 | ); 1228 | 1229 | expect(result.operatorTypes).toContain('gate'); 1230 | const gateOp = result.operators.find(op => op.type === 'gate'); 1231 | expect(gateOp.parsedCriteria).toHaveLength(2); 1232 | expect(gateOp.parsedCriteria[0]).toBe('no errors'); 1233 | expect(gateOp.parsedCriteria[1]).toBe('80% coverage'); 1234 | }); 1235 | }); 1236 | 1237 | describe('Framework Operator Detection', () => { 1238 | it('should detect framework selector', () => { 1239 | const parser = createSymbolicCommandParser(logger); 1240 | const result = parser.detectOperators('@CAGEERF >>strategic_planning'); 1241 | 1242 | expect(result.operatorTypes).toContain('framework'); 1243 | const frameworkOp = result.operators.find(op => op.type === 'framework'); 1244 | expect(frameworkOp.frameworkId).toBe('CAGEERF'); 1245 | expect(frameworkOp.normalizedId).toBe('CAGEERF'); 1246 | expect(frameworkOp.temporary).toBe(true); 1247 | }); 1248 | 1249 | it('should handle case-insensitive framework names', () => { 1250 | const parser = createSymbolicCommandParser(logger); 1251 | const result = parser.detectOperators('@react >>analyze'); 1252 | 1253 | const frameworkOp = result.operators.find(op => op.type === 'framework'); 1254 | expect(frameworkOp.normalizedId).toBe('REACT'); 1255 | }); 1256 | }); 1257 | 1258 | describe('Complex Compositions', () => { 1259 | it('should parse framework + chain + gate', () => { 1260 | const parser = createSymbolicCommandParser(logger); 1261 | const result = parser.detectOperators( 1262 | '@CAGEERF >>analysis --> synthesis --> report = "comprehensive"' 1263 | ); 1264 | 1265 | expect(result.operatorTypes).toHaveLength(3); 1266 | expect(result.operatorTypes).toContain('framework'); 1267 | expect(result.operatorTypes).toContain('chain'); 1268 | expect(result.operatorTypes).toContain('gate'); 1269 | }); 1270 | }); 1271 | }); 1272 | ``` 1273 | 1274 | ### Integration Tests 1275 | 1276 | ```typescript 1277 | // tests/integration/symbolic-execution.test.ts 1278 | 1279 | describe('Symbolic Command Execution', () => { 1280 | it('should execute simple chain', async () => { 1281 | const engine = createConsolidatedPromptEngine(/* ... */); 1282 | const result = await engine.execute( 1283 | '>>content_analysis "test content" --> deep_analysis' 1284 | ); 1285 | 1286 | expect(result).toBeDefined(); 1287 | expect(result.metadata.executionType).toBe('chain'); 1288 | expect(result.metadata.stepsExecuted).toBe(2); 1289 | }); 1290 | 1291 | it('should apply inline gate validation', async () => { 1292 | const engine = createConsolidatedPromptEngine(/* ... */); 1293 | const result = await engine.execute( 1294 | '>>code_review target="app.ts" = "no type errors"' 1295 | ); 1296 | 1297 | expect(result.gateValidation).toBeDefined(); 1298 | expect(result.gateValidation.passed).toBeDefined(); 1299 | }); 1300 | 1301 | it('should execute with framework override', async () => { 1302 | const engine = createConsolidatedPromptEngine(/* ... */); 1303 | const result = await engine.execute( 1304 | '@ReACT >>debug_issue error="memory leak"' 1305 | ); 1306 | 1307 | expect(result.metadata.frameworkUsed).toBe('ReACT'); 1308 | }); 1309 | }); 1310 | ``` 1311 | 1312 | ## Documentation Plan 1313 | 1314 | ### User Documentation 1315 | 1316 | **File**: `/docs/symbolic-command-language.md` 1317 | 1318 | **Contents**: 1319 | 1. Introduction to symbolic operators 1320 | 2. Quick start examples 1321 | 3. Operator reference with examples 1322 | 4. Complex composition patterns 1323 | 5. Best practices 1324 | 6. Troubleshooting 1325 | 1326 | **File**: `/docs/operator-reference.md` 1327 | 1328 | **Contents**: 1329 | - Detailed operator specifications 1330 | - Syntax diagrams 1331 | - Parameter options 1332 | - Execution behavior 1333 | - Error handling 1334 | 1335 | **File**: `/docs/chaining-examples.md` 1336 | 1337 | **Contents**: 1338 | - Research workflows 1339 | - Code review workflows 1340 | - Content processing pipelines 1341 | - Multi-stage analysis patterns 1342 | - Quality-gated executions 1343 | 1344 | ### Developer Documentation 1345 | 1346 | **Updates to**: `/CLAUDE.md` 1347 | 1348 | **New Section**: "Symbolic Command Language" 1349 | - Parser architecture 1350 | - Operator implementation guide 1351 | - Adding new operators 1352 | - Testing requirements 1353 | 1354 | ## Migration Path 1355 | 1356 | ### Backward Compatibility 1357 | 1358 | ✅ **100% Backward Compatible** 1359 | - All existing command syntax continues to work 1360 | - No breaking changes to API 1361 | - Symbolic operators are additive enhancement 1362 | - Fallback to existing parsers if symbolic parsing fails 1363 | 1364 | ### Template File Migration (Optional) 1365 | 1366 | **Automatic detection**: Templates with simple patterns can suggest symbolic equivalents 1367 | 1368 | Example migration suggestions: 1369 | ``` 1370 | Current template: /prompts/analysis/research_chain.md 1371 | Symbolic equivalent: >>web_search --> deep_analysis --> synthesis_report 1372 | 1373 | Consider using symbolic syntax for simpler workflows! 1374 | ``` 1375 | 1376 | ## Performance Considerations 1377 | 1378 | ### Parser Performance 1379 | 1380 | **Operator Detection**: O(n) single pass through command string 1381 | - Regex matching for each operator type 1382 | - No backtracking 1383 | - Early termination on match 1384 | 1385 | **Expected Overhead**: < 5ms for typical commands 1386 | 1387 | ### Execution Performance 1388 | 1389 | **Chain Operator**: Same as existing ChainExecutor (no overhead) 1390 | **Gate Operator**: +100-500ms for LLM validation (one-time per gate) 1391 | **Framework Operator**: < 50ms for framework switching 1392 | 1393 | ### Optimization Strategies 1394 | 1395 | 1. **Operator Detection Caching**: Cache operator patterns per session 1396 | 2. **Lazy Evaluation**: Only parse operators when needed 1397 | 3. **Parallel Gate Evaluation**: Evaluate multiple gates concurrently 1398 | 4. **Framework Switch Batching**: Batch multiple framework switches 1399 | 1400 | ## Security Considerations 1401 | 1402 | ### Input Validation 1403 | 1404 | **Operator Injection Prevention**: 1405 | - Sanitize all operator inputs 1406 | - Validate framework names against whitelist 1407 | - Escape special characters in criteria strings 1408 | - Limit chain depth (max 10 steps) 1409 | 1410 | **Gate Criteria Validation**: 1411 | - Prevent code injection in criteria 1412 | - Limit criteria length (max 500 chars) 1413 | - Sanitize LLM evaluation prompts 1414 | 1415 | ### Execution Limits 1416 | 1417 | **Resource Limits**: 1418 | - Max chain depth: 10 steps 1419 | - Max parallel prompts: 5 concurrent 1420 | - Max gate retries: 3 attempts 1421 | - Execution timeout: 5 minutes 1422 | 1423 | ## Open Questions & Decisions 1424 | 1425 | ### Question 1: Escaping Special Characters 1426 | 1427 | **Problem**: How to use literal `-->`, `=`, `@`, `+`, `?` in arguments? 1428 | 1429 | **Options**: 1430 | - A) Quote entire argument: `content="text with --> arrow"` 1431 | - B) Escape characters: `content=text with \-\-> arrow` 1432 | - C) Raw string syntax: `content=r"text with --> arrow"` 1433 | 1434 | **Decision**: **Option A** (quoting) - Most intuitive, aligns with shell conventions 1435 | 1436 | ### Question 2: Nested Chains 1437 | 1438 | **Problem**: Should we support nested/grouped chains? 1439 | 1440 | **Example**: `(>>a --> b) + (>>c --> d)` 1441 | 1442 | **Options**: 1443 | - A) Phase 5 enhancement (not MVP) 1444 | - B) Implement with parentheses from start 1445 | - C) Never support (keep simple) 1446 | 1447 | **Decision**: **Option A** - Defer to Phase 5, gather user feedback first 1448 | 1449 | ### Question 3: Gate Failure Handling 1450 | 1451 | **Problem**: What happens when gate validation fails? 1452 | 1453 | **Options**: 1454 | - A) Automatic retry (configurable max attempts) 1455 | - B) Return error, let user decide 1456 | - C) Prompt user for retry decision 1457 | 1458 | **Decision**: **Option A** - Auto-retry once by default, configurable via gate operator parameters 1459 | 1460 | ### Question 4: Framework Persistence 1461 | 1462 | **Problem**: Should `@FRAMEWORK` persist beyond single execution? 1463 | 1464 | **Options**: 1465 | - A) Always temporary (revert after execution) 1466 | - B) Option to make persistent: `@@FRAMEWORK` (sticky) 1467 | - C) User setting controls default behavior 1468 | 1469 | **Decision**: **Option A** - Keep simple, use `system_control` for persistent switching 1470 | 1471 | ### Question 5: Operator Aliases 1472 | 1473 | **Problem**: Should we support Unicode operators as aliases? 1474 | 1475 | **Examples**: 1476 | - `→` for `-->` 1477 | - `⚡` for `@` 1478 | - `✓` for `=` 1479 | 1480 | **Options**: 1481 | - A) Support with deprecation warning 1482 | - B) Never support (ASCII only) 1483 | - C) Full support, no warnings 1484 | 1485 | **Decision**: **Option B** - ASCII only for maximum compatibility 1486 | 1487 | ### Question 6: Parallel Aggregation Strategies 1488 | 1489 | **Problem**: How to combine results from parallel execution? 1490 | 1491 | **Options**: 1492 | - A) Simple concatenation (default) 1493 | - B) Explicit aggregator: `>>a + b + c | merge_strategy` 1494 | - C) LLM-based synthesis 1495 | 1496 | **Decision**: **Option A** for MVP, **Option C** for Phase 4 enhancement 1497 | 1498 | ## Success Metrics 1499 | 1500 | ### Adoption Metrics 1501 | 1502 | **Target Goals**: 1503 | - 30% of users try symbolic operators within 1 month 1504 | - 50% reduction in template file creation 1505 | - 80% satisfaction rating for symbolic syntax 1506 | 1507 | **Tracking**: 1508 | - Operator usage statistics 1509 | - Template file creation trends 1510 | - User feedback surveys 1511 | 1512 | ### Performance Metrics 1513 | 1514 | **Target Goals**: 1515 | - < 5ms parsing overhead 1516 | - < 50ms framework switching overhead 1517 | - 95% operator detection accuracy 1518 | 1519 | **Monitoring**: 1520 | - Parser performance metrics 1521 | - Execution time tracking 1522 | - Error rate monitoring 1523 | 1524 | ### Quality Metrics 1525 | 1526 | **Target Goals**: 1527 | - 0 breaking changes to existing functionality 1528 | - 90%+ test coverage for new code 1529 | - < 1% regression rate 1530 | 1531 | **Validation**: 1532 | - Comprehensive test suite 1533 | - Backward compatibility tests 1534 | - Performance benchmarks 1535 | 1536 | ## Risk Assessment 1537 | 1538 | ### High Risk: Parser Complexity 1539 | 1540 | **Risk**: Symbolic parser becomes too complex, hard to maintain 1541 | 1542 | **Mitigation**: 1543 | - Modular operator design (one operator = one file) 1544 | - Comprehensive test coverage 1545 | - Progressive enhancement (one operator at a time) 1546 | - Clear documentation 1547 | 1548 | ### Medium Risk: User Confusion 1549 | 1550 | **Risk**: Users confused by multiple command syntaxes 1551 | 1552 | **Mitigation**: 1553 | - Clear documentation with examples 1554 | - Error messages suggest correct syntax 1555 | - Migration guide for template users 1556 | - Interactive tutorial 1557 | 1558 | ### Low Risk: Performance Degradation 1559 | 1560 | **Risk**: Operator detection slows down parsing 1561 | 1562 | **Mitigation**: 1563 | - Performance benchmarks 1564 | - Optimization strategies 1565 | - Caching mechanisms 1566 | - Lazy evaluation 1567 | 1568 | ## Next Steps 1569 | 1570 | ### Immediate Actions (This Week) 1571 | 1572 | 1. ✅ Review and approve plan 1573 | 2. ⏳ Create feature branch: `feature/symbolic-command-language` 1574 | 3. ⏳ Set up test infrastructure 1575 | 4. ⏳ Begin Phase 1 implementation (chain operator) 1576 | 1577 | ### Phase 1 Kickoff (Week 1) 1578 | 1579 | **Day 1-2**: Foundation 1580 | - Create symbolic parser file structure 1581 | - Implement operator detection framework 1582 | - Write basic type definitions 1583 | 1584 | **Day 3-4**: Chain Operator 1585 | - Implement chain operator parsing 1586 | - Create chain executor 1587 | - Write unit tests 1588 | 1589 | **Day 5**: Integration 1590 | - Integrate with UnifiedCommandParser 1591 | - Add to ConsolidatedPromptEngine 1592 | - Write integration tests 1593 | 1594 | ### Success Checkpoint 1595 | 1596 | **Phase 1 Complete When**: 1597 | ✅ Chain operator fully functional 1598 | ✅ 90%+ test coverage 1599 | ✅ Integration tests passing 1600 | ✅ Documentation complete 1601 | ✅ User feedback collected 1602 | 1603 | --- 1604 | 1605 | ## Appendix: Example Use Cases 1606 | 1607 | ### Research Workflow 1608 | 1609 | ```bash 1610 | # Literature review to publication pipeline 1611 | @CAGEERF >>literature_search topic="quantum computing" --> gap_analysis --> research_proposal = "novel contribution, feasible methodology" 1612 | ``` 1613 | 1614 | ### Code Review Pipeline 1615 | 1616 | ```bash 1617 | # Multi-stage code review with quality gates 1618 | >>static_analysis file="app.ts" --> security_review --> performance_review = "no vulnerabilities, optimized algorithms" --> approval 1619 | ``` 1620 | 1621 | ### Content Creation Workflow 1622 | 1623 | ```bash 1624 | # Multi-perspective content generation 1625 | >>outline_generator topic="AI ethics" + competitor_analysis + seo_research --> content_creation = "comprehensive, SEO-optimized, original" 1626 | ``` 1627 | 1628 | ### Debugging Workflow 1629 | 1630 | ```bash 1631 | # Systematic debugging with ReACT methodology 1632 | @ReACT >>error_analysis logs="{{logs}}" --> root_cause_identification --> fix_proposal ? "fix validated" : comprehensive_test_suite 1633 | ``` 1634 | 1635 | ### Market Analysis 1636 | 1637 | ```bash 1638 | # Parallel market research synthesis 1639 | >>market_trends + competitor_landscape + customer_feedback --> synthesis_report = "data-driven recommendations, risk assessment" 1640 | ``` 1641 | 1642 | --- 1643 | 1644 | **End of Implementation Plan** 1645 | 1646 | This plan will be updated as implementation progresses and new insights emerge. 1647 | ```