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

@beon-tech/ai-score

v0.1.9

Published

Extracts AI coding harness usage (Claude Code, Codex, Cursor, OpenCode, pi) into an auditable, privacy-preserving report and submits it to Beon for scoring.

Readme

@beon-tech/ai-score

CLI that measures how an engineer uses AI coding tools. It scans the session data that coding harnesses already keep on your machine, derives privacy-safe edit/check evidence, and submits it to Beon's scoring service. The server returns a Verified Workflow score plus a separate Usage Profile.

npx @beon-tech/ai-score              # sign in if needed, scan, summarize, confirm, upload
npx @beon-tech/ai-score --dry-run    # scan and summarize only — never touches the network
npx @beon-tech/ai-score --audit      # print the exact JSON that would be uploaded

Uploading requires signing in once per machine. The first upload opens your browser automatically; you can also do it up front:

npx @beon-tech/ai-score login        # choose a provider in the browser, then close the tab
npx @beon-tech/ai-score whoami       # show which account this machine submits as
npx @beon-tech/ai-score logout       # forget the cached token

Supported harnesses

| Harness | Source scanned | | ------------ | --------------------------------------------------------------------------- | | Claude Code | ~/.claude/projects/**/*.jsonl | | Codex CLI | ~/.codex/sessions/**/*.jsonl (+ archived_sessions) | | Cursor CLI | ~/.cursor/chats/**/store.db (node:sqlite) | | Cursor (app) | Cursor's globalStorage/state.vscdb and workspaceStorage (node:sqlite) | | OpenCode | ~/.local/share/opencode/opencode.db (node:sqlite) | | pi | ~/.pi/agent/sessions/**/*.jsonl |

Sources marked node:sqlite need Node ≥ 22.5; on older Node those harnesses report a skippedReason and the rest of the scan proceeds.

Cursor ships two products that share a name and nothing else, so they report as two harnesses — cursor-cli and cursor-ide. They record different things: the desktop app tracks tokens, cost and per-session diff stats, while the CLI's session store keeps neither timestamps per message nor token counts, so cursor-cli sessions carry a model id with an empty usage bucket and no longestTurnMs.

Harness data is read-only — the CLI never modifies it. The one thing it writes outside of --out is your access token, cached in ~/.config/beon/ai-score.json with 0600 permissions.

Authentication

Submissions are attributed to an account you sign in to, not to a string your machine asserts. login uses the OAuth 2.0 device authorization grant (RFC 8628): the CLI asks the server for a code, opens the approval page, and polls until you approve. Because the browser does the provider handshake, the CLI never holds a GitHub or GitLab credential — only a Beon-issued token — and new providers can be added server-side without a new release of this package.

Compare the code in your terminal against the one on the page before approving. If they differ, someone else sent you that link; deny it.

There is no local HTTP listener, so this works over SSH and inside containers. Use --no-browser to print the URL instead of opening one, and AI_SCORE_TOKEN for CI, where no browser can open at all:

AI_SCORE_TOKEN=… npx @beon-tech/ai-score --yes

Privacy model

All classification happens on-device. The CLI transiently inspects tool arguments, structured result statuses, and recorded check output (only to read a test runner's own pass/fail summary when a pipe hid the exit code) to recognize edits, tests, typechecks, builds, lint runs and delivery events, then immediately discards the raw values. What leaves your machine is structural metadata and derived enums only. No code, prompts, message text, file paths, branch names, raw commands, arguments, or tool outputs are uploaded. The full field-by-field contract is in WIRE_FORMAT.md.

Two things leave your machine besides the payload, both only when you sign in: the device-flow exchange with ai-score.beon.tech, and the access token presented on upload. Your provider account is verified in the browser, so no provider credential ever reaches this CLI.

You can hold the tool to that promise before anything is sent:

npx @beon-tech/ai-score --dry-run --audit          # inspect payload in the terminal
npx @beon-tech/ai-score --dry-run --out report.json # or write it to a file

--dry-run needs no account and touches no network, so it works before you ever sign in. Uploading always requires explicit confirmation (interactive y/N, or an explicit --yes in scripts). This package has zero runtime dependencies, so auditing the code means reading src/ and nothing else.

Commands and options

(no command)        scan, summarize, confirm, upload
login               sign in through the browser
logout              forget the cached token for this server
whoami              print the account this machine submits as
--days <n>          look-back window in days (default: 30)
--harness <names>   comma-separated subset: claude-code,codex,cursor-cli,
                    cursor-ide,opencode,pi
--url <url>         ai-score server (default: $AI_SCORE_URL or
                    https://ai-score.beon.tech)
--no-browser        print the login URL instead of opening a browser
--audit             print the exact JSON payload
--out <file>        write the payload to a file
--dry-run           never touch the network
--yes               skip the interactive upload confirmation
--endpoint <url>    deprecated: exact submissions URL, overrides --url
--verbose           log each session file as it is parsed

| Environment variable | Effect | | -------------------- | --------------------------------------------- | | AI_SCORE_TOKEN | use this token instead of signing in (for CI) | | AI_SCORE_URL | default server, same as --url | | XDG_CONFIG_HOME | where the token is cached, if set |

Architecture

src/
  cli.ts             argument parsing, commands, orchestration, consent
  config.ts          resolves which server to talk to
  types.ts           the beon.ai-score.v2 wire format
  workflow.ts        local command classification and workflow reduction
  adapters/
    claude-code.ts   one adapter per harness — each translates its native
    codex.ts         on-disk format into the common SessionRecord shape
    cursor-cli.ts
    cursor-ide.ts
    opencode.ts
    pi.ts
  auth/
    index.ts         login/logout/whoami orchestration and token resolution
    client.ts        the credential chokepoint (device flow + session lookup)
    store.ts         the token cache, 0600, keyed by server origin
    browser.ts       best-effort browser launch
  summary.ts         human-readable terminal summary
  send.ts            the payload chokepoint (one POST)

Design rules:

  • The client derives evidence but never scores it. It classifies native records into fixed workflow enums; all weighting and eligibility remain server-side. A classifier change requires engineers to rescan local history, while a score-weight change remains fully server-side.
  • Adapters are defensive. Harness log formats are undocumented internals that change between versions. Unparseable records are skipped and counted (parseErrors), never fatal.
  • Two network chokepoints, with distinct jobs. send.ts is the only file that sends a payload, and it never obtains credentials. auth/client.ts is the only file that obtains or presents credentials, and it never sees a payload. Auditing what leaves the machine means reading those two files.
  • The client asserts no identity. It sends a token; the server decides who that is. Nothing in the payload says who you are, which is why provider support lives entirely on the server.

Adding a harness

Implement the Adapter interface in src/adapters/<name>.ts, register it in src/adapters/index.ts, add the HarnessName union member in types.ts, and document any new fields in WIRE_FORMAT.md. Raw text may only be inspected transiently by a local classifier; only names, counts, timestamps, enums and hashes may enter SessionRecord.

Adding a sign-in provider

Nothing to do here. The CLI has no provider code — it only knows how to run a device flow against the server, and the server owns which providers exist. Add the provider to the server's auth config and a button to its approval page; engineers get it without updating this package.

Server contract

The CLI POSTs the payload as JSON to <server>/api/v1/submissions with an Authorization: Bearer <token> header, and treats any 2xx as success. A 401 or 403 means the token is dead: the CLI drops it and tells the engineer to log in again. The ingest endpoint validates schema === "beon.ai-score.v2", resolves the submitter from the token (never from the payload), stores the raw submission, and computes both results server-side so their weights can evolve independently of the client. The response keeps score as the Usage Profile for older clients and adds verifiedWorkflow for current clients.

Auth endpoints used, all under <server>/api/auth: POST /device/code, POST /device/token, GET /get-session.

Development

pnpm install
pnpm build
pnpm test
node dist/cli.js --dry-run --verbose

# against a local server
AI_SCORE_URL=http://localhost:3000 node dist/cli.js login

Releasing

Every push to main automatically publishes a patch release via the release workflow: CI bumps the version, builds, smoke-tests, publishes to npm, and pushes the release commit and vX.Y.Z tag back — the tag only lands if the publish succeeded. For a minor or major release, trigger the workflow manually instead:

gh workflow run Release --repo BEON-Tech/ai-score -f bump=minor

Publishing uses npm trusted publishing (GitHub Actions OIDC — no npm tokens anywhere), which attaches a provenance attestation linking the published tarball to the exact commit and workflow run that built it. Never bump versions locally.