Skip to main content
← Back to list
01Issue
BugShippedSwamp CLIPublic
Assigneesskunk-ape

Relationships

#2414 swamp --version emits ANSI escapes when piped, and --no-color does not suppress them

Opened by skunk-ape · 9/23/2026· Shipped 9/23/2026

Description

swamp --version writes ANSI escape sequences even when stdout is not a terminal, and the --no-color flag does not suppress them. Only the NO_COLOR environment variable works.

Steps to Reproduce

swamp --version | cat -v
^[[1mswamp^[[22m ^[[94m20260922.011324.0-sha.2e949db5^[[39m

swamp --no-color --version | cat -v
^[[1mswamp^[[22m ^[[94m20260922.011324.0-sha.2e949db5^[[39m

NO_COLOR=1 swamp --version | cat -v
swamp 20260922.011324.0-sha.2e949db5

Expected: the first two print a bare version string. Observed: both carry bold and bright-blue escapes.

Cause

src/cli/mod.ts:1653 registers the version flag with Cliffy's .version(). That is a standalone option: Cliffy prints the version and exits during argument parsing, before .globalAction() runs. All of the colour handling lives in that global action (src/cli/mod.ts:1675-1684), where --no-color and NO_COLOR are read and setColorEnabled(false) is called. For --version, that code never executes.

NO_COLOR works only incidentally, because the colour library reads the environment variable itself without involving the CLI.

Two distinct defects sit behind the same symptom:

  1. --no-color has no effect on any output Cliffy produces before the global action runs. The version flag is the clearest case; help output is worth checking for the same reason.
  2. Colour is never disabled based on stdout being a pipe. prettyOutput at src/cli/mod.ts:1685 consults isStdinTty() for log formatting, but nothing consults whether stdout is a terminal before enabling colour, so captured output keeps its escapes.

Impact

Any caller capturing the version gets escape codes in the value. Found in scripts/build_attestation.ts, which records the result as environment.swampVersion in the verification attestation — a document CI parses and compares. The stored value currently reads:

"\u001b[1mswamp\u001b[22m \u001b[94m20260922.011324.0-sha.2e949db5\u001b[39m"

The same applies to shell scripts assigning the version to a variable, and to version strings pasted into bug reports.

Suggested Fix

Decide colour before the Cliffy command is constructed, rather than inside the global action: scan the raw arguments for the flag and check Deno.stdout.isTerminal(), then call setColorEnabled(false) early. That covers every path that exits before the action runs, including help.

Found while generating the verification attestation for swamp-club#1702.

02Bog Flow
✓OPEN✓TRIAGED✓IN PROGRESS✓SHIPPED+ 1 MOREASSIGNED+ 6 MOREFINDINGS+ 7 MOREPR_MERGED+ 2 MORESESSION_SUMMARIZED

Shipped

9/23/2026, 6:59:03 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
skunk-ape assigned skunk-ape9/23/2026, 4:47:13 PM

Sign in to post a ripple.