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:
- a directory an embedding program names outright; the CLI has no flag for this
$EPOS_HOME<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 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 search
epos search <query> [flags]
Search a registry's skills by name or description
search enumerates the registry the way list --versions does and filters the result on the client: the query is matched against the repository name, the skill name and the description. The OCI Distribution API has no search endpoint and epos-registry does not add one.
Discovery needs GET /v2/_catalog. Registries that do not implement it cannot be searched at all; direct references still work.
-h, --help- help for search
--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)
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.