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

tokenspendorg

v0.2.0

Published

Zero-setup CLI to backfill local agent-CLI transcript usage (Claude Code first) into tokenspend.org via POST /api/v1/ingest. Reads ~/.claude locally; only usage metadata is uploaded — never your prompts.

Readme

tokenspendorg

Zero-setup, zero-admin backfill of your local agent-CLI usage history into tokenspend.org. v1 reads Claude Code's on-disk transcript store (~/.claude/projects/**/*.jsonl), reconstructs per-call token usage, and uploads it to the existing flat POST /api/v1/ingest.

ingest and setup read usage metadata only — model, timestamps, token counts. They never read, store, or transmit your prompts, responses, tool I/O, or file contents. The separate analyze command opts into sending locally-redacted conversation text to Haiku on your own machine to classify it, and uploads only the resulting normalized task summaries — see its section and the Privacy notes below.

See the full design contract in ../docs/context/08-local-transcript-backfill-cli-spec.md.

Usage

TOKENSPEND_TOKEN="ts_…" \
TOKENSPEND_URL="eu.tokenspend.org" \
  npx tokenspendorg ingest --connectors claude

Preview first (nothing leaves your machine):

npx tokenspendorg ingest --connectors claude --dry-run

Go live for future sessions. setup writes the OpenTelemetry config into the env block of Claude Code's settings.json (default ~/.claude/settings.json), tailored to your org's identity mode:

npx tokenspendorg setup --connectors claude

Because the config lives in settings.json rather than a shell rc file, Claude Code picks it up on its next startup with no shell restart — and it works the same whether Claude Code is launched from a terminal, an IDE, the desktop app, or a wrapper like Conductor (none of which source your shell rc).

If you previously ran an older version that wrote export … lines into a shell startup file, setup migrates you automatically: it detects the old tokenspendorg block (in ~/.zshrc, ~/.zshenv, ~/.bashrc, ~/.bash_profile, ~/.profile, ~/.config/fish/config.fish, plus any file it recorded before or one you pass via --rc-file) and removes it as part of the update.

The chosen method and version are recorded under setup in ~/.config/tokenspendorg/config.json (setup.version), so re-runs and future upgrades know how the machine was last configured. Run tokenspendorg config to see it.

If your machine has an enterprise managed settings file (/Library/Application Support/ClaudeCode/managed-settings.json on macOS, /etc/claude-code/managed-settings.json on Linux) that already defines these telemetry vars, setup won't touch your user settings.json — managed settings are the highest-precedence scope and can't be overridden, so a user-level write would silently do nothing. Instead it tells you which keys are pinned and where, so you (or your admin) can point the managed exporter at this org.

Preview without writing (--print), or skip the confirmation (--yes). To write somewhere other than <claude-dir>/settings.json, pass --settings-file <path>.

Task analysis (analyze)

analyze is a different kind of signal: instead of token counts, it figures out what you actually do with Claude Code. It condenses your recent sessions, classifies each into a normalized, reusable task with Haiku, and uploads those task summaries to POST /api/v1/task-analysis.

# One pass now — preview which sessions would be analyzed, send nothing:
npx tokenspendorg analyze --dry-run

# One real pass:
npx tokenspendorg analyze

Each task looks like Write a web scraper using Playwright to extract product prices with a category (engineering/research/writing/ops/analysis/ planning/communication), a success level (delivered_cleandelivered_with_frictionpartialabandoned), and any friction points — the taxonomy ported from the task-profile plugin.

How Haiku is called. analyze shells out to your local claude CLI in headless mode (claude -p --model claude-haiku-4-5), so it reuses your existing Claude Code auth — no extra API key. Those Haiku calls run in a dedicated working directory (--analyzer-dir, default ~/.config/tokenspendorg/analyzer) with telemetry disabled, and their own transcripts are excluded from both ingest and the next analyze pass, so the daemon never measures or re-analyzes itself.

Run it every hour as a background service (macOS / launchd):

npx tokenspendorg analyze --install --interval 1h   # asks before writing the agent
npx tokenspendorg analyze --status                  # is it loaded?
npx tokenspendorg analyze --uninstall

--install writes a per-user LaunchAgent (~/Library/LaunchAgents/org.tokenspend.analyzer.plist, RunAtLoad + KeepAlive) that runs analyze --interval 1h at login and restarts it if it exits; logs go to ~/Library/Logs/tokenspendorg-analyzer.log. Use --print to see the agent without installing. Without the service you can just run analyze --interval 1h in a terminal/tmux — same loop, foreground.

State is tracked per-session in the same --state-file (key claude-analyze), so re-runs only analyze sessions they haven't seen. --max-sessions caps how many a single pass classifies (the rest run next pass), keeping per-tick Haiku cost bounded.

Options

| Flag | Env | Default | Meaning | |---|---|---|---| | --token | TOKENSPEND_TOKEN | — (required) | org API key ts_…, sent as Authorization: Bearer. | | --url | TOKENSPEND_URL | https://tokenspend.org | host; a bare host is normalized to https://. | | --email | TOKENSPEND_EMAIL | — | override the stored identity email (see Identity below). | | --reconfigure | — | off | re-prompt for email and persist the new answer. | | --user-id | TOKENSPEND_USER_ID | auto-generated | use a specific user_id (e.g. one from another device); persisted and reused. | | --connectors | — | claude | comma list of local sources. | | --claude-dir | — | ~/.claude | Claude store directory. | | --since / --until | — | — | ISO date window on event timestamp. | | --limit | — | — | cap records (testing). | | --state-file | — | ~/.claude/.tokenspend-backfill-state.json | dedup state. | | --no-dedup | — | off | (ingest) ignore state, re-send everything (footgun). | | --dry-run | — | off | (ingest/analyze) summarize/preview; send nothing. | | --print | — | off | (setup/analyze --install) print the settings/agent instead of writing it. | | --yes | — | off | (setup/analyze --install) skip the confirmation prompt before writing. | | --interval | — | — | (analyze) run as a loop every <dur> (1h, 30m, 90s). Omit for a single pass. | | --once | — | off | (analyze) force a single pass even with --interval. | | --max-sessions | — | 30 | (analyze) cap sessions classified per pass. | | --haiku-model | — | claude-haiku-4-5 | (analyze) model for classification. | | --analyzer-dir | — | ~/.config/tokenspendorg/analyzer | (analyze) working dir for the local claude calls; its transcripts are excluded from ingest. | | --install / --uninstall / --status | — | — | (analyze) manage the launchd background service (macOS). | | --settings-file | — | <claude-dir>/settings.json | (setup) override the settings.json to write. | | --managed-settings-file | — | OS managed path | (setup) override the managed-settings.json checked for an existing telemetry override; if it pins these vars, setup writes nothing. | | --shell | — | — | (setup) only used to locate an old shell block to clean up: bash/zsh/fish. | | --rc-file | — | — | (setup) only used to locate an old shell block to clean up. |

Identity

A cryptographically-random 128-bit id is generated on first run and persisted in ~/.config/tokenspendorg/config.json (mode 0600; respects $XDG_CONFIG_HOME). This id is used as user_id on every upload.

You can override it with --user-id <id> (or TOKENSPEND_USER_ID) — useful to reuse an id you already have on another device so both machines map to the same user (especially in anonymous mode, where there's no email to bridge them). An explicit id is remembered like the email choice. The random default stays recommended: a guessable id is guessable by anyone holding the org key.

Email is opt-in and org-gated: the CLI only prompts for an email when your org's identity_mode is "email". It asks once, offering the address detected from ~/.claude.json or git config user.email as a confirmable default; you may answer anonymous to stay anonymous. The answer is remembered in the same config file. Pass --reconfigure to re-prompt and update the stored choice.

The backend resolves a canonical user by checking email first, then the client-supplied id — so multiple machines with the same email key onto one row automatically.

Live telemetry (setup) carries this id as a custom OTEL attribute tokenspend.user_id, not the reserved user.id. Claude Code keeps its own random user.id and silently ignores any override of it, so tokenspend sends and prioritises tokenspend.user_id (the backend reads it ahead of user.id; absent → falls back to the native id). In email orgs user.email is sent too and the backend keys on that. Caveat: a machine with Claude Code managed settings that pin the OTLP endpoint elsewhere sends live telemetry there, not to tokenspend — use ingest (which is unaffected) on such hosts.

Privacy & re-run safety

  • ingest/setup: content never leaves the machine. Only model, ts, token counts, and a conversation_id are uploaded.
  • analyze is the one exception, and it's bounded. It sends your conversation text — locally redacted for secrets (API keys, tokens, private keys, emails, cards, IBANs) — only to Haiku, on your own machine, via your own Claude Code auth, to classify it. What reaches the tokenspend backend is only the resulting normalized task summaries (task name, category, success, friction) — never your raw prompts, responses, tool I/O, or file contents.
  • Email is never sent silently. It is transmitted only when your org is in identity_mode='email' and you have explicitly confirmed or provided it.
  • Safe to re-run. A local state file records which message.ids (ingest) and session ids (analyze) were already processed, so re-runs top up only new work.

Development

Near-zero runtime dependencies — Node built-ins only (fetch, node:fs, node:readline, node:crypto, node:os, node:path, node:util, node:child_process). TypeScript dev dependency only.

bun install      # dev deps (typescript, @types/node)
bun test         # run the test suite
bun run build    # tsc → dist/ (the shipped, Node-compatible artifact)
node dist/cli.js --help

The shipped artifact (dist/cli.js, #!/usr/bin/env node) runs on plain Node ≥18.