[READ-ONLY] Mirror of https://github.com/bombshell-dev/clack. Effortlessly build beautiful command-line apps bomb.sh/docs/clack/basics/getting-started/
cli command-line command-line-app node prompt prompts
5

Configure Feed

Select the types of activity you want to include in your feed.

fix: strip destructive ANSI codes from task logs (#420)

authored by

James Garbutt and committed by
GitHub
(Nov 22, 2025, 8:58 AM UTC) 69681ea4 0041d810

+59 -1
+5
.changeset/evil-rats-turn.md
··· 1 + --- 2 + "@clack/prompts": patch 3 + --- 4 + 5 + Strip destructive ANSI codes from task log messages.
+5 -1
packages/prompts/src/task-log.ts
··· 36 36 }; 37 37 } 38 38 39 + const stripDestructiveANSI = (input: string): string => { 40 + return input.replace(/\x1b\[(?:\d+;)*\d*[ABCDEFGHfJKSTsu]|\x1b\[(s|u)/g, ''); 41 + }; 42 + 39 43 /** 40 44 * Renders a log which clears on success and remains on failure 41 45 */ ··· 131 135 if ((mopts?.raw !== true || !lastMessageWasRaw) && buffer.value !== '') { 132 136 buffer.value += '\n'; 133 137 } 134 - buffer.value += msg; 138 + buffer.value += stripDestructiveANSI(msg); 135 139 lastMessageWasRaw = mopts?.raw === true; 136 140 if (opts.limit !== undefined) { 137 141 const lines = buffer.value.split('\n');
+35
packages/prompts/test/__snapshots__/task-log.test.ts.snap
··· 627 627 ] 628 628 `; 629 629 630 + exports[`taskLog (isCI = false) > message > destructive ansi codes are stripped 1`] = ` 631 + [ 632 + "│ 633 + ", 634 + "◇ foo 635 + ", 636 + "│ 637 + ", 638 + "│ line 1 639 + ", 640 + "<erase.line><cursor.up count=1><erase.line><cursor.left count=1>", 641 + "│ line 1 642 + │ line 2 bad ansi! 643 + ", 644 + "<erase.line><cursor.up count=1><erase.line><cursor.up count=1><erase.line><cursor.left count=1>", 645 + "│ line 1 646 + │ line 2 bad ansi! 647 + │ line 3 648 + ", 649 + ] 650 + `; 651 + 630 652 exports[`taskLog (isCI = false) > message > enforces limit if set 1`] = ` 631 653 [ 632 654 "│ ··· 1355 1377 ", 1356 1378 "│ 1357 1379 ", 1380 + ] 1381 + `; 1382 + 1383 + exports[`taskLog (isCI = true) > message > destructive ansi codes are stripped 1`] = ` 1384 + [ 1385 + "│ 1386 + ", 1387 + "◇ foo 1388 + ", 1389 + "│ 1390 + ", 1391 + "<erase.line><cursor.up count=1><erase.line><cursor.left count=1>", 1392 + "<erase.line><cursor.up count=1><erase.line><cursor.up count=1><erase.line><cursor.left count=1>", 1358 1393 ] 1359 1394 `; 1360 1395
+14
packages/prompts/test/task-log.test.ts
··· 132 132 133 133 expect(output.buffer).toMatchSnapshot(); 134 134 }); 135 + 136 + test('destructive ansi codes are stripped', async () => { 137 + const log = prompts.taskLog({ 138 + input, 139 + output, 140 + title: 'foo', 141 + }); 142 + 143 + log.message('line 1'); 144 + log.message('line 2\x1b[2K bad ansi!'); 145 + log.message('line 3'); 146 + 147 + expect(output.buffer).toMatchSnapshot(); 148 + }); 135 149 }); 136 150 137 151 describe('error', () => {