/** * Progress bar rendering with discrete block characters. * * Renders ▁▂▃▄▅▆▇█ glyphs on a dim background track. */ import type { Theme, ThemeColor } from "@earendil-works/pi-coding-agent"; const GLYPHS = [" ", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"]; const MAX_LEVEL = GLYPHS.length - 1; const RESET = "\x1b[39m\x1b[49m"; /** Render discrete block characters with dim background track. */ export function renderBlocksBar( pct: number, width: number, theme: Theme, color: ThemeColor, ): string { const clamped = Math.max(0, Math.min(100, pct)); const filledFloat = (clamped / 100) * width; const dimBg = fgToBgAnsi(theme.getFgAnsi("dim")); const fgColor = theme.getFgAnsi(color); const result: string[] = []; for (let i = 0; i < width; i++) { const blockFill = Math.max(0, Math.min(1, filledFloat - i)); const level = Math.round(blockFill * MAX_LEVEL); const glyph = GLYPHS[level]; result.push( level > 0 ? `${dimBg}${fgColor}${glyph}${RESET}` : `${dimBg}${glyph}${RESET}`, ); } return result.join(""); } function fgToBgAnsi(fgAnsi: string): string { return fgAnsi.replace("\x1b[38;", "\x1b[48;"); }