UNPKG

@oliverpople/agency-x

Version:

🚀 **Transform feature requests into production-ready code in seconds**

124 lines (98 loc) 3.45 kB
import chalk from 'chalk'; interface ProgressState { total: number; completed: number; failed: number; running: number; startTime: number; } export class ProgressTracker { private state: ProgressState; private updateInterval?: NodeJS.Timer; private lastUpdate: number = 0; constructor(total: number) { this.state = { total, completed: 0, failed: 0, running: 0, startTime: Date.now(), }; } start() { this.updateInterval = setInterval(() => { this.render(); }, 500); } stop() { if (this.updateInterval) { clearInterval(this.updateInterval); this.updateInterval = undefined; } } update(status: { completed: number; failed: number; running: number }) { this.state.completed = status.completed; this.state.failed = status.failed; this.state.running = status.running; this.lastUpdate = Date.now(); } private getProgressBar(percentage: number, width: number = 30): string { const filled = Math.round((percentage / 100) * width); const empty = width - filled; const filledBar = '█'.repeat(filled); const emptyBar = '░'.repeat(empty); return chalk.green(filledBar) + chalk.gray(emptyBar); } private formatTime(ms: number): string { const seconds = Math.floor(ms / 1000); const minutes = Math.floor(seconds / 60); if (minutes > 0) { return `${minutes}m ${seconds % 60}s`; } return `${seconds}s`; } private estimateTimeRemaining(): string { const elapsed = Date.now() - this.state.startTime; const progress = this.state.completed / this.state.total; if (progress === 0) return 'calculating...'; const estimated = elapsed / progress; const remaining = estimated - elapsed; return remaining > 0 ? this.formatTime(remaining) : '0s'; } private render() { const { completed, failed, running, total } = this.state; const pending = total - completed - failed - running; const completionPercentage = ((completed + failed) / total) * 100; // Clear the line and render progress process.stdout.write('\r\x1b[K'); const progressBar = this.getProgressBar(completionPercentage); const elapsed = this.formatTime(Date.now() - this.state.startTime); const estimated = this.estimateTimeRemaining(); const statusLine = [ `${progressBar} ${completionPercentage.toFixed(1)}%`, chalk.green(`✅ ${completed}`), running > 0 ? chalk.yellow(`🔄 ${running}`) : '', failed > 0 ? chalk.red(`❌ ${failed}`) : '', pending > 0 ? chalk.gray(`⏳ ${pending}`) : '', `⏱️ ${elapsed}`, completionPercentage < 100 ? `(~${estimated} left)` : '', ].filter(Boolean).join(' '); process.stdout.write(statusLine); } complete() { this.stop(); const elapsed = this.formatTime(Date.now() - this.state.startTime); process.stdout.write('\r\x1b[K'); if (this.state.failed > 0) { console.log(`🎯 Orchestration completed with ${this.state.failed} failures in ${elapsed}`); } else { console.log(`🎉 Orchestration completed successfully in ${elapsed}`); } } error(message: string) { this.stop(); const elapsed = this.formatTime(Date.now() - this.state.startTime); process.stdout.write('\r\x1b[K'); console.log(`💥 Orchestration failed after ${elapsed}: ${message}`); } }