gsp — the GenSwarms Packages CLI
gsp is a single static Go binary with two planes:
- Offline authoring (deterministic, no network): reproducible digests,
fold/materialize overlays onto a seed, validate
swarm.state/swarm.overlayIR and package manifests. Never touches a live swarm. - Notary client: publish / resolve / verify against a swarmidx notary —
a name→digest resolver plus a signed, append-only transparency log. The notary
is not a blob host: the bytes live in your git; the notary records and
signs
name → digestmappings.
Install
Prebuilt binary from Releases,
or from source: go install github.com/genlayerlabs/genswarms-packages/cli@latest
(installs as cli; rename to gsp). Verify with gsp --help.
Talking to a notary
Set these once (the public hosted notary is https://swarmidx.ygr.ai):
export SWARMIDX_ENDPOINT=https://swarmidx.ygr.ai # or --endpoint
export SWARMIDX_TOKEN=gsp_live_… # or --token; create one in the notary UI under /tokens/
Your scope is your identity (your GitHub handle when you log in with GitHub).
Published refs look like swarmidx:<scope>/<name>@<version>.
Core workflows
Publish a package set. The manifest (swarmidx.json) lists each package's
name, kind (body | policy | handler | swarm) and dir:
gsp publish swarmidx.json --version 0.1.0 --source github://OWNER/REPO@REF
Resolve a ref to its digest and provenance:
gsp resolve swarmidx:jmlago/web-researcher@0.1.0
Verify the whole transparency log client-side (recomputes the SHA-256 hash chain and checks every Ed25519 signature — trust the math, not the server):
gsp log # prints entries and "log verified: N entries, hash chain + Ed25519 signatures OK"
Offline authoring (no network, no token):
gsp dirhash <dir> # reproducible sha256:… of a package dir
gsp materialize <seed> [overlay…] # fold overlays → materialized swarm.state
gsp verify <ir.json> # validate a swarm.state / swarm.overlay
gsp manifest <swarmidx.json> # validate a package manifest
gsp add <pkgref> --as object:NAME # author an add_object overlay (stdout or -o)
gsp bump <target> --field F --from D --to D # author a bump_package overlay
The publish model (read this before publishing — it has two non-obvious rules)
The notary is zero-trust: it does not accept your claimed digest. It
clones the --source itself and re-hashes the package dir, then signs the
name → digest into the log. Two consequences:
- The source must be reachable by the notary.
github://…is a real clone: the repo must be public (or the notary needs clone credentials). A private source fails the clone. diris relative to the source's repo root, and must also exist locally. The CLI hashes the dir locally to compare; the notary hashes the cloned dir. They must match. So the manifest'sdirpaths and your local checkout must be the repo root layout — e.g. if a package lives atexamples/packages/fooin the repo, the manifestdirisexamples/packages/foo(notpackages/foo), and you rungsp publishfrom the repo root.
If the digests disagree you get a clean digest mismatch; if the dir isn't found
in the clone you get dir … not found.
Conventions
- Versions are immutable: republishing the same
<scope>/<name>@<version>is rejected. Bump the version. kind: swarmpackages need nodeps— their dependencies are the refs in their IR, walked by the resolver.- The offline subcommands are safe to run anywhere; only publish/resolve/log reach the network.
Where to read more
README.md— install, the full command table, publishing.gsp-design-doc.md— the package model, the IR, the transparency-log design.- To develop
gspitself (add a command, touch the IR/dirhash), use thegsp-contributeskill.