CLI

radar scan

Scan a directory for technical debt violations with multiple output formats, AI analysis, and configurable failure thresholds.

radar scan

The scan command analyzes all TypeScript and JavaScript files in a directory against your policy configuration. It runs 7 analyzers in parallel, scores violations, and evaluates gate conditions.

Usage

radar scan <path> [options]

Options

FlagDescriptionDefault
-c, --config <path>Path to radar.yml./radar.yml
-r, --rules <path>Path to rules.yml./rules.yml
-f, --format <type>Output format (see below)text
--fail-on <severity>Exit code 1 on: critical or warningcritical
--no-aiSkip AI analysis (faster, no API cost)false

Output Formats

text (default)

Human-readable colored output with violation details, category breakdown, and hotspot files.

$ radar scan src/

═══════════════════════════════════════════════════
  TECHNICAL DEBT RADAR — Local Scan
═══════════════════════════════════════════════════

  Stats
  Files scanned:     47
  Total violations:  12
  Blocking:          3
  Warnings:          9
  Debt score:        38

  🤖 AI Summary
  ──────────────
  The most critical issue is an unbounded query on the events table
  (XL, 1M+ rows) in EventService.findAll() that will cause timeouts
  in production. There are also 3 missing null guards in
  article.service.ts that will crash with 500 errors on invalid slugs.
  Fix the unbounded query first — it affects every user.

  Category Breakdown
    Architecture    : 2
    Runtime Risk    : 3
    Performance     : 2
    Reliability     : 4
    Maintainability : 1

  ✖ BLOCKING VIOLATIONS
  ─────────────────────
  src/events/event.service.ts:42
    [perf-unbounded-query] Query on XL table "events" without LIMIT or pagination
    → Add pagination: findMany({ take: 100, skip: offset })

  src/orders/order.handler.ts:18
    [runtime-sync-fs] Synchronous file read in request handler
    → Replace readFileSync with readFile (async)

  src/billing/payment.service.ts:91
    [reliability-unhandled-promise] Unhandled promise rejection in payment flow
    → Wrap in try/catch and handle the error explicitly

  ⚠ WARNINGS
  ──────────
  src/users/user.service.ts:15
    [reliability-missing-null-guard] Nullable value used without check
    → Add null guard: if (!user) throw new NotFoundException()

  src/articles/article.service.ts:33
    [reliability-missing-null-guard] Nullable value used without check
    → Add null guard before accessing properties

  Top Hotspot Files
  ─────────────────
  src/events/event.service.ts (4 violations)
  src/articles/article.service.ts (3 violations)
  src/billing/payment.service.ts (2 violations)

  RESULT: FAIL — merge would be blocked

json

Machine-readable JSON output, suitable for piping to other tools or CI integrations.

$ radar scan src/ --format json
{
  "filesScanned": 47,
  "violations": [
    {
      "file": "src/events/event.service.ts",
      "line": 42,
      "ruleId": "perf-unbounded-query",
      "message": "Query on XL table \"events\" without LIMIT or pagination",
      "severity": "critical",
      "category": "performance",
      "debtPoints": 8,
      "gateAction": "block",
      "suggestion": "Add pagination: findMany({ take: 100, skip: offset })"
    }
  ],
  "breakdown": {
    "architecture": 10,
    "maintainability": 2,
    "runtime": 8,
    "performance": 8,
    "reliability": 10,
    "aiAdvisory": 0,
    "credits": 0,
    "total": 38
  },
  "gateResult": "fail",
  "blockingReasons": [
    "architecture_violations > 0",
    "runtime_risk_critical > 0"
  ],
  "aiSummary": "The most critical issue is an unbounded query on the events table..."
}

table

Structured table output for terminal viewing.

$ radar scan src/ --format table
TECHNICAL DEBT RADAR — Local Scan

Summary
┌──────────────────┬────────┐
│ Files scanned     │     47 │
│ Total violations  │     12 │
│ Blocking          │      3 │
│ Warnings          │      9 │
│ Debt score        │     38 │
└──────────────────┴────────┘

Violations
┌──────────────┬──────────┬──────────────────────────────────┬──────────────────────────────┐
│ Category     │ Severity │ File                             │ Rule                         │
├──────────────┼──────────┼──────────────────────────────────┼──────────────────────────────┤
│ performance  │ critical │ src/events/event.service.ts:42   │ perf-unbounded-query         │
│ runtime_risk │ critical │ src/orders/order.handler.ts:18   │ runtime-sync-fs              │
│ reliability  │ critical │ src/billing/payment.service.ts:91│ reliability-unhandled-promise │
│ reliability  │ warning  │ src/users/user.service.ts:15     │ reliability-missing-null-guar │
└──────────────┴──────────┴──────────────────────────────────┴──────────────────────────────┘

RESULT: FAIL

ai-prompt

Plain-text output formatted as an instruction prompt. Paste directly into an AI assistant to get fix suggestions.

$ radar scan src/ --format ai-prompt
TECHNICAL DEBT RADAR — Scan Report

EXECUTIVE SUMMARY: The most critical issue is an unbounded query on the events
table (XL, 1M+ rows) in EventService.findAll()...

Fix the following issues in order of severity:

🔴 CRITICAL [Performance] src/events/event.service.ts:42
   Rule: perf-unbounded-query
   Problem: Query on XL table "events" without LIMIT or pagination
   Fix: Add pagination: findMany({ take: 100, skip: offset })

🔴 CRITICAL [Runtime Risk] src/orders/order.handler.ts:18
   Rule: runtime-sync-fs
   Problem: Synchronous file read in request handler
   Fix: Replace readFileSync with readFile (async)

⚠️ WARNING [Reliability] src/users/user.service.ts:15
   Rule: reliability-missing-null-guard
   Problem: Nullable value used without check
   Fix: Add null guard: if (!user) throw new NotFoundException()

Score: 62/100 | Violations: 3 critical, 9 warnings

ai-json

JSON format optimized for AI consumption, with structured violation data and fix instructions.

$ radar scan src/ --format ai-json
{
  "report": "TECHNICAL DEBT RADAR — Scan Report",
  "aiSummary": "The most critical issue is...",
  "instruction": "Fix the following issues in order of severity",
  "violations": [
    {
      "severity": "critical",
      "category": "Performance",
      "file": "src/events/event.service.ts",
      "line": 42,
      "ruleId": "perf-unbounded-query",
      "problem": "Query on XL table \"events\" without LIMIT or pagination",
      "fix": "Add pagination: findMany({ take: 100, skip: offset })",
      "debtPoints": 8
    }
  ],
  "summary": {
    "score": 62,
    "maxScore": 100,
    "criticalCount": 3,
    "warningCount": 9,
    "totalViolations": 12
  }
}

pr

GitHub/GitLab PR comment format with AI-enhanced explanations. Generates full markdown suitable for posting as a PR review comment.

$ radar scan src/ --format pr

This format includes:

  • AI-generated executive summary
  • Top 5 violations with detailed AI explanations of impact
  • Remaining violations in a collapsed section
  • Debt score and gate status
  • Code context around each violation (10 lines before/after)

Checking a Single File

Use radar check to analyze one file:

$ radar check src/events/event.service.ts

═══════════════════════════════════════════════════
  TECHNICAL DEBT RADAR — Local Scan
═══════════════════════════════════════════════════

  Stats
  Files scanned:     1
  Total violations:  4
  Blocking:          1
  Warnings:          3
  Debt score:        17

  ✖ BLOCKING VIOLATIONS
  ─────────────────────
  src/events/event.service.ts:42
    [perf-unbounded-query] Query on XL table "events" without LIMIT

  RESULT: FAIL — merge would be blocked

AI-Enhanced Scanning

When ANTHROPIC_API_KEY is set, radar scan automatically:

  1. Generates a 2-3 sentence executive summary of findings
  2. Runs cross-file analysis to detect indirect violations (e.g., a handler calling a function that contains a blocking operation)

Disable AI analysis for faster, cost-free scans:

radar scan src/ --no-ai

Failure Thresholds

By default, the scan exits with code 1 only on critical (blocking) violations. To fail on warnings too:

radar scan src/ --fail-on warning

Exit Codes

CodeMeaning
0Scan passed (no blocking violations, or only warnings when --fail-on critical)
1Scan failed (blocking violations found, or warnings when --fail-on warning)

Excluded Directories

The scanner automatically skips:

  • node_modules/
  • .git/
  • dist/
  • build/
  • .next/
  • coverage/

Test files (*.spec.ts, *.test.ts, *.spec.js, *.test.js) and declaration files (*.d.ts) are also excluded.

Technical Debt Radar Documentation