4.7 KiB
ninja — BlockNinja developer CLI
The ninja command: build/verify/publish CMS plugins & themes, drive the plugin
registry, and capture theme preview screenshots. Its own repo since WO-WZ-023
(remote git.dev.alexdunmow.com/block/cli); formerly lived inside cms.
Go module git.dev.alexdunmow.com/block/cli (Go 1.26). Cobra CLI. Talks to the
orchestrator over Connect-RPC; builds .bnp artifacts with block/core +
wazero; screenshots with chromedp.
Build / install / test
make build # → ./bin/ninja
make install # go install ./cmd/ninja → $GOBIN (yields `ninja` on PATH)
make test # go test ./... (compiles guest wasm fixtures: needs GOOS=wasip1 + core proxy)
make proto # regenerate the vendored orchestrator client (see below)
make safety-check # cd ../check-safety && go run . ../cli
make installmatters.ninja plugin publish/ninja plugin builduse the binary on your PATH, not the repo. After changing build/pack behaviour you MUSTmake installbefore any publish or the old binary ships. The classic failure: an installed binary that predates.bnppreview-packing silently republishes a theme without itspreview.png, wiping the live preview. Verify withninja theme screenshot --help | grep screenshots-dirand by extracting a fresh.bnp(ninja plugin verify <file.bnp>→preview=true).
Command surface
ninja plugin build | verify <f.bnp> | publish | init | status | bump [major|minor|patch]ninja plugin list | delete | delete-version | pull | version | abininja plugin tags add|rm|set|clearninja scope create|default|set|listninja account list|set|show·ninja login | whoami | logoutninja theme screenshot(preview +--pages/--screenshots-dirmulti-page capture)
.bnp artifacts
A .bnp is a zstd-compressed tar (NOT gzip — tar tzf won't read it; use
tar tf or ninja plugin verify). internal/bnp owns build+verify; wasm
plugins and codeless plugins/themes both pack into one. Optionally packs a root
preview.png and a screenshots/ dir (validated: png/jpg/jpeg/webp, ≤8MB/file,
≤12 files, no subdirs). internal/shot renders pages via chromedp for
ninja theme screenshot.
Publish builds the artifact itself. ninja plugin publish builds the .bnp
and ships it — the artifact is the ONLY publish form (the legacy source-archive
path is deleted). --bnp <file> ships a prebuilt one. Instances download the
artifact and never compile.
Orchestrator target (dev vs prod)
Global --host flag: orchestrator base URL. Default is
https://my.blockninjacms.com — PRODUCTION. For local dev always pass
--host https://my.blockninja.dev (or set it as the active host via
ninja login). Never publish dev/test plugins to the prod registry by omitting
--host.
Auth is device flow (ninja login → AuthService.StartDevice/PollDevice).
Credentials (per-host token + active account) persist to
<os.UserConfigDir>/ninja/credentials.json (Linux: ~/.config/ninja/…).
internal/creds reads/writes it; internal/orchclient builds the Connect client.
Vendored orchestrator proto (NOT a submodule)
proto/orchestrator/v1/plugin_registry.proto is a hand-vendored COPY of the
orchestrator's proto, not a git submodule. make proto regenerates
internal/api/orchestrator/v1/ from it. buf.gen.yaml runs in managed mode
and overrides go_package_prefix → git.dev.alexdunmow.com/block/cli/internal/api
so the generated Go lands in this module regardless of the proto's declared
go_package. Needs buf + protoc-gen-go + protoc-gen-connect-go on PATH.
To pick up new orchestrator RPCs (e.g. registry gallery/review methods): copy
the updated plugin_registry.proto (and any new proto) from the orchestrator's
proto into proto/, run make proto, then add client methods in
internal/orchclient. There is no automatic sync — the copy is deliberate so the
CLI pins a known server surface.
Workspace couplings
make safety-checkshells into the sibling../check-safetytool — the CLI is scanned like the other repos. Run it before publishing CLI changes.- Depends on
git.dev.alexdunmow.com/block/core(the plugin SDK) via the Gitea module proxy. Never usereplacedirectives — tag/pushcore, then bump. - The
.bnpformat + pack/validation rules are shared truth with the CMS host loader and the orchestrator registry ingestion; changing them is a cross-repo contract change.
Working in here
- Standalone repo: commit/push only within
cli/. Work onmain. - Ask before publishing anything to a registry — publish is outward-facing and hits a real orchestrator (prod by default).