UNPKG

@simonecoelhosfo/optimizely-mcp-server

Version:

Optimizely MCP Server for AI assistants with integrated CLI tools

123 lines • 4.95 kB
/** * Clean Progress Reporter - Simple, reliable progress display * No complex libraries, just clean console output that works */ import chalk from 'chalk'; export class CleanProgressReporter { totalSteps = 0; currentStep = 0; currentProject = ''; constructor() { // Simple, no dependencies } /** * Start sync operation */ startSync(operation, options) { console.log(chalk.bold.blue(`\nšŸš€ Optimizely Cache Sync`)); console.log(chalk.gray(`${operation} • ${new Date().toLocaleTimeString()}\n`)); } /** * Set total steps */ setTotalSteps(projectCount, entitiesPerProject, totalSteps) { this.totalSteps = totalSteps || (projectCount * entitiesPerProject); console.log(chalk.gray(`Total steps: ${this.totalSteps} operations across ${projectCount} projects\n`)); this.showProgress(); } /** * Update progress for a specific phase */ updateProgress(progress) { const { phase, message } = progress; if (phase === 'projects') { // Handle project messages if (message.includes('Syncing project:')) { const projectMatch = message.match(/Syncing project:\s*(.+)/); if (projectMatch) { const projectName = projectMatch[1].trim(); if (projectName !== this.currentProject) { console.log(chalk.bold.cyan(`\nšŸ“¦ ${projectName}:`)); this.currentProject = projectName; } } return; } // Handle entity messages if (message.includes('Syncing') && !message.includes('Syncing project:')) { const entityMatch = message.match(/Syncing\s+(\w+)/i); if (entityMatch) { const entityType = entityMatch[1].toLowerCase(); console.log(chalk.yellow(` ā³ Downloading ${entityType}...`)); } return; } if (message.includes('synced') || message.includes('completed')) { const entityMatch = message.match(/(\w+)\s+(?:synced|completed)/i); if (entityMatch) { const entityType = entityMatch[1].toLowerCase(); const recordMatch = message.match(/\((\d+) records?\)/); const recordCount = recordMatch ? ` (${recordMatch[1]} records)` : ''; console.log(chalk.green(` āœ… ${entityType} completed${recordCount}`)); this.currentStep++; this.showProgress(); } return; } } // Handle individual entity phases (project_12345_experiments format) if (phase.startsWith('project_') && phase.includes('_')) { const parts = phase.split('_'); if (parts.length >= 3) { const entityType = parts.slice(2).join('_'); if (progress.percent >= 100) { const recordMatch = message.match(/\((\d+) records?\)/); const recordCount = recordMatch ? ` (${recordMatch[1]} records)` : ''; console.log(chalk.green(` āœ… ${entityType} completed${recordCount}`)); this.currentStep++; this.showProgress(); } } } } /** * Show simple progress indicator - only at key milestones */ showProgress() { if (this.totalSteps === 0) return; const percent = Math.round((this.currentStep / this.totalSteps) * 100); // Only show progress at 25%, 50%, 75%, 100% or every 5 steps const showUpdate = percent % 25 === 0 || this.currentStep % 5 === 0 || this.currentStep === this.totalSteps; if (showUpdate) { const barLength = 20; const filledLength = Math.round((barLength * this.currentStep) / this.totalSteps); const bar = 'ā–ˆ'.repeat(filledLength) + 'ā–‘'.repeat(barLength - filledLength); console.log(chalk.cyan(`Progress: [${bar}] ${percent}% (${this.currentStep}/${this.totalSteps})`)); } } /** * Complete sync operation */ completeSync(result) { console.log(chalk.bold.green('\n✨ Sync Completed Successfully!')); if (result.duration) { console.log(chalk.gray(`ā±ļø Completed in ${(result.duration / 1000).toFixed(1)}s`)); } console.log(chalk.gray(`šŸ“Š Processed ${this.totalSteps} operations\n`)); } /** * Report error */ error(error) { console.error(chalk.red.bold('\nāŒ Sync Failed!')); console.error(chalk.red(error.message)); } /** * Clean up */ dispose() { // Nothing to clean up } } //# sourceMappingURL=CleanProgressReporter.js.map