From 4bf63835f1a7503e682db6ac00e1e07542f530d7 Mon Sep 17 00:00:00 2001 From: LightZirconite Date: Thu, 13 Nov 2025 20:35:47 +0100 Subject: [PATCH] feat: Enhance output formatting for validation results and daily run summary --- src/flows/SummaryReporter.ts | 19 +++++--- src/index.ts | 19 ++++++-- src/util/validation/StartupValidator.ts | 60 ++++++++++++++++--------- 3 files changed, 69 insertions(+), 29 deletions(-) diff --git a/src/flows/SummaryReporter.ts b/src/flows/SummaryReporter.ts index 0e1af35..738e5e4 100644 --- a/src/flows/SummaryReporter.ts +++ b/src/flows/SummaryReporter.ts @@ -60,17 +60,26 @@ export class SummaryReporter { ? `${minutes}m ${seconds}s` : `${seconds}s` - let description = `**Duration:** ${durationText}\n**Total Points:** ${summary.totalPoints}\n**Success:** ${summary.successCount}/${summary.accounts.length}\n\n` + let description = `╔════════════════════════════════════════╗\n` + description += `║ Daily Run Summary ║\n` + description += `╚════════════════════════════════════════╝\n\n` + description += `⏱️ **Duration:** ${durationText}\n` + description += `💰 **Total Points:** ${summary.totalPoints}\n` + description += `✅ **Success Rate:** ${summary.successCount}/${summary.accounts.length} accounts\n\n` - // Add individual account results - description += '**Account Results:**\n' + // Add individual account results with better formatting + description += `📊 **Detailed Results:**\n` + description += `${'─'.repeat(45)}\n` for (const account of summary.accounts) { const status = account.errors?.length ? '❌' : '✅' - description += `${status} ${account.email}: ${account.pointsEarned} points (${Math.round(account.runDuration / 1000)}s)\n` + const emailShort = account.email.length > 25 ? account.email.substring(0, 22) + '...' : account.email + description += `${status} \`${emailShort}\`\n` + description += ` 💎 Points: **${account.pointsEarned}** | ⏱️ Time: ${Math.round(account.runDuration / 1000)}s\n` if (account.errors?.length) { - description += ` ⚠️ ${account.errors[0]}\n` + description += ` ⚠️ Error: *${account.errors[0]}*\n` } + description += `\n` } await ConclusionWebhook( diff --git a/src/index.ts b/src/index.ts index 3246c9e..19cbd2a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ -import { spawn } from 'child_process' +import chalk from 'chalk' +import { spawn } from 'child_process' import type { Worker } from 'cluster' import cluster from 'cluster' import fs from 'fs' @@ -227,8 +228,20 @@ export class MicrosoftRewardsBot { const version = this.getVersion() - log('main', 'BANNER', `Microsoft Rewards Bot v${version}`) - log('main', 'BANNER', `PID: ${process.pid} | Workers: ${this.config.clusters}`) + // ASCII-safe banner for Windows PowerShell compatibility + console.log('') + console.log(chalk.cyan(' ================================================')) + console.log(chalk.cyan(' Microsoft Rewards Bot')) + console.log(chalk.cyan(' ================================================')) + console.log('') + console.log(chalk.gray(' Version: ') + chalk.white(`v${version}`)) + console.log(chalk.gray(' Process ID: ') + chalk.white(process.pid)) + console.log(chalk.gray(' Workers: ') + chalk.white(this.config.clusters)) + console.log(chalk.gray(' Node.js: ') + chalk.white(process.version)) + console.log(chalk.gray(' Platform: ') + chalk.white(`${process.platform} ${process.arch}`)) + console.log('') + console.log(chalk.cyan(' ================================================')) + console.log('') } private getVersion(): string { diff --git a/src/util/validation/StartupValidator.ts b/src/util/validation/StartupValidator.ts index cf0c1c4..93b6d11 100644 --- a/src/util/validation/StartupValidator.ts +++ b/src/util/validation/StartupValidator.ts @@ -677,46 +677,64 @@ export class StartupValidator { private async displayResults(): Promise { if (this.errors.length > 0) { - log('main', 'VALIDATION', chalk.red('❌ VALIDATION ERRORS FOUND:'), 'error') + console.log('') + console.log(chalk.red(' ╔═══════════════════════════════════════════════════════╗')) + console.log(chalk.red(' ║ VALIDATION ERRORS FOUND ║')) + console.log(chalk.red(' ╚═══════════════════════════════════════════════════════╝')) + console.log('') + this.errors.forEach((err, index) => { - log('main', 'VALIDATION', chalk.red(`${index + 1}. [${err.category.toUpperCase()}] ${err.message}`), 'error') + const blocking = err.blocking ? chalk.red.bold(' [BLOCKING]') : '' + console.log(chalk.red(` ${index + 1}. `) + chalk.white(`[${err.category.toUpperCase()}]`) + blocking) + console.log(chalk.gray(' ') + err.message) if (err.fix) { - log('main', 'VALIDATION', chalk.yellow(` Fix: ${err.fix}`), 'warn') + console.log(chalk.yellow(' Fix: ') + chalk.white(err.fix)) } if (err.docsLink) { - log('main', 'VALIDATION', ` Docs: ${err.docsLink}`) + console.log(chalk.cyan(' Docs: ') + chalk.underline(err.docsLink)) } + console.log('') }) } if (this.warnings.length > 0) { - log('main', 'VALIDATION', chalk.yellow('⚠️ WARNINGS:'), 'warn') + console.log('') + console.log(chalk.yellow(' ╔═══════════════════════════════════════════════════════╗')) + console.log(chalk.yellow(' ║ WARNINGS ║')) + console.log(chalk.yellow(' ╚═══════════════════════════════════════════════════════╝')) + console.log('') + this.warnings.forEach((warn, index) => { - log('main', 'VALIDATION', chalk.yellow(`${index + 1}. [${warn.category.toUpperCase()}] ${warn.message}`), 'warn') + console.log(chalk.yellow(` ${index + 1}. `) + chalk.white(`[${warn.category.toUpperCase()}]`)) + console.log(chalk.gray(' ') + warn.message) if (warn.fix) { - log('main', 'VALIDATION', ` Suggestion: ${warn.fix}`) + console.log(chalk.cyan(' Suggestion: ') + chalk.white(warn.fix)) } if (warn.docsLink) { - log('main', 'VALIDATION', ` Docs: ${warn.docsLink}`) + console.log(chalk.cyan(' Docs: ') + chalk.underline(warn.docsLink)) } + console.log('') }) } if (this.errors.length === 0 && this.warnings.length === 0) { - log('main', 'VALIDATION', chalk.green('✅ All validation checks passed!')) - } else { - const errorLabel = this.errors.length === 1 ? 'error' : 'errors' - const warningLabel = this.warnings.length === 1 ? 'warning' : 'warnings' - log('main', 'VALIDATION', `[${this.errors.length > 0 ? 'ERROR' : 'OK'}] Found: ${this.errors.length} ${errorLabel} | ${this.warnings.length} ${warningLabel}`) + console.log('') + console.log(chalk.green(' ╔═══════════════════════════════════════════════════════╗')) + console.log(chalk.green(' ║ ✓ All validation checks passed! ║')) + console.log(chalk.green(' ╚═══════════════════════════════════════════════════════╝')) + console.log('') + } - if (this.errors.length > 0) { - log('main', 'VALIDATION', 'Bot will continue, but issues may cause failures', 'warn') - log('main', 'VALIDATION', 'Full documentation: docs/index.md') - await new Promise(resolve => setTimeout(resolve, 3000)) - } else if (this.warnings.length > 0) { - log('main', 'VALIDATION', 'Warnings detected - review recommended', 'warn') - await new Promise(resolve => setTimeout(resolve, 2000)) - } + // Add delay if errors or warnings were found + if (this.errors.length > 0) { + console.log(chalk.gray(' → Bot will continue, but issues may cause failures')) + console.log(chalk.gray(' → Full documentation: docs/index.md')) + console.log('') + await new Promise(resolve => setTimeout(resolve, 3000)) + } else if (this.warnings.length > 0) { + console.log(chalk.gray(' → Warnings detected - review recommended')) + console.log('') + await new Promise(resolve => setTimeout(resolve, 2000)) } } }