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

finest-ai-xray

v0.1.2

Published

Local, auditable LLM spend x-ray. Your key never leaves your machine.

Readme

finest-ai-xray

Your provider key never leaves your machine. This repository is how you check that, rather than a promise you have to take on faith.

finest-ai-xray reads what your LLM providers actually charged you over the last 30 days, from your own machine, using your own credentials, and prints a receipt. It is open source because the only useful version of the sentence above is one you can verify — so here are the exact lines that back it.

finest-ai-xray is not published and no npm coordinate is approved yet. Do not guess a registry name. From this repository, build it and run the explicit local artifact:

pnpm --filter finest-ai-xray build
node packages/xray/dist/cli.js                 # detect, ask, read, print, consent, upload
node packages/xray/dist/cli.js --demo          # a complete run on demo data: no keys, no network
node packages/xray/dist/cli.js --no-upload     # everything locally; nothing leaves this machine
node packages/xray/dist/cli.js --json          # machine-readable output on stdout

The claim, and the lines that back it

1. A detected key cannot be printed, logged, or serialised

Every credential is wrapped by src/secret.ts before anything else touches it. The material lives in a closure; toString, toJSON and Node's inspect hook all return the redacted display form. Interpolating a credential into a string, an error message, or JSON.stringify produces sk-ant-admin01-…, 108 chars — never the key.

  • secret()src/secret.ts
  • test/secret.test.ts proves it cannot leak through interpolation, JSON.stringify at depth, util.inspect, or an Error message.
  • test/cli.test.ts runs the whole CLI with synthetic keys in the environment and asserts that no contiguous eight-character window of any key body appears anywhere in the output.

The one way to read the material is .expose(). There are exactly three call sites, each building one outbound auth header:

| Call site | Header | Host | |---|---|---| | src/providers/openai.ts | Authorization: Bearer … | api.openai.com | | src/providers/anthropic.ts | x-api-key: … | api.anthropic.com | | src/upload.ts | Authorization: Bearer … | your Finest key — not a provider key |

test/secret.test.ts greps the source tree and fails the build if .expose( appears anywhere else.

2. Requests can only go to hosts on a closed allowlist

src/guard.ts is the only egress path in the package. guardedFetch refuses anything that is not https:, to an exactly-matching allowlisted host, with no userinfo in the URL. Redirects are handled manually (redirect: 'manual') so every hop is re-checked; a 302 to an off-allowlist host is an error, and crossing to a different host drops the auth headers.

test/guard.test.ts proves it rejects http://, an off-allowlist host, a host that merely ends with an allowlisted one (api.openai.com.evil.test), userinfo, an off-allowlist redirect, a redirect that downgrades to http, and a redirect loop — and that a blocked URL issues no request at all.

3. The prefix shown is matched, never sliced

ANTHROPIC_API_KEY detected (sk-ant-admin01-…, 108 chars)

That prefix comes from a fixed allowlist in KNOWN_KEY_PREFIXES. A value matching nothing on the list renders as unrecognized prefix, 108 chars — not the first N characters of whatever you happened to put in that variable.

4. Detection is by variable name

src/detect.ts looks up a fixed table of variable names in process.env and in ./.env. The .env reader does no interpolation and no command substitution — a program that evaluates the contents of a file full of secrets is not a program to trust.

5. Nothing is used, and nothing is uploaded, without a yes

Each credential is asked about individually. The upload prints the literal JSON that would be sent and asks again. src/prompt.ts has one rule: a non-TTY answers no. There is deliberately no --yes flag.


What each provider can actually tell you

Most collectors get this wrong by pretending. These are first-class states, each with its own message. None of them renders as $0.

| Provider | Reality | What this tool does | |---|---|---| | OpenAI | GET /v1/organization/usage/completions and GET /v1/organization/costs require an admin-scoped key. | With an ordinary sk-proj- key: reports scope_denied and sends nothing — an inference key is not handed to an endpoint that cannot use it. | | Anthropic | The Usage & Cost Admin API needs a distinct admin key (sk-ant-admin01-…). Anthropic's own docs: "The Admin API is unavailable for individual accounts." | Without an admin-prefixed key: admin_key_required, nothing sent. On HTTP 403/404: individual_account, with a message saying this is not a fault of your key or of this tool. | | Google | A Gemini API key does not expose billing. There is no endpoint for it. | Contacts nothing at all. Reports billing_not_exposed and offers the two paths that work: Cloud Billing BigQuery export, or --import-csv. | | Anything else | No integration yet. | Reported as a state and listed in scopeDenied on the upload — never silently omitted. |

Two provider quirks are handled rather than papered over:

  • Anthropic reports no request count. Not zero — the field does not exist in the usage report. Every Anthropic line shows not reported.
  • Anthropic cost amounts are cents-as-decimal-string. "123.45" USD is $1.2345. Reading it as dollars overstates a bill by 100×; centsStringToMicros gets it right and test/providers.test.ts asserts the documented worked example.
  • OpenAI cost line items are not model IDs. "gpt-4o-mini, input" is matched to a model only when it actually starts with a model ID from the usage report. Everything else lands in a clearly labelled unattributed row, and a model no line item accounts for keeps unknown — it never inherits a $0 it did not earn.

Latency

Latency not yet measured — install the shim

A billing API establishes spend. It does not establish latency. No arithmetic over an invoice yields a per-request millisecond figure or a "days spent waiting" aggregate, so this receipt does not print one — the upload schema even types the field as latencyMeasured: false so it cannot claim otherwise. Latency numbers appear once the SDK measures real requests.


What the upload contains

Only after you read it and say yes. Built and schema-validated in src/upload.ts against xrayReportRequestSchema — the same schema the server validates against — before it is printed for your consent.

Sent: provider · model ID · request count · input/output/cached token counts · cost in micros · window length · which providers could not be read · which endpoints were contacted.

Cannot be sent (the schema is a strict object with no field for any of it): prompts · completions · system prompts · tool definitions · file or project names · end-user identifiers · API keys · key prefixes · key lengths · your hostname.

Two edges are stated rather than hidden:

  • A line whose cost is unknown is not uploaded at all, because the schema requires an integer and there is no way to say "unknown" in it. The consent screen names every excluded line.
  • A line whose request count is unknown uploads requests: 0 — the schema requires an integer there too, and dropping the line would discard a real cost. Every such line is named at consent and again in the disclosure.

--no-upload skips step 6 entirely.


Estimate mode

When no usage API will answer, --estimate-from PATH scans .jsonl / .ndjson / .log files for lines that already carry token counts (the OpenAI, Anthropic and Gemini usage shapes), aggregates them, and prices them.

It reads only the path you name, does not follow symlinks out of it, skips node_modules and dotted directories, and looks only at numeric usage fields and the model ID — never at message content.

Prices come from @finest-ai/registry through an optional dynamic import. finest-ai-xray does not depend on it: the registry is proprietary and this package is Apache-2.0. When it is not installed — the normal standalone-CLI case — every estimated cost is reported as unknown. Not zero. A model with no verified price epoch produces a row that says so, the total excludes it, and the receipt says how many rows were excluded.

Every estimated figure is labelled estimate (local logs) in the source column.


No dependencies

finest-ai-xray has no runtime dependencies. No argument parser, no colour library, no spinner — just Node built-ins and small helpers in this package. @finest-ai/schemas (and the zod it uses to validate the upload) is bundled into the built artifact, so a future approved standalone distribution needs only one artifact and someone auditing what touches their key does not have to audit a dependency tree to do it.


Development

pnpm --filter finest-ai-xray exec tsc --noEmit
pnpm --filter finest-ai-xray test
pnpm --filter finest-ai-xray run build
pnpm exec oxlint --deny-warnings packages/xray
node packages/xray/dist/cli.js --demo --no-upload --json

Rotate your keys

Every run ends by saying this, and so does this README: rotate any key you pasted into a terminal, exported into a shell, or committed to a .env. It takes a minute and it costs nothing.

  • OpenAI — https://platform.openai.com/api-keys
  • Anthropic — https://platform.claude.com/settings/keys
  • Google — https://aistudio.google.com/app/apikey

Licence

Apache-2.0. See LICENSE.