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

@reopt-ai/cli

v0.9.2

Published

Reopt CLI — manage Brandapp resources, EAV schemas, and AI tooling, with a built-in MCP server for agents.

Readme

@reopt-ai/cli

Reopt CLI — manage Brandapp resources, EAV schemas, and AI tooling.

reopt is built for both humans and agents:

  • JSON-first output — --format json is the default, perfect for CI and LLMs.
  • Pipeable — quiet, deterministic stdout; logs go to stderr.
  • Schema-as-Code — define EAV schemas in TypeScript, sync to server, generate types.
  • MCP server built-in — expose tools to Claude/Cursor/etc. with reopt mcp.

Installation

npm install -D @reopt-ai/cli @reopt-ai/brandapp-sdk

Requires Node.js ≥ 18.

Quick start

# 1. Authenticate (browser-based)
npx reopt login

# 2. Link the current project to a brandapp
npx reopt brandapp link

# 3. Define your schema, then sync
npx reopt brandapp eav sync -s ./eav.schema.ts -o ./generated/eav.ts

Schema-as-Code

// eav.schema.ts
import { defineSchema, defineEntity } from "@reopt-ai/brandapp-sdk/eav/schema";

const contacts = defineEntity({
  name: "contacts",
  description: "Contact list",
  attributes: {
    name: { dataType: "string", label: "Name", isRequired: true },
    email: {
      dataType: "email",
      label: "Email",
      isRequired: true,
      isUnique: true,
    },
    phone: { dataType: "string", label: "Phone" },
    status: {
      dataType: "select",
      label: "Status",
      options: [
        { value: "active", label: "Active" },
        { value: "inactive", label: "Inactive" },
      ] as const,
    },
  },
});

export default defineSchema({ entities: { contacts } });
npx reopt brandapp eav sync -s ./eav.schema.ts -o ./generated/eav.ts
import type { ContactsValues } from "./generated/eav";
import { ENTITY_IDS } from "./generated/eav";

const records = await eav.records.list(ENTITY_IDS.contacts);
const values = records[0].values as ContactsValues;
// values.email → string  (required)
// values.phone → string | undefined
// values.status → "active" | "inactive" | undefined

Output and global flags

| Flag | Default | Notes | | ------------------------------ | ------- | ------------------------------------------------------------------------- | | --format <type> | json | json, table, csv, yaml | | --fields <a,b> | — | Restrict output to listed columns (applies to every format, incl. NDJSON) | | --limit <n> / --offset <n> | — | Client-side window into a result list | | --page-all | off | Auto-paginate; emits NDJSON in JSON mode | | --page-limit <n> | 10 | Max pages with --page-all (a truncation warning is printed to stderr) | | --page-delay <ms> | 100 | Delay between pages with --page-all | | --env <name> | — | Named environment from .reopt.config.mjs (falls back to BRANDAPP_ENV) | | --timeout <ms> | 30000 | Per-request timeout | | --max-retries <n> | 1 | Retry budget for idempotent (GET) requests | | -q, --quiet | off | Suppress non-essential output (errors still print) | | -v, --verbose | off | Include stack traces / debug info | | --no-interactive | auto | Never prompt for missing args (default when stdin/stderr is not a TTY) |

# Default JSON, agent-friendly
$ reopt brand list
[
  { "id": "br_123", "name": "...", ... }
]

# Human view
$ reopt brand list --format table

# YAML
$ reopt brand list --format yaml

# Stream every record as NDJSON for streaming consumers
$ reopt brand list --page-all

Errors in JSON mode go to stderr as a single line:

{ "error": "auth_error", "message": "Session expired ...", "exitCode": 2 }

Authentication

Reopt CLI separates two credential types:

  • User session (~/.reopt/auth.json) — your interactive login, used by reopt login, reopt status, and registry-driven commands like reopt brand list.
  • Brandapp credentials (~/.reopt/credentials.json) — OAuth client id/secret per linked brandapp, used by reopt brandapp eav * and similar SDK-backed flows.

Both files are written with 0o600 permissions; the parent directory uses 0o700.

Sign in

$ reopt login
$ reopt login --server https://reopt.example.com
$ REOPT_CLI_SERVER=https://staging.reopt.ai reopt login

login --format json emits NDJSON events on stdout — useful for automation:

{"event":"verification_uri","url":"https://id.reopt.ai/api/cli/auth/verify?code=...","code":"..."}
{"event":"polling"}
{"event":"success","email":"[email protected]","name":"You","expiresAt":"2026-06-01T..."}

Sign out

$ reopt logout            # remove user session, leave brandapp credentials
$ reopt logout --all      # also remove every stored brandapp credential

Environment variables

| Variable | Purpose | | --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | BRANDAPP_CLIENT_ID / BRANDAPP_CLIENT_SECRET / BRANDAPP_ID | OAuth client credentials for SDK-backed commands (EAV, token, env). Highest priority. | | BRANDAPP_CLIENT_TOKEN | Short-lived service JWT (from reopt token mint). When set, brandapp requests send Authorization: Bearer instead of Basic auth. | | BRANDAPP_ENV | Default named environment from .reopt.config.mjs (overridden by --env). | | REOPT_BASE_URL | Override the API base URL used by the SDK (default https://brandapp.reopt.ai). Point this at a local dev server to target it. | | REOPT_CLI_SERVER | Override the auth/CLI server URL (default https://reopt.ai). | | REOPT_ID_SERVER | Override the derived id (auth) server URL — needed only when running apps/id directly on :3004. | | REOPT_USER_TOKEN | Use a pre-issued session token instead of running reopt login (CI/headless). Requires REOPT_CLI_SERVER or REOPT_BASE_URL to be set. | | REOPT_USER_EMAIL | Optional label for REOPT_USER_TOKEN users. | | REOPT_CREDENTIALS_FILE | Path to a JSON file containing {clientId, clientSecret, brandappId, baseUrl?}. | | REOPT_DEV_AI_PROXY_URL | Legacy alias for REOPT_BASE_URL used by reopt brandapp dev --proxy-ai. |

Resolution order for SDK credentials:

  1. BRANDAPP_CLIENT_ID + BRANDAPP_CLIENT_SECRET + BRANDAPP_ID
  2. REOPT_CREDENTIALS_FILE
  3. .reopt.json + ~/.reopt/credentials.json (set by reopt brandapp link)
  4. ~/.reopt/config.json (legacy)

Resolution order for the user session:

  1. REOPT_USER_TOKEN (+ REOPT_CLI_SERVER)
  2. ~/.reopt/auth.json (set by reopt login)

Preferences

Persist defaults in ~/.reopt/preferences.json so you don't have to set env vars or pass flags every time:

$ reopt config set server https://reopt.example.com
$ reopt config set format table          # use table view by default
$ reopt config set interactive false     # never prompt
$ reopt config list                       # show all
$ reopt config get format                 # show one
$ reopt config unset server               # remove

Resolution order for the active value: explicit flag > env var > preference > built-in default.

| Key | Type | Notes | | ------------- | ------------------------------ | ----------------------------------------------------------------------------------------------- | | server | URL | Default for reopt login and getAuthState (overridden by REOPT_CLI_SERVER and --server). | | format | json \| table \| csv \| yaml | Default for --format. | | interactive | boolean | Force interactive prompts on/off; otherwise auto-detected from TTY. |

Shell completion

# Bash — drop into ~/.bashrc:
eval "$(reopt completion bash)"

# Zsh — append to ~/.zshrc (after `compinit`):
eval "$(reopt completion zsh)"

# Fish — write the file once:
reopt completion fish > ~/.config/fish/completions/reopt.fish

The script enumerates the full command tree (including aliases like reopt ws ls, reopt ba eav up) so subcommands tab-complete after the parent.

Status and diagnostics

$ reopt status                # human-readable status table
$ reopt status --format json  # full JSON report (auth, brandapps, env overrides)
$ reopt brandapp doctor       # step-by-step ✓/✖ checks for the local setup

status --format json returns a structured report:

{
  "version": "0.6.0",
  "build": "2026-07-24T00:00:00.000Z",
  "server": { "url": "https://reopt.ai", "source": "default" },
  "auth": { "status": "ok", "email": "...", "expiresAt": "..." },
  "brandapps": [
    { "cwd": "apps/web", "brandappId": "...", "hasCredentials": true }
  ],
  "envOverrides": {
    "REOPT_BASE_URL": "https://...",
    "BRANDAPP_CLIENT_ID": true
  }
}

Commands

Brandapp setup

| Command | Purpose | | ----------------------------------- | ----------------------------------------------------------------------------------------------- | | reopt brandapp link [--dry-run] | Link the current directory to a brandapp; writes .reopt.json and ~/.reopt/credentials.json. | | reopt brandapp unlink [--dry-run] | Remove the link for this directory. | | reopt brandapp doctor | Step-by-step health check (auth, project config, server, per-entry credentials). | | reopt brandapp init [--force] | Scaffold dev-mode files into the current project. |

EAV (schema-as-code)

Two workflows: immediate sync (fast, dev) or file-based migrations (plan → migrate → verify, recommended for prod). See the reopt-eav skill for the full guide.

| Command | Purpose | | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | reopt brandapp eav sync | Apply local schema to the server and regenerate types. --dry-run, --watch, --delete-orphans, --force. | | reopt brandapp eav status | Diff local schema vs server (concise). | | reopt brandapp eav pull | Generate a local schema file from the server state. | | reopt brandapp eav diff | Render the schema diff as a markdown report (--out <file>, PR-attachable). | | reopt brandapp eav plan <name> | Scaffold a migration file (--from-diff fills the up() body + per-op risk). | | reopt brandapp eav migrate | Apply pending migrations sequentially under an advisory lock. --dry-run, --target <name>. | | reopt brandapp eav history | Show pending / applied / drift / missing-file state. | | reopt brandapp eav verify | CI-friendly checksum validation against applied migrations. | | reopt brandapp eav records list | List records. --entity <name\|id>, --filter <json>, --auth-user, --sort, --order, --select, --limit, --page. | | reopt brandapp eav records get <id> | Show one record (--entity). | | reopt brandapp eav records count | Count records matching a filter, without fetching bodies. | | reopt brandapp eav records delete-where | Delete every record matching a filter. Reports the match count and exits 7 unless --force. |

Workspace as code (RFC-0030)

Declare the reopt resources a product needs in reopt.workspace.ts and reconcile them through the platform API. Credentials come from the same --env / BRANDAPP_CLIENT_* chain as the EAV commands (scope workspace:admin).

Six resource kinds, applied in this order (references flow one way, so the order is the dependency order); creates and updates run forward, deletes run in reverse and always last:

brand → brandapp → oauth-client → eav.schema → works.pipeline → webhook

// reopt.workspace.ts
import { defineWorkspace } from "@reopt-ai/cli/workspace";

export default defineWorkspace({
  schemaVersion: 1,
  brands: {
    data: { name: "Reopt Data", domain: "data.example.com" },
  },
  brandapps: {
    "reopt-data": {
      name: "Reopt Data",
      brand: "data",
      eav: { schema: "./eav/reopt-data.schema.ts" },
    },
  },
  oauthClients: {
    "data-sdk": {
      brandapp: "reopt-data",
      scopes: ["works:read", "works:write"],
      grantTypes: ["client_credentials"],
    },
  },
  works: {
    pipelines: {
      "error-triage": {
        name: "Error triage",
        stages: [
          { key: "new", label: "New", isEntry: true },
          { key: "doing", label: "In progress" },
          { key: "done", label: "Done", outcome: "completed" },
        ],
      },
    },
  },
  webhooks: {
    "work-sync": {
      url: "https://example.com/api/webhooks/reopt",
      triggers: ["workTaskStageChanged"],
      // optional — omit and `apply` issues one for a new endpoint (shown once, `--secrets-out`)
      secret: process.env.REOPT_WEBHOOK_WORK_SYNC_SECRET,
    },
  },
});

| Command | Description | | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | reopt workspace plan [--out <file>] [--exit-code] | Read the workspace and print the plan (+ create, ~ update, - delete, ! destructive / import-required, · unchanged). Never writes. --exit-code → 6 on changes. | | reopt workspace apply [--plan <file>] [--allow-destructive] [--yes] | Apply under the server advisory lock. Exit 7 on destructive changes without --allow-destructive, 9 when --plan is stale, 10 when the lock is held, 3 when a prompt is needed but stdin is not a TTY. | | reopt workspace import <kind>/<key> <remoteId> | Bind an existing UI-created resource to a declaration key, write reopt.workspace.lock, print a stub to paste. | | reopt workspace export [--out <file>] [--all] | Write reopt.workspace.ts, the per-brandapp EAV schema files and the lock from the current server state. The migration path for a workspace built by hand. Refuses to overwrite without --force-overwrite. | | reopt workspace rotate-secret oauth-client/<key> | Issue a new client secret. Shown once — capture it with --secrets-out <file> (written 0600) or --format json. | | reopt workspace drift | CI alias for plan --exit-code. |

An absent section means "not managed"; works: { pipelines: {} } means "declared empty" and deletes code-managed pipelines. reopt.workspace.lock (per --env: reopt.workspace.<env>.lock) binds declaration keys to server ids — commit it.

Two things the tool refuses rather than guesses. Destructive changes — deleting a pipeline or stage that still holds tasks, an EAV entity that still has records, an OAuth client whose tokens are live — need --allow-destructive, and the server refuses them a second time on its own. Brands and brandapps have no delete path at all: one that leaves the declaration is reported and left alone (remove it in superadmin). A resource that exists on the server but was not created by code is reported as import-required, never overwritten — run import first.

New OAuth secrets exist only in the response that creates or rotates them. apply --secrets-out <file> and rotate-secret --secrets-out <file> write them with mode 0600; human-readable output only ever shows a mask.

Resource lookups (registry-driven)

reopt workspace list | get [id]
reopt brand list
reopt domain list
reopt post list | post-group list
reopt member list
reopt brandapp list | term list
reopt schema [resource]      # inspect available resource shapes

All registry commands honour --format, --fields, --limit, --offset, --page-all.

Customers (CRM)

reopt customer (alias cu) manages the workspace CRM with the same rules as Studio and the remote MCP — plan limits, duplicate detection, idempotency, timeline events and workflow triggers all run server-side in one shared core. Every command takes --workspace <id>.

reopt customer list     --workspace <id> [--search <text>] [--tag <t>] [--brand-id <id>] [--journey-id <id>] [--stage-id <id>]
reopt customer count    --workspace <id> [same filters]
reopt customer get      <customerId> --workspace <id> [--unmask]
reopt customer timeline <customerId> --workspace <id>
reopt customer create   --workspace <id> --name <name> [--email --phone --address --record]
                        [--tag <t>] [--attributes <json>] [--brand <idOrName>] [--journey <idOrName> --stage <idKeyOrLabel>]
                        [--note <text> | --note-file <path>] [--key <key>] [--on-conflict fail|link]
reopt customer update   <customerId> --workspace <id> [--name --email --phone --address --attributes] [--clear-email|--clear-phone|--clear-address]
reopt customer import   --workspace <id> --file <path|-> [--dry-run] [--on-conflict fail|link] [--brand --journey --stage --tag]
reopt customer brand    link|unlink <customerId> --workspace <id> --brand <idOrName>
reopt customer journey  list | set <customerId> --journey <idOrName> [--stage <idKeyOrLabel>] | remove <customerId> --journey <idOrName>
reopt customer tag      list | add <customerId> --tag <t>[,<t>] | remove <customerId> --tag <t>
reopt customer note     list <customerId> | add <customerId> --text|--file | update <noteId> --text|--file | delete <noteId>
reopt customer field    list

Rules worth knowing:

  • Lists mask email and phone (pii: "masked"). customer get --unmask returns one customer's raw contact details and is recorded in the workspace audit log.
  • "Register as a lead of a brand" is one command: create (or link to the existing customer when the email/phone is already known, with --on-conflict link) → --brand → --journey/--stage → --note, in a single transaction. Nothing is merged by name.
  • Idempotency: a customer without email or phone needs --key; otherwise the key derives from the contact. Re-sending the same key never creates a second customer, note or event (status: skipped).
  • Brand, journey and stage accept an id or an exact name (stage: id, key or label). An ambiguous name is not guessed — the result lists the candidates and the command exits 3.
  • import takes a JSON array, {"rows": [...], "defaults": {...}} or NDJSON (--file - for stdin), at most 200 rows, one transaction per row. The result lists every row as created / linked / skipped / conflict / unresolved / invalid-attributes / failed with the customer id, Studio URL and the next action; re-sending the same file only retries the rows that failed. --dry-run validates references, duplicates and plan capacity without writing — the real run validates again.
  • update changes only the fields you pass (--clear-* removes a value); tags are never touched by update — use tag add / tag remove, which keep the other tags.
  • Registering a customer or linking a brand is not a messaging consent and sends nothing.
$ reopt customer import --workspace <id> --file ./agency-leads.json --dry-run
$ reopt customer import --workspace <id> --file ./agency-leads.json
$ reopt customer create --workspace <id> --name "쇼엠" --key showm --brand "Reopt Studio" \
    --journey "영업 파이프라인" --stage lead --note-file ./showm.md
$ reopt customer tag add <customerId> --workspace <id> --tag "마케팅 에이전시"
$ reopt customer journey set <customerId> --workspace <id> --journey "영업 파이프라인" --stage won

Sandbox environments [experimental]

reopt brandapp env list
reopt brandapp env create -n <name> [--ttl 7d]
reopt brandapp env use <envId>
reopt brandapp env destroy <envId> [--force]

env create saves only a name → sandbox brandappId mapping to .reopt/env-credentials.json (mode 0o600) — it does not issue or write OAuth client credentials. Create the sandbox's OAuth client in Studio and export BRANDAPP_CLIENT_ID / BRANDAPP_CLIENT_SECRET yourself. (--ai-limit and --type are accepted for forward-compat but currently ignored by the environments API — the CLI warns when you pass them.)

Local dev server [experimental]

reopt brandapp dev [-s <schema>] [-p <port>] [--persist] [--seed <path>] [-w] [--proxy-ai]
reopt brandapp seed [-f <file>] [-t <url>] [--reset]

Service tokens (CI)

reopt token mint [--ttl 15m] [--scope eav:migrate,eav:read,eav:write] [--env <name>]

Exchanges the long-lived Basic-Auth client credentials for a short-lived HS256 JWT (default 15m, capped 1h) scoped to the active brandapp. Use it in CI so a leaked variable expires before it can do harm:

export BRANDAPP_CLIENT_TOKEN=$(reopt token mint --quiet)
# Subsequent EAV / migration commands now send Authorization: Bearer instead
# of Basic auth. `--quiet` emits the bare token on stdout; the summary goes to
# stderr. Without --quiet the token is one field of the JSON envelope.

MCP server

reopt mcp     # stdio MCP server — exposes the same tools as the CLI
              # (every tool ships a title + read-only annotations, so MCP clients
              #  can auto-approve reads instead of prompting on every call)

The stdio server advertises the registry list/get tools, the CRM customer tools (reopt_customer_* and reopt_journey_list — the same contracts as the remote MCP, served through the logged-in session), plus reopt_status, reopt_schema, reopt_brandapp_doctor, reopt_sdk_inspect, and reopt_schema_validate. The EAV entity/record, segment and feedback/proposal tools are served by the remote (web) MCP endpoint, not stdio. Write tools carry readOnlyHint: false and an explicit destructiveHint, so MCP clients can ask before overwriting or deleting.

Environments and config (.reopt.config.mjs)

Project metadata and per-environment credential routing live in a .reopt.config.mjs at the project root. Secrets never go in the file — only the names of the env vars that carry them.

// .reopt.config.mjs
import { defineConfig } from "@reopt-ai/cli/config";

export default defineConfig({
  brandapps: [{ cwd: ".", brandappId: "abc-123", brandappName: "store" }],
  environments: {
    staging: {
      clientIdEnv: "BRANDAPP_CLIENT_ID_STAGING",
      clientSecretEnv: "BRANDAPP_CLIENT_SECRET_STAGING",
      baseUrlEnv: "REOPT_BASE_URL_STAGING",
    },
  },
});

Then every EAV / token / env command accepts --env <name> (falling back to BRANDAPP_ENV) to route credentials to that environment's env vars:

reopt brandapp eav migrate --env staging

Trust model. Because .reopt.config.mjs executes JavaScript on load, the CLI records a hash of each file the first time it runs one and prompts before executing an untrusted or changed file. Set REOPT_TRUST_CONFIG=1 to trust and record non-interactively (CI / headless). The legacy .reopt.json shape still loads (without environments) and is exempt from the trust check.

Lockfile

reopt brandapp eav sync writes eav.lock next to your schema. The lockfile maps entity/attribute names to their server IDs and survives renames. Commit it. Add generated/eav.ts to .gitignore if desired.

Exit codes

| Code | Meaning | | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 0 | Success | | 1 | API / network error | | 2 | Auth error (missing/expired session, 401) | | 3 | Validation error (bad input, unknown resource; workspace apply needing a prompt with no TTY; a customer result that is a conflict, an unresolved name or a failed import row) | | 4 | Config error (missing credentials, malformed .reopt.json) | | 5 | Internal error (uncaught) | | 6 | Drift detected (eav history saw drift; workspace plan --exit-code / drift saw changes) | | 7 | Destructive blocked (eav sync / eav records delete-where without --force; workspace apply without --allow-destructive) | | 8 | Checksum mismatch (eav migrate / verify — local file ≠ applied row) | | 9 | Checksum conflict (same migration name applied with a different checksum); workspace apply --plan when the saved plan is stale | | 10 | Lock held — another eav migrate / eav sync / workspace apply runner holds the advisory lock, or the lock store is unreachable |

CI / automation

# Provide credentials non-interactively
export BRANDAPP_CLIENT_ID=...
export BRANDAPP_CLIENT_SECRET=...
export BRANDAPP_ID=...

# Sync the schema, fail the job if anything goes wrong
reopt brandapp eav sync --dry-run --format json | jq -e '.success'

For interactive tools that should never block on stdin, pass --no-interactive.

Agent plugin (skills + MCP server)

The package is an Agent Plugins 1.0.0 plugin, so an agent client that speaks the standard picks up both halves from the installed package — no manual wiring:

  • Skills (skills/) — reopt-shared (auth, global flags, exit codes), reopt-brandapp (linking, listing, health checks), and reopt-eav (schema-as-code, migrations).
  • MCP server (mcp.json) — the hosted server at https://mcp.reopt.ai, which carries the full tool set (including the EAV entity/record tools) and authenticates over OAuth.

Point your client at the installed package root (node_modules/@reopt-ai/cli); it reads plugin.json there and discovers the rest from the standard's fixed locations.

For a client that does not implement Agent Plugins, the same two pieces are still usable directly: load skill markdown from node_modules/@reopt-ai/cli/skills/, and register https://mcp.reopt.ai as a remote MCP server yourself.

The plugin deliberately ships only the hosted server. The local stdio server (reopt mcp, see MCP server) overlaps it by 10 tools and needs a separate CLI login, so bundling both would hand the client two copies of the same tools with one copy failing until you log in. Use the stdio server for work that needs your local project — reopt_schema_validate, reopt_brandapp_doctor, reopt_sdk_inspect, reopt_status — and register it manually as documented.

License

MIT