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

@rulebase/cli

v0.5.0

Published

CLI for a Rulebase workspace. Push, read, and reconcile work items with JSON in and JSON out, sign in, and check which region your credentials belong to.

Readme

rulebase

CLI for a Rulebase workspace. JSON in, JSON out — built to be driven by an agent or a CI job as much as by a person.

npx @rulebase/cli doctor                                  # which region is my key from?
npx @rulebase/cli work-items apply --file work-items.json # push a batch, get per-item results

Every work-items command is non-interactive, reads JSON from a file or stdin, writes exactly one JSON envelope to stdout, and exits with a code you can branch on. Full guide: docs.rulebase.co/guides/cli.

Why doctor exists

Rulebase runs separate US and EU deployments with separate credential stores. A valid API key sent to the wrong region returns:

{ "error": "Unauthorized" }

Which is byte-identical to what a revoked or mistyped key returns. Nothing in the response distinguishes them, so people spend hours debugging a credentials problem they do not have.

doctor does not trust the region you give it. It tries both and tells you which one answers:

  api key   rk_live_…32 chars
  region    us (requested)

  US   api rejected · mcp reachable
  EU   api authenticated · mcp reachable

  Your key belongs to EU.
  You asked for US, which rejected it. That 401 is indistinguishable
  from a bad key, so use --region eu (or RULEBASE_REGION=eu).

Commands

rulebase doctor [--region us|eu]   # which region your key belongs to, and what is reachable
rulebase login --region us|eu      # sign in to MCP through your browser (OAuth)
rulebase login --auth api-key      # configure a REST API key
rulebase logout [--region|--all]   # remove stored credentials
rulebase whoami [--region us|eu]   # which workspace your credentials belong to
rulebase skills [...]              # where to get the CX ops skills
rulebase work-items ...            # work-item CRUD and batch apply (see below)

Add --json to any of them for machine-readable output. Prompts and progress go to stderr, so rulebase login --json | jq works.

Work items

The agent-facing half of the CLI: create, read, update, soft-delete, and batch-apply work items over REST, against the canonical /v1/work_items endpoints.

rulebase work-items create --file item.json          # create-only; duplicate external_id is a conflict
rulebase work-items get <id>                         # or --external-id TASK-9182
rulebase work-items list --status completed,pending --all   # cursor paginated; --all follows every page
rulebase work-items update <id> --file patch.json    # merges custom_attributes, external_id is immutable
rulebase work-items delete <id> --yes                # soft delete; idempotent
rulebase work-items apply --file work-items.json     # create/update/restore by external_id
rulebase work-items schema                           # bundled JSON Schema for the inputs above

Input is a JSON object for the CRUD commands, and the canonical batch envelope — or a bare array, which is normalized to it — for apply:

cat > work-items.json <<'JSON'
{
  "work_items": [
    { "external_id": "TASK-9182", "agent_email": "[email protected]", "type": "fraud_review" },
    { "external_id": "TASK-9183", "type": "kyc_verification", "custom_attributes": { "risk_score": 12 } }
  ]
}
JSON

rulebase work-items apply --file work-items.json --dry-run   # plan only, writes nothing
rulebase work-items apply --file work-items.json

# stdin works everywhere a path does
jq -n '{external_id:"TASK-9182",type:"fraud_review"}' | rulebase work-items create --file -

Apply is keyed on external_id, so re-running the same input is safe: unchanged items come back as unchanged, and an external_id you previously deleted comes back as restored. Items you leave out are never deleted. Inputs are capped at 25 MB, and anything over the API's 100-item limit is split into chunks automatically — index in the output is always the position in your input.

Output and exit codes

{
  "ok": true,
  "data": { "dry_run": false, "results": [ { "index": 0, "external_id": "TASK-9182", "status": "created", "data": {} } ],
            "summary": { "total": 1, "created": 1, "updated": 0, "unchanged": 0, "restored": 0, "error": 0 } },
  "meta": { "region": "us", "chunks": 1, "chunk_size": 100 }
}

Failures use {"ok": false, "error": {"code", "message", "details"}}. Progress goes to stderr and never contains a secret, so ... | jq is always safe.

| Exit | Meaning | |---|---| | 0 | Success | | 1 | A batch apply finished with at least one failed item (error.code is partial_failure; data.results is still complete) | | 2 | Usage, malformed JSON, or input that fails schema validation — caught before any request | | 3 | Credentials: missing, ambiguous across regions, or rejected (401) | | 4 | Network failure or an API error (not_found, conflict, unprocessable, rate_limited, api_error) |

429s and transient network errors are retried with backoff, honouring Retry-After; when the CLI gives up, error.details.retry_after carries the seconds the API asked for.

Work-item commands authenticate with an API key, never OAuth — see below. A key from the wrong region returns the same 401 as a revoked one, so if unauthorized looks wrong, run rulebase doctor.

Two credentials, two jobs

| | API key | OAuth login | |---|---|---| | Authenticates as | the organization | you | | Good for | pushing data in over REST | MCP tool calls | | Names your workspace | yes | yes | | Names the authenticated user | no | yes | | Configure with | rulebase login --auth api-key | rulebase login --region us\|eu |

Keeping these straight is most of what the CLI is for. Neither one substitutes for the other, and a 401 does not tell you which one you were missing.

The API key

Configure it once and the CLI uses it automatically:

export RULEBASE_API_KEY=rk_live_...
npx @rulebase/cli login --auth api-key
unset RULEBASE_API_KEY
npx @rulebase/cli doctor             # uses the stored key

Without RULEBASE_API_KEY, login securely prompts for the key with input hidden. The key is never accepted as a command-line value because argv appears in shell history, ps output, and transcripts. The environment variable always overrides a stored key, which is useful for CI and one-off commands.

The key is verified against both regions before it is saved, so --region is optional. If supplied, a mismatch is rejected with the correct region instead of storing a key under the wrong workspace.

You only need a key to push data in. Reading a workspace over MCP needs no key at all — see rulebase-setup for connecting Claude Code, Codex or Cursor.

Signing in

npx @rulebase/cli login --region us

Opens your browser, catches the redirect on 127.0.0.1, and stores the token alongside API keys in ~/.rulebase/credentials.json with mode 0600. It refreshes on its own.

Login is per region, because the auth servers are separate (auth.rulebase.co and auth-eu.rulebase.co) and a token from one is rejected by the other. So there is no ambient "logged in", only "logged in to EU".

The token's audience is that region's MCP resource, not the REST API — so it authorises tool calls, and pushing data in still wants an API key.

Under the hood this is authorization code + PKCE (S256), with the CLI registering its own public OAuth client on first use via RFC 7591 dynamic registration. There is no client secret, which is what makes this safe to ship in a public npm package. The client id is cached per issuer so repeat logins do not create new client records.

--device selects the device-code flow, which is the right shape for a headless box. Discovery advertises the grant, but the registration endpoint currently issues clients for authorization_code and refresh_token only, so --device needs a client provisioned out of band:

RULEBASE_OAUTH_CLIENT_ID=... npx @rulebase/cli login --region us --device

For CI, skip the store entirely:

RULEBASE_TOKEN=... npx @rulebase/cli whoami --region us   # never written to disk

logout deletes both locally stored credential types for a region. It is not a server-side revocation; use --all to remove the complete local credential file.

Local credential security

Credentials stay local in ~/.rulebase/credentials.json. The directory is created with mode 0700 and the file is created and rewritten with mode 0600. API keys are only sent to Rulebase REST endpoints as Bearer tokens; production Rulebase endpoints use HTTPS. Neither API keys nor OAuth tokens are printed by the CLI.

Environment

| Variable | Purpose | |---|---| | RULEBASE_API_KEY | Override the stored REST credential; also supplies API-key login | | RULEBASE_REGION | Default region. Blank counts as unset | | RULEBASE_TOKEN | Use a token without storing one, for CI | | RULEBASE_CREDENTIALS_PATH | Move the credential file | | RULEBASE_OAUTH_CLIENT_ID | Use a specific OAuth client instead of self-registering | | RULEBASE_NO_BROWSER | Print the URL, do not launch anything | | BROWSER / RULEBASE_BROWSER | Command used to open the URL | | RULEBASE_RETRY_BASE_MS | Backoff base for retried requests, in ms (default 500) |

Development

npm run lint          # parse every shipped file and assert it survives npm pack
npm test              # subprocess tests against a mock API
npm run schema:check  # bundled work-item schemas vs the published OpenAPI
npm run check         # all three

lib/work-items/schemas.json is a copy of the public OpenAPI's work-item input schemas: it is what work-items schema prints and what the CLI validates against before sending. npm run schema:check fails if it has drifted; --write accepts the upstream shape.

Skills

Skills live in a separate package so the catalog stands on its own:

npx rulebase-skills list

License

MIT