Boring Docs
CLI First — Run Your App From a Terminal
Every feature has an API route and a matching terminal command. Log a machine in, hand your agent a scoped token, and operate a local or live app with `bp`.
In this guide
CLI First
Every feature in BoringPush is reachable three ways, in this order:
- An API route that accepts a browser session or a Bearer token.
- A terminal command (
bp <thing>) that calls that route. - A page for humans who prefer clicking.
The page is last on purpose. If a feature works from the terminal, an AI agent can operate it, a script can automate it, and you can run it from a phone over SSH.
Log a machine in
bp loginThe command prints a short code and a link. Open the link in a browser where you are signed in, approve the code, and the terminal receives a token. Nothing is pasted, and the token is stored in ~/.config/boringpush/credentials.json with owner-only permissions.
Point at a live site instead of your local server:
bp login --remote https://yourdomain.com --save-remote--save-remote makes that site the default target for later commands. (If bp is not linked globally yet, run npm link once, or use npm run bp -- <command>).
Scopes
A token is read or read,write. Ask for the smallest one that does the job:
bp login --scopes readA read token can list and show. It cannot create, change, delete, or grant access. Tokens expire after 90 days.
Commands
| Command | What it does |
|---|---|
bp whoami |
Who this machine is logged in as, and their plan |
bp boards [list|show|create|rename|delete] |
Feedback boards |
bp posts [list|show|create|status|delete] |
Posts on a board |
bp products [list|show|create|set-active|delete] |
Store products |
bp orders [list|show] [--all] |
Your orders, or every order for admins |
bp jobs [list|show|counts|retry-dead|discard-dead] |
Background workers and timely jobs |
bp users [show|grant|revoke] |
Your profile; admins can grant or revoke access by email |
bp analytics [overview|funnel|revenue|live] |
Traffic and revenue |
bp billing status |
Your spending summary |
bp tokens [list|revoke] |
See and revoke tokens |
bp logout |
Forget this machine's token |
Anything that changes data needs --yes. Without it the command refuses and tells you what to type. Add --json for a machine-readable result: { ok, command, exit, data, hint }.
Give your agent a token
For an agent or a CI job, skip the credentials file and pass the token in the environment:
BP_TOKEN=bp_live_xxx bp orders list --remote https://yourdomain.com --jsonUse a read token unless the job has to write. Revoke it the moment the job is done:
bp tokens list
bp tokens revoke --id <id> --yesHow the server checks a request
Routes call one function, requireApiUser() from libs/api-auth.js:
- A Bearer token is looked up by its SHA-256 hash. The token itself is never stored.
- No token? The browser session is used instead.
apiAuthError(auth, { needAccess: true, scope: "write" })turns the result into401(nobody), or403(wrong scope, or not a paying user).
The paywall rules are identical for a browser and a token. A free user's token is exactly as limited as their login.
Add a command for your own feature
- Build the API route first and guard it with
requireApiUser(). - Copy
bin/commands/boards.mjstobin/commands/<thing>.mjs. - Export
describe,usage, andrun({ flags, sub, tail }), and call your route throughforTarget(base, token).
The CLI finds command files by name, so bp <thing> works as soon as the file exists. Then run the end-to-end test, which drives the real CLI against a throwaway database:
npm run test:e2eWhat to keep in mind
- Admin commands are admin-only on the server.
bp users grantis refused unless the token's owner is inADMIN_EMAILS. - A token is a password. Keep it out of git, logs, and chat.
BP_TOKENin a CI secret store is fine. - Rate limits apply. The login handshake and the app routes are limited per address in
config/rate-limits.js.