← Epos

Reference

CLI reference

Every epos command and every flag it takes. This page is generated from the command definitions themselves, so it is the same text epos --help prints.

New to Epos? The quick start runs the whole round trip end to end. For the composition language epos build evaluates, see the Skillfile reference.

Environment

Epos keeps its state — the local store above all — under one root directory. The root resolves in this order, first match winning:

  1. a directory an embedding program names outright; the CLI has no flag for this
  2. $EPOS_HOME
  3. <home>/.epos, the default

Set EPOS_HOME to keep epos state somewhere other than your home directory — a throwaway directory for an experiment, or a shared cache. It must be on a local filesystem: the store's advisory locks are unreliable over NFS and SMB.

EPOS_HOME=/tmp/epos epos store path

epos store path prints the directory that resolution arrived at, which is the quickest way to see whether the variable took effect.

epos

epos [flags]

OCI-native packaging and composition for agent skills

epos packages agent skills as OCI artifacts and composes them.

State lives under ~/.epos, or under $EPOS_HOME when that is set.

-h, --help
help for epos
-v, --version
version for epos

Subcommands: epos attest, epos build, epos generate-key-pair, epos install, epos list, epos ls, epos pack, epos pull, epos push, epos registry, epos search, epos sign, epos store, epos uninstall, epos verify

epos attest

epos attest <ref> [flags]

Attest a published skill, as an OCI referrer

attest wraps a predicate document in an in-toto statement and a DSSE envelope, signs it, and attaches it to the skill's manifest as a referrer — the same layout a signature uses (SPEC.md 11).

-h, --help
help for attest
--key string
private key to sign with (default "cosign.key")
--plain-http
talk to the registry over HTTP
--predicate string
JSON predicate document
--registry-config string
registry credentials file to use instead of Docker's ($DOCKER_CONFIG/config.json, or ~/.docker/config.json)
--type string
predicate type the document conforms to (default "https://in-toto.io/attestation/custom/v0.1")

epos build

epos build <context> [flags]

Build a skill from a Skillfile into the local store

build evaluates a Skillfile against a context directory and writes one conformant artifact into the local store. Nothing executes.

Only an OCI FROM touches a registry, and it is pinned by the manifest digest the reference resolved to; with local and git bases the whole workflow is standalone.

The build is a pure function of its bases, the Skillfile and the context, so the same three inputs always produce the same digest.

--build-arg stringArray
set a build argument, as k=v; repeatable
-f, --file string
Skillfile to build (default: <context>/Skillfile)
-h, --help
help for build
--plain-http
talk to the registry of an OCI FROM over HTTP
-t, --tag string
tag as <name>:<version> (default: the name and version of the built SKILL.md)

epos generate-key-pair

epos generate-key-pair [flags]

Write a signing keypair

generate-key-pair writes cosign.key and cosign.pub. The private key is an unencrypted PKCS#8 PEM file and is yours to protect; the public key is the same PKIX PEM cosign writes.

-h, --help
help for generate-key-pair
--output-dir string
directory to write the keypair into (default ".")

epos install

epos install <ref|name:version> [flags]

Install a skill from the local store into this worktree

install renders the skill's templates with the values you supply and writes the result into .claude/skills, plus any additionalBasePaths skills.json names. The artifact carries its templates verbatim; this is where they are rendered, and nothing upstream renders anything.

The resolved digest is pinned in skills.lock.json. The store is a cache and the lock is the truth, so two worktrees can pin two different versions out of one store at the same time.

The skill must already be in the local store: install resolves, it does not fetch. Run epos pull or epos build first.

-h, --help
help for install
--set stringArray
set one value, as k=v with dots naming nested keys; repeatable
-f, --values stringArray
read values from a YAML file; repeatable, later files win

epos list

epos list [flags]

List the skills a registry holds

list reads the registry's catalog and keeps the repositories under the configured namespace. It stops there unless --versions is given: with it, each repository is asked for its versions and each version's manifest for the skill name and description.

Discovery needs GET /v2/_catalog. Registries that do not implement it cannot be enumerated at all; direct references still work.

-h, --help
help for list
--namespace string
only enumerate repositories under this namespace (default: the whole registry)
--plain-http
talk to the registry over HTTP
--registry string
registry to enumerate, as host[:port] (required)
--registry-config string
registry credentials file to use instead of Docker's ($DOCKER_CONFIG/config.json, or ~/.docker/config.json)
--versions
also resolve each repository's versions, names and descriptions

epos ls

epos ls [flags]

List the skills this worktree has pinned

ls prints what skills.lock.json pins: the skill, the version and the digest this worktree is on. It reads the lock and not the filesystem, because the lock is what the worktree actually installed.

For what the local store holds, use epos store ls.

-h, --help
help for ls

epos pack

epos pack <dir> [flags]

Pack a skill directory into the local store

pack derives the config blob from SKILL.md's frontmatter, builds the deterministic content layer, and writes the artifact into the local store. Packing the same directory twice produces the same digest.

-h, --help
help for pack
-t, --tag string
tag as <name>:<version> (default: the name and version from SKILL.md)

epos pull

epos pull <ref> [flags]

Pull a skill from a registry into the local store

pull fetches a skill and tags it in the local store. It sends Epos-Download, so a registry fronted by epos-registry records the download as verified.

A credential stored for the registry is sent; finding none is normal and the fetch is made anonymously.

-h, --help
help for pull
--plain-http
talk to the registry over HTTP
--registry-config string
registry credentials file to use instead of Docker's ($DOCKER_CONFIG/config.json, or ~/.docker/config.json)

epos push

epos push <name>:<version> <destination> [flags]

Publish a skill from the local store to a registry

push copies a skill the local store already holds to an OCI registry, byte for byte. Nothing is repacked and nothing is re-derived, so the digest `epos pack` printed is the digest that arrives.

The destination names a namespace and the skill's name is appended:

epos push reviewer:1.0.0 oci://ghcr.io/acme/agent-skills

publishes ghcr.io/acme/agent-skills/reviewer, tagged 1.0.0. An oci:// prefix is accepted and is not required. The reference push reports is the one it resolved, so a destination that already ends in the skill's own name shows the doubled segment straight away.

A credential stored for the registry is sent; a registry that permits anonymous writes needs none. Log in with `epos registry login`.

This is a direct client-to-registry copy. epos-registry serves no write path (SPEC.md 4.5) and no bytes pass through it.

-h, --help
help for push
--plain-http
talk to the registry over HTTP
--registry-config string
registry credentials file to use instead of Docker's ($DOCKER_CONFIG/config.json, or ~/.docker/config.json)

epos registry

epos registry [flags]

Log in to and out of OCI registries

registry manages the credentials epos sends to a registry.

They are read from and written to Docker's configuration and the platform's native credential helpers, so a login performed by epos, docker, oras or helm is usable by all of them. Where no native helper is configured the credential is stored in a configuration file — as base64, which is not encryption.

Epos issues no credentials of its own; these commands only hold the ones your registry gave you.

-h, --help
help for registry

Subcommands: epos registry login, epos registry logout

epos registry login

epos registry login <host> [flags]

Log in to a registry

login verifies a credential against the registry and then stores it, so a bad password fails here rather than at the next push.

The secret is read from standard input with --password-stdin, or typed at a prompt that does not echo. There is deliberately no --password flag: an argument vector is world-readable through /proc/<pid>/cmdline and lands in your shell history.

Where the platform has no credential helper configured, the credential is written to the configuration file as base64. That is Docker's format and it is not encryption; the file is created readable only by you.

-h, --help
help for login
--password-stdin
read the password or token from standard input
--plain-http
talk to the registry over HTTP
--registry-config string
registry credentials file to use instead of Docker's ($DOCKER_CONFIG/config.json, or ~/.docker/config.json)
-u, --username string
user to log in as (required)

epos registry logout

epos registry logout <host> [flags]

Log out of a registry

logout removes the stored credential for a registry. Logging out of one you are not logged in to succeeds and does nothing.

The credential is removed from wherever it was stored, which may be a native credential helper shared with docker, oras and helm.

-h, --help
help for logout
--plain-http
talk to the registry over HTTP
--registry-config string
registry credentials file to use instead of Docker's ($DOCKER_CONFIG/config.json, or ~/.docker/config.json)

epos sign

epos sign <ref> [flags]

Sign a published skill, as an OCI referrer

sign attaches a cosign signature to the skill's manifest, as a referrer whose subject is that manifest (SPEC.md 11).

The signature is written to the registry the skill lives in, which is the upstream registry rather than epos-registry: epos-registry serves no write path (SPEC.md 4.5), and a referrer can only live beside what it refers to.

-h, --help
help for sign
--key string
private key to sign with (default "cosign.key")
--plain-http
talk to the registry over HTTP
--registry-config string
registry credentials file to use instead of Docker's ($DOCKER_CONFIG/config.json, or ~/.docker/config.json)

epos store

epos store [flags]

Inspect and maintain the local artifact store

store inspects and maintains the local OCI layout epos packs, builds and pulls into.

It lives at ~/.epos/store, or at $EPOS_HOME/store when EPOS_HOME is set. Set EPOS_HOME to keep epos state somewhere other than your home directory; it must be on a local filesystem, because the store's advisory locks are unreliable over NFS and SMB.

-h, --help
help for store

Subcommands: epos store ls, epos store path, epos store prune

epos store ls

epos store ls [flags]

List the skills the local store holds

-h, --help
help for ls

epos store path

epos store path [flags]

Print where the local store lives

path prints the resolved store directory: $EPOS_HOME/store when EPOS_HOME is set, ~/.epos/store otherwise.

-h, --help
help for path

epos store prune

epos store prune [flags]

Delete blobs no tagged skill reaches

prune is mark-and-sweep from the tagged manifests. Collection is manual only, like the Go module cache, pnpm, Cargo and Bazel.

-h, --help
help for prune

epos uninstall

epos uninstall <name> [flags]

Remove an installed skill from this worktree

uninstall removes the skill from every base path it was installed into and drops it from skills.json and skills.lock.json. The store keeps its copy; use epos store prune to collect it.

-h, --help
help for uninstall

epos verify

epos verify <ref> [flags]

Verify the cosign signature attached to a skill

verify resolves the skill's manifest, lists its referrers, and checks the cosign signature over that manifest (SPEC.md 11). Attestations attached to the same manifest are verified too, and every one of them must hold.

Verification fetches the signature blob from the skill's own repository, so a registry fronted by epos-registry counts it as an unverified download of the skill. That inflation is known and deliberate: telling a signature blob from a content blob needs state, and epos-registry holds none (SPEC.md 4.4, 5.2).

-h, --help
help for verify
--key string
public key to verify against (default "cosign.pub")
--plain-http
talk to the registry over HTTP
--registry-config string
registry credentials file to use instead of Docker's ($DOCKER_CONFIG/config.json, or ~/.docker/config.json)

Publishing

epos push copies a packed or built skill from the local store to a registry. It is a direct client-to-registry copy of bytes that already exist: nothing is repacked and no digest is re-derived, so what lands upstream is what epos pack printed.

For a registry that wants a credential, run epos registry login first; epos registry logout discards it. Both use the Docker credential store, so a credential a docker login already placed there is found without being copied.

Publishing through epos-registry is a separate matter and stays withdrawn (SPEC.md 4.5): it would have to redirect the upload session to the registry behind it, and oras-go refuses a cross-host upload location. A client pointed straight at your registry gets that registry's own location and is unaffected, which is what epos push is.

What epos produces is an ordinary OCI artifact in an OCI layout, so any other OCI client publishes it too — the quick start shows oras cp reading straight out of the directory epos store path prints.