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

@ykstormsorg/goldset

v0.2.4

Published

Lock your AI app's behavior. Golden datasets + LLM-as-judge + structural assertions in CI.

Readme

Goldset

Lock your AI app's behavior — golden datasets, LLM-as-judge, and structural assertions in CI.

npm CI License Docs


Contents


Why Goldset?

Most AI eval tools are dashboards with no CI integration. Goldset is the opposite:

  • Evals as code — sit next to your app in the same repo
  • GitHub Action native — PR diff comments, merge-blocking on regression
  • Provider agnostic — plug in any llm: (input) => Promise<string>
  • Three orthogonal runners — catch three completely different failure modes

| Runner | What it catches | Best for | |--------|-----------------|----------| | goldenDataset | Output drifted from canonical answer | FAQ, refusal correctness, deterministic Q&A | | llmJudge | Behavior regression on open-ended outputs | Tone, helpfulness, brand voice, language matching | | structural | Output shape broke | Function calling, structured generation, JSON schema |


Install

npm install @ykstormsorg/goldset

Peer dependency (not installed automatically):

npm install tsx   # for running .eval.ts files directly

Quickstart

1. Create an eval file

// evals/customer-support.eval.ts
import { goldenDataset, llmJudge, structural, runEval } from '@ykstormsorg/goldset'
import { myLLM, myJudge } from '../src/llm'

const golden = await goldenDataset(
  [
    { id: 'refund-q', input: 'How do I get a refund?', expected: 'Email support@...' },
    { id: 'shipping-q', input: 'Where is my order?', expected: 'Track at track.example.com/...' },
  ],
  { llm: myLLM, threshold: 0.85 }
)

const judged = await llmJudge(
  [
    { id: 'hindi-q', input: 'Bopal mein 2BHK?', expected: 'Hindi response' },
    { id: 'french-q', input: 'Comment ça marche?', expected: 'French response' },
  ],
  {
    llm: myLLM,
    judge: myJudge,
    rubric: 'Score 5 if response is in the same language as the input. 0 if not.',
    passThreshold: 3,
  }
)

const shape = await structural(
  [{ id: 'tool-q', input: 'lookup order #42' }],
  {
    llm: myLLM,
    assertions: [
      { type: 'json-schema', schema: { type: 'object', properties: { orderId: { type: 'string' } } } },
      { type: 'tool-call-shape', toolName: 'lookupOrder', argCount: 1 },
    ],
  }
)

// runEval prints a human summary (or JSON with `--output json`, as the
// GitHub Action does) and exits non-zero if any runner failed.
await runEval(golden, judged, shape)

2. Run locally

npx tsx evals/customer-support.eval.ts

Output:

✓ goldenDataset: 2/2 passed
✓ llmJudge: 2/2 passed
✓ structural: 1/1 passed

3. Add to CI

# .github/workflows/eval.yml
name: Goldset Eval

on:
  pull_request:
    branches: [main]

permissions:
  contents: read
  pull-requests: write

jobs:
  eval:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm ci
      - uses: ykstorm/goldset@v1
        with:
          eval-dir: evals
          judge-provider: none   # or openai | anthropic
          fail-on-regression: true
          comment-on-pr: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          # OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}   # if judge-provider: openai

The Action runs every *.eval.ts under eval-dir with npx tsx <file> --output json, writes a combined goldset-results.json, posts (or updates) a PR comment with a results table and a delta-vs-base section, and fails the check if any eval fails or regresses against the base branch — gating the merge.

GitHub Action

| Input | Default | Description | |-------|---------|-------------| | eval-dir | evals | Directory containing *.eval.ts files | | judge-provider | none | openai | anthropic | none. Exposes the matching key (already on the runner env) to your eval as GOLDSET_JUDGE_PROVIDER | | fail-on-regression | true | Fail the check if any eval regresses vs the base branch | | comment-on-pr | true | Post/update a results + delta comment on the PR |

Outputs: results-path, passed, failed, total, all-passed.


Three runners

| Runner | Function | Catches | |--------|----------|---------| | Golden dataset | goldenDataset(cases, { llm, threshold }) | Output drifted from the canonical answer (Levenshtein similarity vs a threshold) | | LLM-as-judge | llmJudge(cases, { llm, judge, rubric }) | Behavior regression on open-ended outputs (a second LLM scores against a rubric) | | Structural | structural(cases, { llm, assertions }) | Output shape broke (JSON schema, regex, substring, tool-call shape) |

See the full API reference.

License

Apache-2.0