logger.ts
1 /** 2 * Unified logging for opencli. 3 * 4 * All framework output (warnings, debug info, errors) should go through 5 * this module so that verbosity levels are respected consistently. 6 */ 7 8 import { styleText } from 'node:util'; 9 10 function isVerbose(): boolean { 11 return !!process.env.OPENCLI_VERBOSE; 12 } 13 14 export const log = { 15 /** Informational message (always shown) */ 16 info(msg: string): void { 17 process.stderr.write(`${styleText('blue', 'ℹ')} ${msg}\n`); 18 }, 19 20 /** Lightweight status line for adapter progress updates */ 21 status(msg: string): void { 22 process.stderr.write(`${styleText('dim', msg)}\n`); 23 }, 24 25 /** Positive completion/status line without the heavier info prefix */ 26 success(msg: string): void { 27 process.stderr.write(`${styleText('green', msg)}\n`); 28 }, 29 30 /** Warning (always shown) */ 31 warn(msg: string): void { 32 process.stderr.write(`${styleText('yellow', '⚠')} ${msg}\n`); 33 }, 34 35 /** Error (always shown) */ 36 error(msg: string): void { 37 process.stderr.write(`${styleText('red', '✖')} ${msg}\n`); 38 }, 39 40 /** Verbose output (shown when -v flag or OPENCLI_VERBOSE is set) */ 41 verbose(msg: string): void { 42 if (isVerbose()) { 43 process.stderr.write(`${styleText('dim', '[verbose]')} ${msg}\n`); 44 } 45 }, 46 47 /** Alias for verbose output. */ 48 debug(msg: string): void { 49 this.verbose(msg); 50 }, 51 52 /** Step-style debug (for pipeline steps, etc.) */ 53 step(stepNum: number, total: number, op: string, preview: string = ''): void { 54 process.stderr.write(` ${styleText('dim', `[${stepNum}/${total}]`)} ${styleText(['bold', 'cyan'], op)}${preview}\n`); 55 }, 56 57 /** Step result summary */ 58 stepResult(summary: string): void { 59 process.stderr.write(` ${styleText('dim', `→ ${summary}`)}\n`); 60 }, 61 };