Skip to content

Output Formats

codescan supports three output formats, automatically selected based on whether stdout is a terminal.

Pretty (Default in Interactive Mode)

Cargo-inspired human-readable output with colors and source context:

error[SECRET001]: Hardcoded password
  --> src/config.py:14:12
   |
14 |   password = "hunter2"
   |              ^^^^^^^^^
   = help: Use environment variables or a secrets manager instead

warning[CRYPTO001]: Weak hashing algorithm
  --> src/auth.py:8:5
   |
 8 |   hashlib.md5(data).hexdigest()
   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = help: Use SHA-256 or better

found 1 error, 1 warning, 0 notes

Color coding:

  • error[...] — red bold
  • warning[...] — yellow bold
  • info[...] — cyan bold
  • Location arrows (-->, |) — blue bold
  • Caret underline — red
  • = suppressed: — dimmed (when --show-suppressed)

Force pretty output even in a pipe:

bash
codescan --format pretty --interactive true . | less -R

Text (Default in Non-Interactive Mode)

Colon-delimited plain text, one finding per line. Easy to grep, awk, or parse in CI scripts:

src/config.py:14:12:error:SECRET001:Hardcoded password
src/auth.py:8:5:warning:CRYPTO001:Weak hashing algorithm
# errors=1 warnings=1 infos=0

Format: path:line:col:severity:rule_id:message

The summary line (prefixed with #) is omitted with --quiet.

bash
# Extract only error lines
codescan --format text . | grep '^[^#].*:error:'

# Count findings per rule
codescan --format text -q . | awk -F: '{print $5}' | sort | uniq -c | sort -rn

JSON

Newline-delimited JSON (NDJSON), one object per finding. Ideal for downstream processing, dashboards, and tooling integrations:

json
{"path":"src/config.py","line":14,"col":12,"end_col":21,"severity":"error","rule_id":"SECRET001","category":"SECRET","message":"Hardcoded password","snippet":"  password = \"hunter2\"","help":"Use environment variables or a secrets manager instead","suppressed_by":null}
{"path":"src/auth.py","line":8,"col":5,"end_col":36,"severity":"warning","rule_id":"CRYPTO001","category":"CRYPTO","message":"Weak hashing algorithm","snippet":"  hashlib.md5(data).hexdigest()","help":"Use SHA-256 or better","suppressed_by":null}

A summary object is written to stderr:

json
{"summary":{"errors":1,"warnings":1,"infos":0}}

JSON Schema

FieldTypeDescription
pathstringRelative file path
linenumber1-based line number
colnumber1-based column number
end_colnumberEnd column (exclusive)
severity"error" | "warning" | "info"Severity level
rule_idstringRule identifier
categorystringRule category
messagestringFinding description
snippetstringSource line text
helpstring | nullRemediation hint
suppressed_bystring | nullSuppression reason (null if active)

Processing JSON Output

bash
# Filter errors only
codescan --format json . | jq 'select(.severity == "error")'

# Group by rule
codescan --format json -q . | jq -s 'group_by(.rule_id) | map({rule: .[0].rule_id, count: length})'

# Export to CSV
codescan --format json -q . | jq -r '[.path, .line, .severity, .rule_id, .message] | @csv'

Writing to a File

bash
codescan --output findings.txt --format text .
codescan --output findings.jsonl --format json .

Quiet Mode

Suppress the summary line:

bash
codescan --quiet .
codescan -q --format json .  # suppress stderr summary too

Show Suppressed Findings

Suppressed findings are hidden by default. Reveal them with:

bash
codescan --show-suppressed .

In pretty format, suppressed findings show an extra line:

  = suppressed: inline codescan:ignore