Operations

Layer CLI

The layer CLI operates hevlayer from the terminal. It manages named environments, initializes adopted namespaces for sharding, observes index, pipeline, and UDF state from the gateway, mints and revokes API keys, shows VectorStore and Warehouse health, 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:

PrioritySource
1Explicit flags such as --base-url, --api-key, --context, and --kube-namespace
2LAYER_BASE_URL, LAYER_API_KEY, and the HEVLAYER_ twins
3Environment selected by --env or LAYER_ENV
4Active environment in ~/.hevlayer/config.toml
5Built-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.

FlagEnvironmentDefault
--base-urlLAYER_BASE_URL, HEVLAYER_BASE_URLhttps://aws-us-east-1.hevlayer.com
--api-keyLAYER_API_KEY, HEVLAYER_API_KEYnone
--envLAYER_ENVactive config env
-o, --outputnonetable

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.

Initialize a Namespace

layer init products --shards 8
layer init products --shards 8 --watch=false
layer init products --shards 8 --poll-interval 5s

init calls POST /v2/namespaces/{namespace}/init through the selected gateway environment. The command creates or reattaches to the namespace shard marker, starts the shard backfill, and watches by default until shard_lag_rows reaches 0 and scatter/gather is active. Re-running with the same shard count is idempotent; requesting a different shard count returns a conflict message instead of changing the marker.

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 viewCommand
Environmentslayer env ls
Functionslayer udf list
Function detaillayer udf get UDF_ID [--watch]
Indexeslayer index list
Index detaillayer index get NAME
Pipelineslayer pipeline list
Pipeline detaillayer pipeline get ID
Keyslayer keys ls
Key detaillayer 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. keys revoke is the default way to retire a key and keeps its audit record. keys rm is rare permanent cleanup and accepts only a key already in the Revoked phase.

FlagShape
--entitleTARGET[=SCOPE[+SCOPE]], repeatable. Targets are vectorstore.<name>, warehouse.<name>, or layer.
--namespacesUpstream-namespace globs for the vectorstore entitlement, comma-separated.
--claimTARGET=STRING, repeatable. Appends an opaque claim string to that target’s entitlement.
--expires-afterDuration 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.

Vector Store And Warehouse

layer vectorstore list
layer vectorstore get
layer vectorstore get prod-turbopuffer -o json
layer warehouse list
layer warehouse get prod-snowflake

vectorstore list shows declared stores with kind, default marker, region, reachability, and turbopuffer org id. vectorstore get prints endpoint, credential Secret reference, inbound auth mode, reachability, observed generation, and the turbopuffer dashboard link when the store has spec.turbopuffer.orgId. Without a name, vectorstore get selects the default-marked store, or the only store when exactly one exists.

warehouse list leads with name, kind, phase, verification time, and consumer counts. warehouse get NAME shows the Snowflake source identity, credential Secret reference, verification status, failure reason, and what still depends on the warehouse. These commands are read-only and gateway-backed; they never read or print Secret contents.

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.

Manage Snapshots

layer index snapshot shop-products --field category
layer index policy shop-products --facet-field category --facet-field brand --interval 5m --retention 30d

index snapshot creates an on-demand snapshot job and waits for it to complete. index policy writes the same facetFields, interval, and retention shape used by Index.spec.snapshot, so shared-gateway namespaces can enable the automatic writer without applying a Kubernetes resource.

Delete An Index

layer index delete shop-products
layer index delete shop-products shop-products-staging
layer index delete --prefix shop-
layer index delete --prefix shop- --yes

index delete purges the upstream turbopuffer namespace, document cache rows and snapshot mirrors, S3 snapshots/search history/clickstream/shard metadata, in-memory job state, and the operator-discovered Index CR where GC is enabled. Pass one or more names, or --prefix to delete every index whose name starts with that prefix — name arguments and --prefix are mutually exclusive, and the prefix must be non-empty.

The prefix form lists the matched indexes for confirmation before deleting; on a TTY it prompts, and --yes skips the prompt. --yes is required when stdin is not a TTY. A prefix that matches nothing exits 0 without deleting.

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.

esc