← Back to home

Examples

Real invocations grouped by where this CLI tends to land — jq on the terminal, GitHub Actions in CI, programmatic use from Node.

1

One-liners with jq

The default JSON output is designed for piping. These are the recipes that come up most often when reading the result by hand.

# Triage histogram: how many files of each verdict?
prcompass analyze --repo . --diff HEAD~1 \
  | jq '.triage.verdicts | group_by(.verdict) | map({verdict: .[0].verdict, n: length})'

# Top 5 risk-scored files
prcompass analyze --repo . --diff main..HEAD \
  | jq '.risk.byFile
        | to_entries
        | sort_by(-.value.score)
        | .[0:5]
        | map({path: .key, score: .value.score, tier: .value.tier})'

# Files that are both review-candidate AND high-risk — the sharp end of the cone
prcompass analyze --repo . --diff main..HEAD \
  | jq '
    [.triage.verdicts[]
      | select(.verdict == "review-candidate")
      | .path] as $review
    | .risk.byFile
    | to_entries
    | map(select(.value.tier == "high" and (.key | IN($review[]))))
    | map(.key)
  '

# Just the headline: count of files, hotspot top, risk top
prcompass analyze --repo . --diff HEAD~1 \
  | jq '{
      files: .diff.fileCount,
      hotspot: (.hotspots.byFile | to_entries | sort_by(-.value.score) | .[0]),
      riskTop: (.risk.byFile  | to_entries | sort_by(-.value.score) | .[0])
    }'
2

GitHub Action — fail on high-risk files

The CLI itself never gates on what it found — that is policy. Wrap it in a job that turns the JSON into a pass/fail. This action fails the check if any review-candidate file scores in the high-risk tier.

# .github/workflows/risk-gate.yml
name: PR risk gate

on:
  pull_request:
    branches: [main]

jobs:
  risk:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }   # full history needed for churn / cochange

      - uses: actions/setup-node@v4
        with: { node-version: '22' }

      - name: Install jq
        run: sudo apt-get install -y jq

      - name: Run analysis
        run: |
          npx --yes @prcompass/cli analyze \
            --repo . \
            --diff origin/main..HEAD \
            > analysis.json

      - name: Gate on high-risk review-candidates
        run: |
          HIGH_RISK_REVIEW=$(jq '
            [.triage.verdicts[]
              | select(.verdict == "review-candidate")
              | .path] as $review
            | .risk.byFile
            | to_entries
            | map(select(.value.tier == "high" and (.key | IN($review[]))))
            | length
          ' analysis.json)

          echo "High-risk review-candidates: $HIGH_RISK_REVIEW"
          if [ "$HIGH_RISK_REVIEW" -gt 0 ]; then
            echo "::error::PR touches files flagged high risk; require an extra reviewer."
            exit 1
          fi

      - uses: actions/upload-artifact@v4
        with:
          name: prcompass-analysis
          path: analysis.json
3

Programmatic — analyse a remote PR

The GitHubAdapter needs both a local clone (for the engine to walk history) and a PR number (for metadata enrichment). Bring your own Octokit so auth and rate-limits stay under your control.

// scripts/analyze-pr.ts
import { GitHubAdapter, runAnalyzeCommand, formatJson } from '@prcompass/cli';
import { Octokit } from '@octokit/rest';
import { resolve } from 'node:path';

const REPO_DIR = resolve('./checkout');  // local clone you cloned beforehand
const PULL = Number(process.argv[2]);
if (!Number.isFinite(PULL)) throw new Error('usage: analyze-pr <pr-number>');

const adapter = new GitHubAdapter({
  repoDir: REPO_DIR,
  octokit: new Octokit({ auth: process.env.GITHUB_TOKEN }),
  owner: 'nkwib',
  repo: 'prcompass-cli',
  pullNumber: PULL
});

const output = await runAnalyzeCommand(adapter);
process.stdout.write(formatJson(output, { pretty: true }) + '\n');
4

NDJSON: one line per analysis run

Long-running comparisons (every PR over 6 months, every commit on main in a quarter) are easier to consume as NDJSON. Default output is already compact JSON — append a newline and you're good.

# Walk every commit on main, one analysis per line
git rev-list main | head -200 | while read SHA; do
  prcompass analyze --repo . --diff "${SHA}~1..${SHA}" 2>/dev/null
  echo
done > main-walk.ndjson

# Then read it row-by-row
jq -c '{sha: .head.sha, riskCount: (.risk.byFile | length)}' main-walk.ndjson
5

Smoke test the binary on this monorepo

The repo ships a smoke npm script that runs the freshly built binary against the workspace itself. Useful to sanity-check changes to analyze.ts, the formatters, or the adapters.

# From the prcompass-cli repo
npm run build
npm run smoke
# → node dist/cli.js analyze --local --repo ../.. --diff HEAD~1

Got an integration not covered here?

The API surface is intentionally small. Open an issue with your use case — the answer is usually one jq filter.

@prcompass/cli Deterministic git-diff analysis on the command line