SARIF pipeline
Sverka provides an end-to-end SARIF pipeline: serialize findings, view them in a terminal TUI, generate HTML reports, and serve a local web dashboard.
Sverka provides an end-to-end SARIF pipeline: serialize findings, view them in a terminal TUI, generate HTML reports, and serve a local web dashboard.
Overview
sverka run --format sarif
│
▼
.sverka/findings.sarif
│
├──→ sverka view <file> (terminal TUI)
├──→ sverka view <file> -f web (HTML report)
├──→ sverka ui (web dashboard, scans .sverka/artifacts/)
└──@sverka/verification (programmatic API)Note:
sverka run --format sarifwrites to.sverka/findings.sarifby default. Thesverka uidashboard scans.sverka/artifacts/for SARIF files. To make findings visible in the dashboard, either copy the file:cp .sverka/findings.sarif .sverka/artifacts/or write directly to the artifacts directory:sverka run --format sarif -o .sverka/artifacts/findings.sarif.
Serializing findings
serializeSarif converts normalized Finding[] to a SARIF 2.1.0 log:
import { serializeSarif, normalizeSarif } from "@sverka/verification";
// Normalize external SARIF into findings
const findings = normalizeSarif(rawSarif, {
root: process.cwd(),
checkIdPrefix: "",
defaultConfidence: 0.5,
});
// Serialize findings back to SARIF
const sarifLog = serializeSarif(findings);
// sarifLog.version === "2.1.0"
// sarifLog.runs[0].tool.driver.name === "eslint"
// sarifLog.runs[0].results[0].ruleId === "no-unused-vars"The serializer:
- Groups findings by source tool into separate runs
- Deduplicates rules within each run
- Maps Sverka severity to SARIF level (
critical/high→error,medium→warning, etc.) - Includes fingerprints, locations, and optional snippets
Running checks with SARIF output
# Run workflow and produce SARIF
sverka run --format sarif
# Custom output path
sverka run --format sarif -o reports/findings.sarifThis runs the workflow, collects findings from all steps, serializes them
to SARIF 2.1.0, and writes to .sverka/findings.sarif (or the path you
specify with -o).
Viewing findings
Terminal TUI
# View a SARIF file in the terminal
sverka view findings.sarif
# Pipe SARIF via stdin
cat findings.sarif | sverka viewThe TUI provides:
- Severity filtering (all, critical, high, medium, low, info)
- Text search across message, check ID, file, and rule
- Column sorting (severity, file, rule)
- Detail panel with full finding information
- Keyboard navigation (j/k, /, f, s, d, q)
Both viewers are standalone packages — they work on any SARIF 2.1.0 file from any tool (Semgrep, CodeQL, ESLint, Bandit) without installing Sverka's workflow runtime, and each ships its own binary:
# Same TUI, no sverka install — file argument or stdin
npx @sverka/sarif-viewer-tui findings.sarif
cat findings.sarif | npx @sverka/sarif-viewer-tui
# Same HTML report — defaults output to sarif-report.html
npx @sverka/sarif-viewer-web findings.sarif -o report.htmlHTML report
# Generate an HTML report
sverka view findings.sarif --format web
# Custom output path
sverka view findings.sarif --format web -o report.htmlThe HTML report is self-contained — inline CSS and JavaScript, no external dependencies, no CDN. It includes:
- Summary counts (total, critical, high, medium, low, info)
- Tool name from the first finding
- Severity filtering, text search, and column sorting
- XSS-safe rendering (escaped HTML and JSON)
Web dashboard
# Start a local web dashboard
sverka ui
# Custom port and host
sverka ui --port 8080 --host 0.0.0.0The dashboard:
- Lists all SARIF files in
.sverka/artifacts/ - Click any file to view the rendered findings report
- Path traversal protection on report endpoints
- Pure Node.js
http— no external server dependency
Running with web output
# Run workflow and generate HTML report directly
sverka run --format web
# Custom output path
sverka run --format web -o .sverka/report.htmlThis runs the workflow, collects findings, generates a self-contained HTML
report via @sverka/sarif-viewer-web, and writes it to disk.
Programmatic API
Serialize
import { serializeSarif, type Finding } from "@sverka/verification";
const sarifLog = serializeSarif(findings);
const json = JSON.stringify(sarifLog, null, 2);TUI viewer
import { renderSarifTui } from "@sverka/sarif-viewer-tui";
await renderSarifTui({ sarif: sarifLog });
// or: await renderSarifTui({ findings });
// or: await renderSarifTui({ sarifPath: "findings.sarif" });Exactly one of sarif, sarifPath, findings must be provided; a
context?: NormalizeContext option overrides the default normalization
({ root: cwd, checkIdPrefix: "", defaultConfidence: 0.5 }, exported as
DEFAULT_NORMALIZE_CONTEXT). For embedding inside another Ink app, the
SarifTuiApp component takes Finding[] directly:
import { SarifTuiApp } from "@sverka/sarif-viewer-tui";
<SarifTuiApp findings={findings} />;The standalone viewer deliberately drops the new and error filters
the run TUI has — they need baseline fingerprints and run context a
SARIF file doesn't carry.
HTML generator
import { generateSarifHtml, renderSarifWeb } from "@sverka/sarif-viewer-web";
// Pure function — no I/O
const html = generateSarifHtml(findings);
// Or write to file
await renderSarifWeb({ findings, outputPath: "report.html" });Web dashboard server
import { startUiServer } from "@sverka/ui";
const server = await startUiServer({
artifactsDir: ".sverka/artifacts",
port: 3000,
host: "localhost",
});
console.log(`Dashboard running at ${server.url}`);
// server.close() to stopPackages
| Package | Purpose |
|---|---|
@sverka/verification | serializeSarif, normalizeSarif, Finding types |
@sverka/sarif-viewer-tui | Ink-based terminal TUI |
@sverka/sarif-viewer-web | Self-contained HTML report generator |
@sverka/ui | Local web dashboard server |
All viewer packages are standalone — they do not depend on
@sverka/runtime, @sverka/workflow, or @sverka/reporter.
Next steps
- Built-in checks — check IDs and SARIF extraction
- Findings normalization — SARIF normalization details
- Policy enforcement — severity rules and gates
Suspend and resume
> **Work in progress.** Suspend is implemented in the native engine. > `Engine.resume()` is specified but **not yet implemented** — the engine > throws
Remote Run Hub API
The remote run hub (Spec 55) provides two things, in the nx-cloud model: a **shared remote cache** and **run history** (reports + findings). The self-hosted