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

@infrarates/cli

v0.3.0

Published

CLI for the Oimo public API

Readme

Oimo CLI

Requires Node.js 22.11 or newer, with no runtime dependencies. The npm package is @infrarates/cli and the command is oimo. MIT licence.

Install it from public npm (see Releases):

npm install -g @infrarates/cli          # install
npm install -g @infrarates/cli@latest   # update to the newest release
oimo --version
npm uninstall -g @infrarates/cli        # remove

From a checkout, npm install -g . in this directory or node oimo.mjs runs the unreleased code. Run npm test for its tests.

Read data with an organization API key

Create a key on the Oimo API keys page. The server accepts keys for reviewed price history, customer price/terms/status reads, providers, catalog, activity and comparisons.

export OIMO_API_KEY='your-organization-api-key'
oimo providers list
oimo prices latest --provider openai --limit 100
oimo prices history --providers openai,anthropic --all > prices.json
oimo terms latest --provider openai
oimo terms diff --provider openai --doc terms-of-use
oimo status
oimo catalog --provider openai
oimo compare resources
oimo compare prices --resource 'resource-id-from-compare-resources'

Keys always get the customer view, even if a staff session also exists. Pending rows are hidden and status responses omit internal details. Keys carry an organization identity and no user role; management and personal commands require a user session.

OIMO_API_KEY is not tied to an origin. A command that accepts a key sends it, as a Bearer header, to the origin that command targets: https://oimo.com by default, otherwise the one named by --base-url or OIMO_BASE_URL. This differs from saved sessions, which are stored per origin and never sent anywhere else. The origin must be HTTPS (HTTP only on loopback) and redirects are refused, so the key reaches the origin you named and no other. When a key is set, no session is sent with it; session commands never send the key.

A key works only in the environment that issued it, so create one per environment and set it for the command instead of exporting a production key in a shell that also targets other origins:

OIMO_API_KEY="$OIMO_DEVELOP_KEY" oimo prices latest --base-url https://oimo.dev
OIMO_API_KEY="$OIMO_DEVELOP_KEY" OIMO_BASE_URL=https://oimo.dev oimo status

Do not point --base-url or OIMO_BASE_URL at an origin you do not trust with the key in your environment.

Customer operations with a session

Run oimo login. It opens your default browser, signs you in through the website's existing WorkOS flow, and asks you to approve CLI access for the shown account. Approval starts a fresh WorkOS authorization-code exchange for the CLI; AuthKit requires a fresh sign-in (max_age=0). The new session has its own refresh token, so browser and CLI refreshes do not invalidate each other. The callback leaves the website's session and staff organization selection in place. No cookie copying is needed. The CLI validates the returned session with /v1/me before saving it.

Use --base-url https://oimo.dev to sign in against the develop deployment. For local development, start the service with [email protected] and run oimo login --base-url http://localhost:8080.

If your browser cannot be launched automatically, the terminal prints a URL. Open it on the same computer. login --no-browser prints the URL without trying to launch a browser. Login waits up to five minutes; --timeout <seconds> sets a deadline from 1 to 600 seconds. Ctrl-C or the browser's Cancel button ends it.

The handoff uses a temporary listener bound to 127.0.0.1, a random state value, and an ephemeral X25519 key. The server requires same-origin browser consent, binds the new code exchange to the approved account with a separate signed OAuth state cookie, and encrypts the new CLI session with X25519/HKDF-SHA256/AES-256-GCM. The encrypted result is POSTed to loopback, with no credentials in URLs or the terminal. The CLI checks the browser Origin, callback state, encryption tag and expiry, then closes the listener. The handshake uses no persistent server records and works across service instances.

login --session-stdin retains manual session import for scripts: it reads OIMO_SESSION or a session value from stdin. Automatic browser login always obtains a fresh session even if that environment variable is set. Manually importing a browser session shares its refresh token; use browser login to obtain independent credentials. Existing CLI sessions created before this change must log in again to gain that independence.

oimo login
oimo me
oimo organizations get
oimo organizations create --data '{"name":"My workspace"}'
oimo organizations switch --data '{"organizationId":"org_..."}'
oimo webhooks list
oimo webhooks create --data @webhook.json
oimo webhooks deliveries webhook-id
oimo webhooks test webhook-id
oimo members list
oimo members update membership-id --data '{"role":"member"}'
oimo invitations create --data '{"email":"[email protected]","role":"member"}'
oimo api-keys create --data '{"name":"My integration"}'
oimo preferences get
oimo provider-requests list
oimo logout

The CLI sends the session cookie and target Origin; existing role checks, current membership checks, tenant boundaries and last-admin protection remain in force. Admins manage people; admins and members manage integrations. Creation and rotation commands print newly issued API keys or signing secrets in their JSON responses, as the API does. JSON bodies may be inline, @file.json, or - for stdin. See the service README for request-body schemas and oimo --help for every command and its options.

Sessions are stored per origin at ~/.config/oimo/sessions.json with permissions 0600. --config <file> overrides the location. Responses that rotate or switch sessions update the saved value, and one that ends the session removes it; when a response sets the cookie twice, the last one is kept, as in a browser. Each update is applied to the file's current contents under a lock file (sessions.json.lock), so commands running at the same time, against the same or different origins, do not undo each other's rotations or logouts. The organization a staff user is viewing is saved beside the session and sent with later commands, until a switch into an organization they belong to, a new login or logout clears it. An environment session overrides the saved value and keeps nothing between commands, so a staff viewer selection does not carry over; unset it after login to use the saved session and rotations. logout removes only the selected origin's local session; it does not revoke either remote WorkOS session or unset environment credentials. Website logout ends the browser's WorkOS session and leaves an independently created CLI session usable. Revoking the CLI's WorkOS session leaves the browser session usable; revoking all sessions for the user ends both. Revocation is enforced when the affected access token expires and its next refresh fails.

Output and paging

prices history shows a readable table in an interactive terminal: provider, resource, dimension, exact price with currency, and billing unit. Each observation also shows its tier, source and recorded timestamp, plus effective dates and renames when present. Names wrap rather than being truncated; very narrow terminals use stacked observations. The header shows the pinned snapshot and providers, and a paginated result prints a command to read the next page with the same --base-url, --limit and --config.

Piping or redirecting history output defaults to JSON with all original fields. Use --format json to get JSON in the terminal, or --format table to redirect the readable display. Rates retain their decimal strings and native currencies and units, without conversions or rounding. Other commands print JSON; empty responses print null, and terms content prints the upstream text. Terms are vendor-written, so in an interactive terminal their control characters (escape sequences, BEL, bidirectional overrides) are shown escaped as \uXXXX instead of being interpreted; line breaks and tabs are kept. Piped or redirected output is the text as served. Errors go to stderr with exit code 1.

prices history reads /v1/prices/history, including older rates. By default, one page is read. JSON includes asOf, providers, prices and nextCursor. --all combines all pages in memory and prints only after every page succeeds. The cursor pins the snapshot and providers; subsequent requests send only cursor and limit. --alias takes an alias group's id or comparison name (compare aliases lists them) and reads that resource at every provider that sells it; the answer adds alias with the group's revision and members, and the cursor pins that revision. Keep asOf to reproduce a reading. Default page size is 5000, maximum 10000. Credit-denominated providers require explicit selection under the API defaults.

oimo prices history --as-of 2026-10-01T00:00:00Z --limit 100
oimo prices history --providers openai --limit 20
oimo prices history --providers openai --format json
oimo prices history --alias claude-opus-5.5 --all
oimo prices history --all > prices.json
oimo prices history --cursor 'cursor-from-previous-response'
oimo prices resource-history --provider openai --resource gpt-5
oimo prices latest --provider openai --offset 100 --limit 100 --sort price --dir asc
oimo prices history --base-url https://oimo.dev --all

prices latest uses offset paging (maximum 1000 rows per page; without --limit, an API key or a customer session gets the first 1000); it is a current reading, not a pinned export, and has no automatic paging. resource-history reads the existing per-resource /api/prices/history endpoint. Other list commands follow their existing API bounds; use --after where shown in help. Timestamps and provider names are validated by the API.

OIMO_BASE_URL sets a default origin; --base-url overrides it. Saved sessions are never sent to another origin; an environment API key goes to the selected origin (see above). HTTP is supported only on loopback for local development. Redirects are refused and each request times out after 30 seconds. Requests are not automatically retried, including mutations.

Releases

The package is @infrarates/cli on public npm, first released as 0.1.0 (OIM-511). 0.2.0 removes compare proposals list and compare proposals create: customers no longer propose alias changes, and the server no longer answers them (OIM-677). 0.3.0 changes only the sign-in timeout message: sign-up is open, so it points newcomers to Sign up instead of an invitation email (OIM-867). The @infrarates scope is the one Oimo can already publish to: its packages are maintained by Jorge's personal npm account (jtkm6), which is also the account that links the package to the publish workflow. The owner of @oimo is unconfirmed. The command stays oimo.

  • oimo --version prints the installed package's package.json version, so a release changes only that file. Versions follow semver: a removed or renamed command or option is a major bump while the version is 1.x or later (a minor one while it is 0.x).

  • install-smoke.mjs (part of npm test) packs the package, checks the tarball holds exactly package.json and the files list (which includes LICENSE), installs it globally into an empty prefix with an empty npm cache and config, runs the installed oimo from outside the repository, installs the next patch release's tarball over it (the upgrade path, e.g. 0.1.0 → 0.1.1), then uninstalls it. Release versions are plain MAJOR.MINOR.PATCH; the test refuses any other package.json version. It has passed on node:22.11.0-slim (the engines floor) and node:24-slim with only this directory copied in:

    podman run --rm -v "$PWD:/src:ro,Z" node:22.11.0-slim \
      sh -c 'cp -r /src /cli && cd /cli && npm test'
  • .github/workflows/publish-cli.yml publishes. A pull request that touches this directory runs the tests and npm publish --dry-run. To release:

    1. merge a PR that bumps version in package.json;
    2. tag that merged commit cli-v<version> and push the tag (git tag cli-v0.1.1 <sha> && git push origin cli-v0.1.1);
    3. a platform reviewer approves the run in the npm-publish environment.

    The workflow refuses a tag that does not match package.json or a commit that is not on main. It publishes with npm trusted publishing, where the job's GitHub OIDC token buys a one-time publish token, so no npm token is stored. It then installs the published version from npm on Node 22.11 and checks oimo --version. There is no provenance attestation because the repository is private.

    The package's Trusted Publisher settings on npmjs.com link it to oimo-ai/oimo, publish-cli.yml and the npm-publish environment, which is what lets that one job publish without a token. npm also requires repository.url in package.json to name oimo-ai/oimo exactly; without it the publish fails with only ENEEDAUTH.