feat: Enhance output formatting for validation results and daily run summary

This commit is contained in:
2025-11-13 20:35:47 +01:00
parent 5651f62088
commit 4bf63835f1
3 changed files with 69 additions and 29 deletions

View File

@@ -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(

View File

@@ -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 {

View File

@@ -677,46 +677,64 @@ export class StartupValidator {
private async displayResults(): Promise<void> {
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))
}
}
}