Skip to content
29 changes: 21 additions & 8 deletions clawpinch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ source "$HELPERS_DIR/common.sh"
source "$HELPERS_DIR/report.sh"
source "$HELPERS_DIR/redact.sh"
source "$HELPERS_DIR/interactive.sh"
source "$HELPERS_DIR/sarif.sh"

# ─── Signal trap for animation cleanup ──────────────────────────────────────

Expand All @@ -23,6 +24,7 @@ trap '_cleanup_animation; exit 130' INT TERM

DEEP=0
JSON_OUTPUT=0
SARIF_OUTPUT=0
SHOW_FIX=0
QUIET=0
NO_INTERACTIVE=0
Expand All @@ -39,6 +41,7 @@ Usage: clawpinch [OPTIONS]
Options:
--deep Run thorough / deep scans
--json Output findings as JSON array only
--sarif Output findings in SARIF format
--fix Show auto-fix commands in report
--quiet Print summary line only
--sequential Run scanners sequentially (default is parallel)
Expand All @@ -60,6 +63,7 @@ while [[ $# -gt 0 ]]; do
case "$1" in
--deep) DEEP=1; shift ;;
--json) JSON_OUTPUT=1; shift ;;
--sarif) SARIF_OUTPUT=1; shift ;;
--fix) SHOW_FIX=1; shift ;;
--quiet) QUIET=1; shift ;;
--sequential) PARALLEL_SCANNERS=0; shift ;;
Expand Down Expand Up @@ -88,6 +92,12 @@ export CLAWPINCH_SHOW_FIX="$SHOW_FIX"
export CLAWPINCH_CONFIG_DIR="$CONFIG_DIR"
export QUIET

# Determine if we should show terminal UI (not in JSON/SARIF/quiet mode)
_SHOW_UI=1
if [[ "$JSON_OUTPUT" -eq 1 ]] || [[ "$SARIF_OUTPUT" -eq 1 ]] || [[ "$QUIET" -eq 1 ]]; then
_SHOW_UI=0
fi

# ─── Validate security config (early check for --remediate) ──────────────────
# Fail fast with a clear setup message instead of per-command failures later.

Expand Down Expand Up @@ -131,7 +141,7 @@ export OPENCLAW_CONFIG

# ─── Banner ──────────────────────────────────────────────────────────────────

if [[ "$JSON_OUTPUT" -eq 0 ]] && [[ "$QUIET" -eq 0 ]]; then
if [[ "$_SHOW_UI" -eq 1 ]]; then
print_header_animated
log_info "OS detected: $CLAWPINCH_OS"
if [[ -n "$OPENCLAW_CONFIG" ]]; then
Expand Down Expand Up @@ -240,7 +250,7 @@ _scan_start="${EPOCHSECONDS:-$(date +%s)}"

if [[ "$PARALLEL_SCANNERS" -eq 1 ]]; then
# Parallel execution
if [[ "$JSON_OUTPUT" -eq 0 ]] && [[ "$QUIET" -eq 0 ]]; then
if [[ "$_SHOW_UI" -eq 1 ]]; then
start_spinner "Running ${scanner_count} scanners in parallel..."
fi

Expand All @@ -256,7 +266,7 @@ if [[ "$PARALLEL_SCANNERS" -eq 1 ]]; then
# Count findings from merged results
_parallel_count="$(echo "$ALL_FINDINGS" | jq 'length')"

if [[ "$JSON_OUTPUT" -eq 0 ]] && [[ "$QUIET" -eq 0 ]]; then
if [[ "$_SHOW_UI" -eq 1 ]]; then
stop_spinner "Parallel scan" "$_parallel_count" "$_parallel_elapsed"
fi
else
Expand All @@ -269,7 +279,7 @@ else
# Record scanner start time
_scanner_start="${EPOCHSECONDS:-$(date +%s)}"

if [[ "$JSON_OUTPUT" -eq 0 ]] && [[ "$QUIET" -eq 0 ]]; then
if [[ "$_SHOW_UI" -eq 1 ]]; then
# Print section header for this scanner
print_section_header "$scanner_name"

Expand All @@ -290,7 +300,7 @@ else
elif has_cmd python; then
output="$(python "$scanner" 2>/dev/null)" || true
else
if [[ "$JSON_OUTPUT" -eq 0 ]] && [[ "$QUIET" -eq 0 ]]; then
if [[ "$_SHOW_UI" -eq 1 ]]; then
stop_spinner "$local_name" 0 0
fi
log_warn "Skipping $scanner_name (python not found)"
Expand All @@ -315,7 +325,7 @@ else
_scanner_end="${EPOCHSECONDS:-$(date +%s)}"
_scanner_elapsed=$(( _scanner_end - _scanner_start ))

if [[ "$JSON_OUTPUT" -eq 0 ]] && [[ "$QUIET" -eq 0 ]]; then
if [[ "$_SHOW_UI" -eq 1 ]]; then
stop_spinner "$local_name" "$local_count" "$_scanner_elapsed"
fi
done
Expand All @@ -325,7 +335,7 @@ fi
_scan_end="${EPOCHSECONDS:-$(date +%s)}"
_scan_elapsed=$(( _scan_end - _scan_start ))

if [[ "$JSON_OUTPUT" -eq 0 ]] && [[ "$QUIET" -eq 0 ]]; then
if [[ "$_SHOW_UI" -eq 1 ]]; then
printf '\n'
fi

Expand All @@ -352,7 +362,10 @@ count_ok="$(echo "$SORTED_FINDINGS" | jq '[.[] | select(.severity == "ok")

# ─── Output ──────────────────────────────────────────────────────────────────

if [[ "$JSON_OUTPUT" -eq 1 ]]; then
if [[ "$SARIF_OUTPUT" -eq 1 ]]; then
# SARIF v2.1.0 output (for GitHub Code Scanning, etc.)
convert_to_sarif "$SORTED_FINDINGS"
elif [[ "$JSON_OUTPUT" -eq 1 ]]; then
# Pure JSON output (compact for piping efficiency)
echo "$SORTED_FINDINGS" | jq -c .
else
Expand Down
Loading