Commands
Quick summary
Choose a command by outcome: init prepares a workspace, plan proposes changes, apply changes supported assets, and verify executes checks.
Exit code 0 means that stage completed—not that the project is fully protected. Use --json for machine-readable results.
Complete reference — every command and flag below is copied from devpay.mjs USAGE/HELP and verified by executing yp <cmd> --help.
yp init
yp init [--yes] [--force] [--name n] [--target m.mjs] [--type t] [--api-base url]Scaffolds devpay.json + .devpay/ workspace at the project root and appends .devpay/ to .gitignore.
| Flag | Meaning |
|---|---|
--yes | Non-interactive; accept detected defaults. |
--force | Overwrite an existing devpay.json. |
--name n | Project id/name. |
--type t | js | nuxt | rust | unknown. |
--target m.mjs | Module to protect (protect.target). |
--api-base url | DevPay API base stored in api.base_url. |
Detection: nuxt.config.* → nuxt, Cargo.toml → rust (analyzer handles js/wasm only — the note says so), package.json/.mjs → js. Missing protect.target is null; plan refuses until it is set — the CLI never guesses a paid boundary.
yp doctor
yp doctor [--api-base url]Environment checks: node ≥18.17, protection toolkit present, SDK present, devpay.json present, API reachability, git. Any FAIL → exit 1.
yp protect plan
yp protect plan [--target m.mjs] [--driver d.mjs] [--spec s.json]
[--overrides o.json] [--no-dynamic]2
Analyze → spec draft → ProtectionPlan. Plan-only: nothing applied.
| Flag | Meaning |
|---|---|
--target m.mjs | Paid-logic module (overrides devpay.json). |
--driver d.mjs | Dynamic-analysis driver module. |
--spec s.json | Approved spec (skips draft generation). |
--overrides o.json | Spec-draft overrides. |
--no-dynamic | Static analysis only (skip the driver trace). |
Writes .devpay/<name>.analysis.json, .devpay/spec.draft.json (when needed), and .devpay/plan.json sha-bound to spec/target/driver bytes.
yp protect review
yp protect reviewHuman-readable §6.1 plan summary — per-asset strategy, function changes, server changes, test plan, estimated server calls, unverified risks. Requires a plan to exist. Printed under a PLAN ONLY banner.
yp protect apply
yp protect apply [--approve] [--vectors v.vectors.json] [--port n]
[--auth dev-open|yp-license] [--license-seed f.json]2
Executes the plan: AUTO → partitioner, AGENT → handoff brief, MANUAL_REVIEW → skipped. Re-hashes spec/target/driver and refuses on drift (exit 2).
| Flag | Meaning |
|---|---|
--approve | Allow apply under an unapproved spec — handoffs only, never AUTO (fail closed). |
--vectors v.vectors.json | Equivalence vectors file. |
--port n | Generated partition-server loopback port (default 4930). |
--auth dev-open|yp-license | Generated-server auth mode. |
--license-seed f.json | Seed file required by yp-license mode. |
Refusals (fail-closed decisions, unapproved AUTO) exit 3.
yp protect verify
yp protect verify [--vectors v.vectors.json] [--port n] [--asset id] [--api-base url]Executes verification legs (equivalence over loopback, license/API checks) and writes schema-valid evidence records under .devpay/evidence/. --asset restricts to one spec asset id. Refuses without an apply report — verify attests applied work.
yp auth login
yp auth login [--email e] [--password p] [--api-base url]POSTs {email,password} to {api}/api/v1/auth/login and stores the credential (0600) in the yp config dir. Flag/env (YP_EMAIL/YP_PASSWORD) win; a masked TTY prompt is the fallback. --api-base is stored for later commands. Never echoes the password or issued token.
yp auth status
yp auth status [--api-base url]GET /api/v1/me with the stored credential. Prints role, seller_id, token expiry. Exit 1 when unauthenticated. (There is no /api/v1/auth/me route on either backend — the command uses /me.)
yp project list / yp project inspect
yp project list [--api-base url]
yp project inspect <project_id> [--api-base url]2
GET /api/v1/projects and GET /api/v1/projects/:id (auth required). 401/403 → exit 3 with the login hint.
yp license status / yp license verify
yp license status <license_id|key> [--api-base url]
yp license verify <key> [--api-base url]2
status— seller license record viaGET /api/v1/licenses(auth required), plus per-backend detail probesGET /licenses/:id/bindingsand/usagewhich are be-cloudflare-only and reportNOT_AVAILABLEon Axum. A key argument that is not in the seller list falls back to the public verify endpoint (source:"public-verify").verify—POST /api/v1/licenses/verify. Public — no login needed. Exit0valid,1invalid.
yp integration check
yp integration check <project_id> [--api-base url]GET /api/v1/projects/:id/integration (auth required). Statuses: CONFIGURED / EMPTY / NOT_CONFIGURED / NOT_AVAILABLE.
Backend parity note
The route is now implemented on both backends — the d3 parity port added it to be-cloudflare (be-cloudflare/src/lib.rs /api/v1/projects/:id…/integration arm). The CLI's --help text still says "Axum-only" (a stale string left from before the port); the NOT_AVAILABLE degrade path remains for backends where the route genuinely is not routed (detected via the Worker's request_id 404 fingerprint).
Endpoint coverage
| Command | Endpoint | be/ (Axum) | be-cloudflare |
|---|---|---|---|
auth login | POST /api/v1/auth/login | ✓ (no token — X-Dev-User dev auth) | ✓ (JWT) |
auth status | GET /api/v1/me | ✓ | ✓ |
project list/inspect | GET /api/v1/projects[/:id] | ✓ | ✓ |
license status | GET /api/v1/licenses | ✓ | ✓ |
| — detail probes | GET /licenses/:id/bindings, /usage | NOT_AVAILABLE | ✓ |
license verify | POST /api/v1/licenses/verify | ✓ public | ✓ public |
integration check | GET /api/v1/projects/:id/integration | ✓ | ✓ (d3 port) |
--json output
Every command prints a human summary by default and a single JSON object with --json:
yp license verify NG-AB12-CD34 --json
# {"command":"license verify","api_base":"…","valid":true,"result":{…}}2
yp-mcp consumes this exact mode — an MCP tool result is the CLI's JSON verbatim plus cli_exit_code and a receipt.