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`.

CLI First

Every feature in BoringPush is reachable three ways, in this order:

  1. An API route that accepts a browser session or a Bearer token.
  2. A terminal command (bp <thing>) that calls that route.
  3. 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 login

The 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 read

A 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 --json

Use 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> --yes

How 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 into 401 (nobody), or 403 (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

  1. Build the API route first and guard it with requireApiUser().
  2. Copy bin/commands/boards.mjs to bin/commands/<thing>.mjs.
  3. Export describe, usage, and run({ flags, sub, tail }), and call your route through forTarget(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:e2e

What to keep in mind

  • Admin commands are admin-only on the server. bp users grant is refused unless the token's owner is in ADMIN_EMAILS.
  • A token is a password. Keep it out of git, logs, and chat. BP_TOKEN in 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.