// Terminal escapes: colours and cursor moves (CSI), titles and links (OSC), and the short ones. const ESCAPES = /\x1b(?:\[[0-?]*[ -/]*[@-~]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[@-Z\\-_])/g; /** * A step's output as plain lines, the way a terminal would end up showing them: escapes removed and * carriage-return redraws (progress bars) collapsed to what was drawn last. Keeps the last `max` lines. */ export function logTail(text: string, max = 2000) { const lines = text .replace(ESCAPES, "") .replace(/\r+\n/g, "\n") .split("\n") .map((line) => line.slice(line.lastIndexOf("\r") + 1)); if (lines.at(-1) === "") lines.pop(); const omitted = Math.max(0, lines.length - max); return { lines: lines.slice(omitted), omitted }; }