Publishing

How to publish, what a version means, and what you can change afterwards.

Getting an account

Sign in with GitHub or Google and choose a username. That username is your scope: everything you publish lands under you/<name>, and nothing can publish under a scope you do not own — the API takes the scope from the token's owner rather than from the request, so it is not a field you can set.

From the web

Publish a package walks through it. You need a name, a semver version, a one-line description, and the file. Fill in permissions too: it costs a minute and it is what turns a future upgrade into a check instead of a hope.

From a script

Mint a token with the publish scope under API tokens, then:

curl -X POST https://senclaw.bacnd.com/api/v1/publish \
  -H "Authorization: Bearer $SENCLAW_TOKEN" \
  -F kind=skill \
  -F name=my-skill \
  -F version=1.0.0 \
  -F 'description=Does the thing' \
  -F file=@my-skill.tgz

Every form part is listed in the HTTP API reference. Tokens are stored hashed — the value is shown once, at creation, and cannot be recovered.

Versions are permanent

A published name@version is permanent. It can be deprecated, and it can be yanked, but it can never be replaced with different bytes. If it could, pinning a version would mean nothing.

Versions must be valid semver. Upstream plugin manifests elsewhere treat version as optional and fall back to a commit SHA; SenClaw does not, because without an ordered immutable version you cannot pin, yank, diff or attest.

What you can change afterwards

ActionEffectReversible
DeprecateA warning on the package page and in the API documentyes
Yank a versionExcluded from range resolution; exact pins still resolveyes
Change visibilitypublic, unlisted, or private with an access listyes
Remove the packageHidden everywhere; version numbers stay burnedno

Removal is not a row delete. The rows stay so that name@1.0.0 can never come back meaning different bytes — freeing the number would be handing the next publisher a way to impersonate an old release.

Visibility

  • public — listed, in search, in the API, in marketplace.json.
  • unlisted — hidden from browse, reachable by anyone with the URL.
  • private — gated by an access list of emails. Invisible to everyone else,

including to the API, which reports it as not found. Manage the list under your packages.