npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

kustos

v1.0.0

Published

Compliance linter for call transcripts in VTT and SRT format

Readme

Kustos

Compliance linter for call transcripts in VTT and SRT format. Define rules in YAML, point kustos at a directory, get a structured HTML report with every violation flagged by timestamp, severity, and rule.

Built for fintech and regtech teams that need a fast, free, offline-first compliance pre-check layer before AI-assisted review.


Contributing

pnpm install
pnpm prepare  # sets up Husky hooks

Before pushing, the pre-commit hook runs lint-staged automatically — it formats and lints every staged .ts file. CI runs the full suite across Node 18, 20, and 22 on every push and PR.

Release flow

  1. Update CHANGELOG.md with the new version under a ## [x.y.z] header
  2. Push to main
  3. The release workflow detects the version change, syncs package.json, builds, publishes to npm, and creates a GitHub release automatically

Requires NPM_TOKEN set as a repository secret.


Install

npm install
npm run build
npm link

Usage

kustos ./calls

kustos looks for kustos.yaml inside the scanned directory by default. If your rules file lives elsewhere, pass it explicitly:

kustos ./calls --rules ./rules/finra.yaml

To write the report to a specific path:

kustos ./calls --out ./reports/2024-Q1.html

The short alias kt is also available after linking:

kt ./calls

| Argument | Required | Default | Description | | --------- | -------- | ---------------------- | ------------------------------------------- | | <dir> | yes | — | Directory containing .vtt or .srt files | | --rules | no | <dir>/kustos.yaml | Path to YAML rules file | | --out | no | ./report/report.html | Output path for HTML report |


Rules Format

Place a kustos.yaml file inside your transcripts directory, or point to one with --rules.

- id: RULE-001
  description: Advisor must not guarantee returns
  type: keyword
  pattern: "guaranteed returns"
  severity: high

- id: RULE-002
  description: Do not promise specific percentage gains
  type: regex
  pattern: "\\d+%\\s+(return|profit|gain)"
  severity: high

- id: RULE-003
  description: Risk must not be denied or minimized
  type: keyword
  pattern: "no risk"
  severity: medium

- id: RULE-004
  description: Urgency pressure tactics are prohibited
  type: regex
  pattern: "(limited time|act now|don't wait)"
  severity: low

| Field | Type | Values | | ------------- | ------ | ---------------------------------------------- | | id | string | Unique identifier — duplicates are rejected | | description | string | Human-readable description shown in the report | | type | string | keyword or regex | | pattern | string | Literal string or JavaScript regex pattern | | severity | string | low, medium, or high |

keyword does a case-insensitive literal match. regex evaluates the pattern as a JavaScript regular expression with gi flags. Invalid regex patterns are caught at startup before any files are scanned.


Exit Codes

| Code | Meaning | | ---- | ------------------------------------------ | | 0 | No high-severity violations found | | 1 | One or more high-severity violations found |

The exit code is the integration hook. Any tooling that reads process exit codes — CI pipelines, shell scripts, pre-commit hooks — reacts to it automatically without parsing the HTML report.


CI/CD Integration

GitHub Actions

Drop this into any workflow that handles call recordings or transcript uploads. If a high-severity violation is found the step exits with 1, the pipeline stops, and the HTML report is still uploaded as an artifact so the team can see exactly what triggered it.

name: Compliance Check

on:
  push:
    paths:
      - "recordings/**"

jobs:
  compliance:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Install kustos
        run: npm install && npm run build && npm link

      - name: Scan transcripts
        run: kustos ./recordings --out ./report.html

      - name: Upload report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: compliance-report
          path: report.html

if: always() on the upload step is intentional — when the scan fails the job stops, but you still want the report artifact. Without it, a failing scan would leave the team with no visibility into which calls triggered violations.

Pre-commit Hook

Catch violations before recordings hit the remote. Wire kustos into husky:

npx husky init
echo "kustos ./recordings" > .husky/pre-commit

Commits that introduce high-severity violations are blocked locally before they ever reach CI.

Shell Script Composition

Because kustos exits with a standard code, it composes cleanly with anything:

kustos ./calls && echo "Passed" || echo "Violations found — check report.html"

Or with a Slack webhook:

kustos ./calls \
  && curl -s -X POST $SLACK_WEBHOOK -d '{"text":"Compliance check passed"}' \
  || curl -s -X POST $SLACK_WEBHOOK -d '{"text":"Violations found — review report"}'

Error Handling

kustos validates aggressively at startup and before processing any files:

  • Missing or unreadable directory — exits immediately with a clear message
  • Missing rules file — exits with a message pointing to the expected location
  • Invalid YAML in rules file — exits and prints the parse error
  • Invalid rule shape (wrong type, missing fields, bad regex, duplicate IDs) — exits and lists every issue
  • Unreadable transcript file — skipped with a warning, scan continues
  • Empty transcript file — skipped with a warning, scan continues
  • Unparseable transcript — skipped with a warning, scan continues
  • No valid files found after skipping — exits cleanly with code 0

Development

npm run dev -- ./examples
npm test
npm run lint

Project Structure

src/
  index.ts       CLI entry, argument parsing, orchestration
  parser.ts      VTT and SRT parsing
  engine.ts      Rule evaluation
  reporter.ts    HTML report generation
  validator.ts   Rules file validation
  types.ts       Shared TypeScript interfaces
tests/
  engine.test.ts
  parser.test.ts
  validator.test.ts
examples/
  sample.vtt
  sample.srt
  kustos.yaml