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

prism-triage

v3.0.2

Published

BYOK GitHub PR/Issue triage tool — de-duplicate, rank, and vision-check PRs at scale

Readme

pr-prism

CI npm version license node

triage tool for repos drowning in PRs. finds dupes, ranks quality, checks vision alignment across repos.

built this because i saw someone staring at 3000+ open PRs and losing their mind trying to figure out which ones were duplicates. turns out 40% of them were. ran pr-prism on 6K+ items across a real repo, found 594 duplicate clusters.

who this is for: maintainers, triage teams, anyone staring at a 4-digit PR count and wondering where to start.

quickstart

brew tap stresstestor/tap && brew install prism-triage
prism init
prism scan
prism triage

or with npm: npm install -g prism-triage

pipeline

scan ─── fetch PRs + issues via GraphQL
  │
embed ── vectorize titles + bodies
  │
  ├── dupes ── cluster by cosine similarity
  ├── rank ─── score by quality signals
  ├── vision ─ check alignment with VISION.md
  └── review ─ LLM deep review
  │
triage ─ run everything in one shot

why pr-prism

  • zero cost default: ollama + opencode zen + github PAT. $0 to run
  • local-first: sqlite + sqlite-vec, everything stays on your machine
  • multi-repo: repos: [a/b, c/d] in config, cross-repo dupe detection
  • multi-provider: ollama, jina, openai, voyage, kimi for embeddings. opencode, openai, anthropic, kimi, ollama for LLM
  • cross-repo dupes: the thing no other free tool does. finds duplicates across different repos
  • incremental: only re-embeds new/changed items, crash-recoverable
  • read-only by default: won't touch your repo unless you pass --apply-labels

commands

| command | what it does | |---------|-------------| | prism scan | fetch PRs + issues into local db (GraphQL default, --rest fallback) | | prism dupes | cluster duplicates, show best picks | | prism rank | score and rank by quality signals | | prism vision | check alignment against VISION.md or README | | prism review <n> | LLM review of a specific PR or issue | | prism triage | full pipeline in one shot | | prism report | generate markdown triage report | | prism stats | database stats, embedding coverage, provider info | | prism doctor | check config, providers, db health | | prism init | auto-detect providers, generate config | | prism re-embed | re-embed with current provider (no github fetch) | | prism compare <n1> <n2> | compare two PRs/issues for similarity | | prism benchmark | compare embedding models for quality + speed | | prism reset | wipe database and start fresh |

flags

prism scan --state all              # open + closed items
prism scan --since 7d               # only items updated in last 7 days
prism dupes --threshold 0.9         # stricter similarity
prism dupes --cluster 3             # inspect specific cluster
prism dupes --starmap map.json      # stable JSON contract for visualizers
prism dupes --housekeeping todo.md  # editable close-checklist manifest
prism init -r owner/repo -y         # non-interactive init, repo from flag
prism rank --top 50 --explain       # top 50 with signal breakdown
prism vision --stats                # histogram + section breakdown
prism vision --detail               # per-item alignment table
prism review --top 10               # batch review top 10
prism review 42 --type issue        # review an issue
prism review --show 42              # show saved review
prism triage --output markdown      # markdown output for github issues
prism dupes --json | jq '.bestPick' # machine-readable NDJSON
prism compare 42 99          # check similarity between two items
prism benchmark --repo sst/opencode                              # compare default models
prism benchmark --models nomic-embed-text,qwen3-embedding:0.6b    # specify models

zero cost setup

run the whole thing for free:

  • embeddings: ollama + nomic-embed-text (local, 768 dims, 3.7x faster than qwen3)
  • LLM: opencode zen (kimi-k2.5-free, $0)
  • github: 5000 GraphQL points/hr with a PAT (~36 queries for 3500+ PRs)
brew install ollama
ollama pull nomic-embed-text

cloud alternative: jina gives 10M free tokens per key, no account needed.

multi-repo config

version: 1

# single repo
repo: owner/repo

# or multi-repo
repos:
  - owner/repo1
  - owner/repo2
  - owner/repo3

# per-repo vision docs
vision_docs:
  owner/repo1: ./VISION_1.md
  owner/repo2: ./VISION_2.md

cross-repo dupe display: [owner/repo1] #1234 <-> [owner/repo2] #567

providers

| type | provider | cost | notes | |------|----------|------|-------| | embedding | ollama | free | local, default (nomic-embed-text) | | embedding | jina | free tier | 10M tokens/key | | embedding | openai | paid | text-embedding-3-small | | embedding | voyageai | paid | | | embedding | kimi | free tier | | | LLM | opencode | free | kimi-k2.5-free, default | | LLM | openai | paid | gpt-4o-mini | | LLM | anthropic | paid | | | LLM | kimi | free tier | | | LLM | ollama | free | local |

labeling

prism can label your github PRs/issues but won't unless you say so:

prism dupes --apply-labels      # mark dupes + best picks
prism vision --apply-labels     # aligned/drifting/off-vision
prism dupes --dry-run           # preview first

read-only by default. always.

every github write (labels, comments, closes, issue creation) funnels through one gate that defaults to dry-run. the CLI writes only under --apply-labels. the webhook server writes only when PRISM_APPLY=1 is set - without it a deployed bot logs what it would do instead of touching the repo. --dry-run always wins.

housekeeping

prism dupes --housekeeping todo.md writes an editable markdown checklist: per cluster, the tracker issue (the original bug report), role-tagged fix/duplicate candidates, and paste-ready close text. loose clusters get flagged for review instead of a close directive. confirmed exact-dupes lead the checklist.

it's a checklist you edit and act on. prism never closes anything itself.

star map export

prism dupes --starmap map.json emits a stable JSON contract for external visualizers (schema v1, additive-only evolution): clusters with confidence tiers, contested + runner-up, tracker, item state (open/closed/merged), embedding metadata, and github node ids as a join key.

github action

run pr-prism automatically on every PR:

# .github/workflows/prism-triage.yml
name: PR Triage
on:
  pull_request:
    types: [opened, reopened]
  schedule:
    - cron: '0 0 * * 1'  # weekly full scan

jobs:
  triage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: StressTestor/pr-prism@main
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          embedding-provider: jina
          embedding-api-key: ${{ secrets.JINA_API_KEY }}

on pull_request events, prism checks if the new PR is a duplicate and comments with matches. on schedule, it does a full triage scan.

docker

docker build -t pr-prism .
docker run --rm -v $(pwd):/work -w /work --env-file .env pr-prism triage

live triage bot

run pr-prism as a GitHub App that auto-triages every new issue and PR in real time.

what it does:

  • comments on new issues with duplicate matches and source-of-truth links
  • optionally auto-closes obvious dupes (>95% similarity, opt-in)
  • suggests code owners via CODEOWNERS parsing
  • posts a weekly triage digest
  • runs a full backlog scan when first installed on a repo

self-hosted setup:

  1. register a GitHub App at github.com/settings/apps/new
    • permissions: issues (read+write), pull requests (read), metadata (read), contents (read)
    • webhook URL: your server's public URL + /webhook
    • subscribe to events: issues, pull_request, installation, installation_repositories
  2. provision a server (Oracle ARM free tier works)
  3. run the setup script:
    git clone https://github.com/StressTestor/pr-prism.git /opt/prism-bot
    cd /opt/prism-bot && ./server/deploy/setup.sh
  4. copy your .env and private key, then restart the service

per-repo config: drop a .prism.json in your repo root to customize:

{
  "autoClose": true,
  "autoCloseThreshold": 0.95,
  "similarityThreshold": 0.85,
  "weeklyDigest": true,
  "smartRouting": true
}

how dupe detection works

embeds every PR/issue title+body into a vector, stores in sqlite-vec, computes cosine similarity across all pairs. anything above 0.85 gets clustered. each cluster picks a "best" based on quality score (tests, CI, diff size, reviews, recency, description quality). rest get flagged as dupes.

every cluster reports a confidence tier off its minimum pairwise similarity (high >= 90%, solid >= 80%, loose < 80%), so a chained-together loose cluster gets eyeballed before anything is closed. near-tied best picks get a contested flag with the runner-up named. issue-majority clusters resolve to the earliest report (the original bug), PR-majority to the highest quality item, and merged PRs beat open ones.

above the embedding clusters sits a confirmed tier: PRs with the same head commit or an identical patch (git patch-id) are exact duplicates, grouped deterministically with no similarity threshold involved.

for repos with 5000+ items, automatically switches from brute-force to ANN pre-filtering via sqlite-vec, then verifies with exact cosine similarity.

programmatic usage

pipeline functions are independently importable:

import { createPipelineContext, runScan, runDupes, runRank } from "prism-triage";

const ctx = await createPipelineContext();
await runScan(ctx, { json: true });
const clusters = await runDupes(ctx, { json: true });
ctx.store.close();

performance

  • matryoshka truncation: EMBEDDING_DIMENSIONS=512 in .env halves storage with 91% clustering agreement
  • ANN pre-filtering kicks in at 5000+ items automatically
  • incremental scan: only embeds new/changed items
  • crash recovery: resumes from last embedded item
  • batch size: configurable via batch_size in config (default 50)

notes

  • first scan of ~3500 PRs via GraphQL: ~3 min (pagination + author history)
  • embedding ~10000 items with nomic-embed-text locally: ~13 min on M1 Air (was ~47 min with qwen3)
  • after that it's incremental
  • switching providers: prism re-embed or prism reset
  • sqlite-vec pinned at 0.1.7-alpha.2 (alpha but stable in our testing)

contributing

see CONTRIBUTING.md

license

MIT