Use the SDK
Submit reviews, start scans and triage findings from TypeScript, with a client that has zero runtime dependencies.
Install
npm install --save-dev @patchlight/sdkNeeds Node.js 18.17 or newer. The package has no runtime dependencies and stays that way, so CI installs stay small.
Authenticate
Create an API key on the API Keys page of the dashboard. It is shown once.
import { createClient } from "@patchlight/sdk";
const client = createClient({ apiKey: process.env.PATCHLIGHT_API_KEY! });A key belongs to the workspace that was active when you created it. It bills that workspace's balance and files reviews under it. Revoking a key takes effect within about a minute.
The client talks to https://api.patchlight.dev. Override it with the baseUrl option or the
PATCHLIGHT_BASE_URL environment variable.
Review a diff
const { id } = await client.createReview({
repo: "acme/checkout-service", // any name, groups reviews in the dashboard
diff: myUnifiedDiff, // unified diff text, from git or anywhere else
});
// Polls until the review settles. Throws if it fails, is skipped or times out.
const review = await client.waitForReview(id);
console.log(review.summary);
const { findings } = await client.getReviewFindings(id);
for (const f of findings) {
console.log(`[${f.severity}] ${f.title} at ${f.filePath}:${f.line}`);
}Only repo and diff are required. Passing the contents of the changed files makes the review
noticeably better:
await client.createReview({
repo: "acme/checkout-service",
diff: myUnifiedDiff,
files: { "src/payment.ts": paymentSource },
ref: "9f2c1ab", // the reviewed commit
baseRef: "main", // what the diff is against
title: "Add 3DS fallback",
});A review is billed from the workspace balance. When the balance is too low, the submit fails with
insufficient_funds.
Scan a repository
A scan reads a whole repository. It needs a repository connected through the GitHub App, because the scanner clones it itself.
const repos = await client.listRepos();
const repo = repos.find((r) => r.fullName === "acme/checkout-service")!;
const { id } = await client.startScan(repo.id);
await client.waitForScan(id);
const { findings } = await client.getScanFindings(id);One scan per repository runs at a time, and scans are billed per token. To scan a local checkout instead, use the CLI.
Triage findings
const findings = await client.listFindings();
for (const f of findings.filter((f) => f.category === "style")) {
await client.updateFinding(f.id, "dismissed");
}updateFinding takes review and scan finding ids alike, so you never need to check which kind you
hold.
Every method, option and error code is in the SDK client reference.