Examples
Real invocations grouped by where this CLI tends to land — jq on the terminal, GitHub Actions in CI, programmatic
use from Node.
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])
}'
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
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');
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
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.