skip to content
$registry / executables

registry-cli

(alias: workers-cli)v0.2.0

Command-line tool to publish workers and kits to the iii registry (workers.iii.dev).

executable
iiiverified
106 installs29 in 7d0 today
install
$curl -fsSL https://workers.iii.dev/install/registry-cli/0.2.0.sh | sh
executablelicense: Apache-2.0clipublishregistryreleasekits
  • macOS: arm64 · x64
  • Linux: arm64 · armv7 · x64
  • Windows: arm64 · x64

exact versions are immutable; the install script pins every archive url and verifies its sha-256 before installing.

standalone executable
installed on the host by the script above (default ~/.local/bin, override with INSTALL_DIR); not a worker, so it cannot be added to a compose graph.
agent-ready brief for v0.2.0
install + config + dependencies + readme + skills + api reference, all in one place. fetch as agent-context.md for an llm to consume.
the same content rendered as discrete blocks below is exposed as a single markdown document at /executables/registry-cli.md?version=0.2.0. paste it into an llm prompt or pipe it through curl from a worker.

install

install
$iii trigger compose::add worker=registry-cli@0.2.0

dependencies

no dependencies for v0.2.0

readme

README.md

workers-cli

workers is the command-line tool for publishing workers to the iii worker registry. Point it at a worker project and it uploads your pre-built artifacts, registers a new immutable version with its README, metadata and skills, and makes it installable by anyone running iii.

workers login
workers publish --hosting registry --artifacts ./dist --skills ./skills

Install

curl -fsSL https://workers.iii.dev/install/workers-cli/latest.sh | sh

The installer detects your OS and CPU architecture, downloads the matching archive, verifies its SHA-256 checksum and places the workers binary in ~/.local/bin. If that directory is not on your PATH, it tells you how to add it.

  • Custom location: set INSTALL_DIR, e.g. curl -fsSL … | INSTALL_DIR="$HOME/bin" sh.
  • Pin a version: replace latest with a release tag (next) or an exact version, e.g. https://workers.iii.dev/install/workers-cli/0.1.0.sh.

Supported platforms:

OS Targets
macOS aarch64-apple-darwin (Apple Silicon), x86_64-apple-darwin (Intel)
Linux x86_64-unknown-linux-musl (static, any distribution), x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu, armv7-unknown-linux-gnueabihf
Windows x86_64-pc-windows-msvc, aarch64-pc-windows-msvc (run the installer from Git Bash, MSYS2 or Cygwin)

Check the installation with workers --version. Run workers --help or workers publish --help for the built-in reference.

Build from source

With a stable Rust toolchain, from the CLI's source directory:

cargo install --path .    # installs `workers` into ~/.cargo/bin

How it works

The registry does not store your files: it stores where they live and their SHA-256 digests. Every workers publish run goes through the same steps:

  1. Reads your project. iii.worker.yaml provides the worker's name, type and metadata; README.md becomes the worker's page; the version comes from --version or from your language manifest.
  2. Collects the artifacts and computes the SHA-256 and size of each one locally, before anything leaves your machine.
  3. Uploads the artifacts to the host chosen with --hosting: the registry's own CDN or a GitHub release in your repository.
  4. Publishes the version. The registry records the name, version, release tag, README, metadata and, for each artifact, its URL and digest.
  5. Attaches your skills (optional): Markdown documentation for that version, sent right after the version is published.

Once published, the worker appears on workers.iii.dev and anyone can add it to their project:

iii trigger compose::add worker=<name>

Versions are immutable. Re-running a publish is always safe: if the version already exists with identical artifacts, the run is a no-op (already published with identical contents); if the artifacts differ, the CLI stops and asks you to bump the version. A CI job that failed halfway can simply be retried.

Authenticate

workers login

Prompts for your registry API key (input is hidden) and saves it to ~/.iii/workers-api-key (%USERPROFILE%\.iii\workers-api-key on Windows), with 0600 permissions on macOS and Linux.

In CI, skip login and set WORKERS_API_KEY instead; it takes precedence over the saved key. The key is only needed to talk to the registry, so --dry-run works without it.

Prepare your worker

A typical project looks like this:

my-worker/
├── iii.worker.yaml     # worker manifest
├── Cargo.toml          # or package.json / pyproject.toml, provides the version
├── README.md           # shown on the worker's registry page
├── skills/             # optional Markdown skills
│   └── SKILL.md
└── dist/               # pre-built artifacts

iii.worker.yaml

iii: v1
name: bridge                 # worker name on the registry
language: rust
deploy: binary               # binary | bundle | executable
manifest: Cargo.toml         # file the version is read from
bin: bridge                  # artifact file name prefix (defaults to `name`)
description: Bridge two engines.
license: Apache-2.0
repo: https://github.com/acme/bridge
tags: [bridge, remote]
experimental: false
config:                      # default configuration, shown on the worker's page
  url: ws://0.0.0.0:49134
dependencies:                # other workers, by semver range or release tag
  configuration: "latest"
Field Required Description
name yes The worker's name on the registry.
deploy yes binary, bundle or executable; see Artifacts.
manifest no Language manifest, next to iii.worker.yaml, that holds the version: Cargo.toml, package.json or pyproject.toml.
bin no Prefix of the binary artifact file names. Defaults to name.
repo no Link to the source repository. When omitted, it is derived from --github-repo if given.
tags no Search tags. When omitted, the tags already set on the registry are kept.
description, license, config, dependencies, experimental no Sent to the registry as-is.

Version

The version is resolved in this order:

  1. --version X.Y.Z;
  2. the file named by manifest:: the version field of a JSON file (package.json), or [package].version / [project].version of a TOML file (Cargo.toml, pyproject.toml).

If neither is available, publish stops and asks for --version.

Artifacts

--artifacts is required, and what it points to depends on deploy:

deploy --artifacts points to What gets published
binary a folder One archive per platform, named -.tar.gz (or .zip, typically for Windows). Files that don't follow this pattern are ignored.
bundle a .tar.gz file A single archive for every platform, e.g. a Node.js or Python worker.
executable a folder Same rules as binary. For standalone programs, like this CLI, that users install with curl -fsSL https://workers.iii.dev/install//latest.sh | sh instead of adding them to a project.

Example dist/ folder for a binary worker named bridge:

dist/
├── bridge-aarch64-apple-darwin.tar.gz
├── bridge-x86_64-apple-darwin.tar.gz
├── bridge-x86_64-unknown-linux-gnu.tar.gz
└── bridge-x86_64-pc-windows-msvc.zip

Skills

--skills points to a folder of Markdown files, read recursively (empty files are skipped). SKILL.md at the root is the overview; every other file keeps its relative path under skills/:

Local file Published as
skills/SKILL.md SKILL.md
skills/guides/setup.md skills/guides/setup.md

Publish

Choose where the artifacts are hosted

Registry hosting (--hosting registry)

workers publish --hosting registry --artifacts ./dist --skills ./skills

The files are uploaded straight to the registry and served from https://cdn.iii.cloud/workers///. Only your API key is needed.

  • The CLI opens a release for the version, uploads each artifact to a short-lived signed URL and then publishes. Transient upload failures are retried automatically, and an interrupted run resumes the same release the next time.
  • Nothing becomes public until the publish succeeds: the registry first checks the presence, size and digest of every upload.
  • Binary archives keep their - names; a bundle is always published as -.tar.gz, whatever its local file name.
  • --github-repo is optional here; when given, it only fills the repo link if iii.worker.yaml has none.

GitHub hosting (--hosting github, the default)

export GITHUB_TOKEN=...   # token with `contents: write` on the repository
workers publish --artifacts ./dist --github-repo owner/repo

The CLI uploads the artifacts to the GitHub release v of --github-repo (creating it if missing), then registers the version with URLs that point at those release assets. It needs GITHUB_TOKEN or GH_TOKEN.

  • An asset already on the release with the same digest is skipped; one with the same name but different content is an error.
  • GitHub Enterprise is supported through GITHUB_SERVER_URL and GITHUB_API_URL.

Release tags

By default, a version is published under the latest tag: it is stable, installed by default and matched by semver ranges such as ^1.0.0. Any other tag (next, beta, rc, …) publishes a candidate, which is only installed when requested explicitly by tag or exact version; semver ranges ignore it.

workers publish --hosting registry --artifacts ./dist --tag next

# users opt in explicitly:
iii trigger compose::add worker=my-worker@next

Preview with --dry-run

--dry-run prints the worker, version, hosting target, every artifact with its digest and size, and the exact JSON payload that would be sent, without uploading or publishing anything and without an API key. Use it to check the manifest, the version and the artifact names before spending a version number.

workers publish --hosting registry --artifacts ./dist --dry-run

Flags

Flag Env Default Description
--manifest iii.worker.yaml Worker manifest.
--readme README.md Markdown shown on the worker's page. Must exist.
--skills Folder of Markdown skills.
--artifacts required Folder (binary, executable) or .tar.gz file (bundle).
--hosting WORKERS_HOSTING github Where the artifacts are hosted.
--github-repo GITHUB_REPOSITORY Repository whose v release hosts the artifacts. Required with --hosting github.
--version read from manifest: Version to publish.
--tag latest Release tag. Anything other than latest publishes a candidate.
--registry WORKERS_REGISTRY_URL https://api.workers.iii.dev Registry API base URL.
--dry-run Print the payload; upload and publish nothing.

GitHub Actions

GitHub Actions sets GITHUB_REPOSITORY for you, so --github-repo can be omitted:

- name: Publish to the iii registry
  env:
    WORKERS_API_KEY: ${{ secrets.WORKERS_API_KEY }}
    GITHUB_TOKEN: ${{ github.token }}   # only needed for --hosting github
  run: |
    curl -fsSL https://workers.iii.dev/install/workers-cli/latest.sh | sh
    ~/.local/bin/workers publish --artifacts dist --skills skills

With GitHub hosting, the job also needs permissions: contents: write to create the release and upload its assets.

Troubleshooting

Message Fix
no API key: run `workers login` or set WORKERS_API_KEY Run workers login or export WORKERS_API_KEY.
--hosting github needs --github-repo (or GITHUB_REPOSITORY) Pass --github-repo owner/repo, or use --hosting registry.
set GITHUB_TOKEN (or GH_TOKEN) to upload artifacts to the GitHub release Export a token with contents: write on the repository.
no `-.tar.gz|.zip` files in The files in --artifacts don't follow the naming pattern, or bin: doesn't match their prefix.
bundle workers need --artifacts to be the .tar.gz archive With deploy: bundle, point --artifacts at the archive, not at a folder.
deploy `x` is not supported (only binary, bundle and executable) Fix deploy: in iii.worker.yaml.
iii.worker.yaml has no `manifest:` to read the version from; pass --version Add manifest: to iii.worker.yaml or pass --version.
no string `version` in ; pass --version Add a version to your language manifest or pass --version.
… is already published with different contents; bump the version instead of overwriting Versions are immutable: bump the version and publish again.
release vX already has a different ; bump the version instead of overwriting Same as above, with GitHub hosting.

License

Apache-2.0

api reference (json)

no api surface registered for this version