Operations
Layer CLI
The layer CLI operates hevlayer from the terminal. It manages
named environments, observes index, pipeline, and UDF state from the gateway,
mints and revokes API keys, and runs Function manifests. Every read goes through the gateway API with an
API key; only run touches Kubernetes — it applies the Function CR, registers
the UDF spec with the gateway, triggers discovery, and optionally watches until
the queue drains. run is the only command that needs a kube context: set it
on the environment with --kube-context/--kube-namespace or per invocation
with --context/--kube-namespace.
Install
From the repository root:
go build -o layer ./apps/layer-cli
Configuration
layer reads named environments from ~/.hevlayer/config.toml.
The directory is created with mode 0700; the config file is written
with mode 0600.
active = "partner"
[envs.partner]
base_url = "https://aws-us-east-1.hevlayer.com"
api_key = "..."
kube_context = "partner-cluster"
kube_namespace = "hevlayer"
[envs.local]
base_url = "http://localhost:8080"
api_key = "dev"
kube_context = "kind-hevlayer"
Resolution order is:
| Priority | Source |
|---|---|
| 1 | Explicit flags such as --base-url, --api-key, --context, and --kube-namespace |
| 2 | LAYER_BASE_URL, LAYER_API_KEY, and the HEVLAYER_ twins |
| 3 | Environment selected by --env or LAYER_ENV |
| 4 | Active environment in ~/.hevlayer/config.toml |
| 5 | Built-in base URL default |
A shell exporting LAYER_BASE_URL or LAYER_API_KEY keeps the
env-var-only behavior and does not need a config file. --env and
LAYER_ENV select an environment for one invocation without changing
the active environment.
| Flag | Environment | Default |
|---|---|---|
--base-url | LAYER_BASE_URL, HEVLAYER_BASE_URL | https://aws-us-east-1.hevlayer.com |
--api-key | LAYER_API_KEY, HEVLAYER_API_KEY | none |
--env | LAYER_ENV | active config env |
-o, --output | none | table |
Output formats are table, json, and names.
Environments
layer env add partner --base-url https://aws-us-east-1.hevlayer.com \
--api-key "$LAYER_API_KEY" --kube-context partner-cluster \
--kube-namespace hevlayer
layer env use partner
layer env ls
layer env show partner -o json
layer env rm partner
env add prompts for missing values on a TTY. On a non-TTY, the
required values must be supplied by flags. API keys are masked in
env ls and env show.
Run A Function
layer run -f tag-products.yaml
layer run -f tag-products.yaml --index amazon-products-staging
layer run -f tag-products.yaml --detach
layer run -f tag-products.yaml --rm
The input is a Kubernetes Function manifest. --index overrides
spec.targetNamespaces with one target. --context selects a
kubeconfig context; --kube-namespace selects the Kubernetes namespace
for the Function CR. --no-apply skips the Kubernetes apply step for
workers managed outside the operator.
spec.version is registered with the gateway as the Function completion
marker version. Bump it before re-running a Function after changing a
model, prompt, taxonomy, or worker write contract.
--detach returns after registration and discovery. Without --detach,
the CLI polls UDF status until discovery has completed and
pending_count and processing_count are both zero. A drained queue
with failures exits non-zero.
--rm deletes the gateway registration and, unless --no-apply is
set, the Function CR after the queue drains cleanly. A drain with
failures leaves both in place so you can inspect them.
Watch a run from another terminal:
layer udf list
layer udf get product-tags --watch
udf list lists registered UDFs with pending, processing, failed, discovery
sweep count, and indexed rate. udf get shows those fields for one UDF;
--watch polls until pending_count and processing_count are both zero.
TUI
Bare layer on a TTY opens the read-only operations TUI (layer browse is
the explicit spelling); on a non-TTY it prints usage and exits 2. Press
i/f/p/k/e to switch between indexes, functions, pipelines, keys,
and environments from any view, enter to open a detail view, and esc/q
to back out. Every view has a non-interactive command twin with the same
data — the TUI humanizes timestamps and sizes; the commands emit raw values
for scripting.
| TUI view | Command |
|---|---|
| Environments | layer env ls |
| Functions | layer udf list |
| Function detail | layer udf get UDF_ID [--watch] |
| Indexes | layer index list |
| Index detail | layer index get NAME |
| Pipelines | layer pipeline list |
| Pipeline detail | layer pipeline get ID |
| Keys | layer keys ls |
| Key detail | layer keys get KEY_ID |
The keys views are read-only like the rest of the TUI: minting and revoking stay in the commands.
Keys
layer keys mint cohort-reader --owner acme \
--entitle vectorstore.prod-turbopuffer=read \
--namespaces "cohort-*" \
--claim warehouse.prod-snowflake="notes:cohort:*:read"
layer keys ls
layer keys get cohort-reader
layer keys revoke cohort-reader
layer keys rm cohort-reader
keys mint creates the key through the gateway and prints the token
once — alone on stdout, so layer keys mint … | pbcopy captures it;
the metadata table goes to stderr. There is no way to print it again.
| Flag | Shape |
|---|---|
--entitle | TARGET[=SCOPE[+SCOPE]], repeatable. Targets are vectorstore.<name>, warehouse.<name>, or layer. |
--namespaces | Upstream-namespace globs for the vectorstore entitlement, comma-separated. |
--claim | TARGET=STRING, repeatable. Appends an opaque claim string to that target’s entitlement. |
--expires-after | Duration or never; defaults to 365d. |
--entitle layer=admin mints an admin key. For anything longer than a
couple of flags, write the object instead: layer keys mint -f key.yaml
takes the same ApiKey manifest kubectl apply does.
keys ls and keys get show metadata only — key id, owner, phase,
entitlement targets, expiry, last seen — never tokens or hashes.
revoke is idempotent and keeps the record; rm hard-deletes it. All
keys commands call the gateway key routes, which require a key with
the layer entitlement at admin scope (or the bootstrap gateway
key); no kube access is involved.
Ask The Docs
layer ask queries the committed docs digest with the ask CLI. It is
keyless and local by default: from a checkout, it finds site/.hev-ask, prefers
a sibling ../ask source checkout, and falls back to the docs site’s installed
@hevmind/ask package or an ask binary on PATH.
layer ask tree
layer ask grep "warm cache"
layer ask cat api/query
layer ask glossary get watermark
layer -o json ask tree
Use --endpoint to query a deployed hev ask endpoint instead of the local
digest:
layer ask --endpoint https://hevlayer.com/api/ask tree
Inspect An Index
layer index get shop-products
layer index get shop-products -o json
index get reports row count, size, schema summary, last write, stable
watermark and lag, index (WAL) status, cache state, and snapshot history.
Timestamps and sizes are raw (epoch-ms, bytes); -o json carries the full
snapshot list.
Pipelines
layer pipeline list
layer pipeline get product-images
pipeline list reads registered pipelines and fans out to the
pipeline status API for each one’s
live queue depth (pending, processing, failed, rate/min); pipeline get adds target namespace, distance metric, and created-at. A pipeline with
no worker staged into it yet renders without queue counts rather than
erroring. Reads need only an API key — no kube access.
layer push is deferred to the managed build/dev-loop milestone.