diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..b4b2056 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,94 @@ +# `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 + +```bash +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 install` matters.** `ninja plugin publish` / `ninja plugin build` use +> the binary on your PATH, not the repo. After changing build/pack behaviour you +> MUST `make install` before any publish or the old binary ships. The classic +> failure: an installed binary that predates `.bnp` preview-packing silently +> republishes a theme **without** its `preview.png`, wiping the live preview. +> Verify with `ninja theme screenshot --help | grep screenshots-dir` and by +> extracting a fresh `.bnp` (`ninja plugin verify ` → `preview=true`). + +## Command surface + +- `ninja plugin build | verify | publish | init | status | bump [major|minor|patch]` +- `ninja plugin list | delete | delete-version | pull | version | abi` +- `ninja plugin tags add|rm|set|clear` +- `ninja scope create|default|set|list` +- `ninja account list|set|show` · `ninja login | whoami | logout` +- `ninja theme screenshot` (preview + `--pages`/`--screenshots-dir` multi-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 ` 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.localdev.blockninjacms.com` (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 +`/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-check` shells into the sibling `../check-safety` tool — 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** use `replace` directives — tag/push `core`, then bump. +- The `.bnp` format + 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 on `main`. +- Ask before publishing anything to a registry — publish is outward-facing and + hits a real orchestrator (prod by default).