DreamLake

lakeshore CLI

The operator surface for managing providers, daemons, queues, storage, and secrets from your terminal.

@dreamlake/lakeshore is an ESM Node package built on Commander. It ships a single binary, lakeshore.

bash
npm i -g @dreamlake/lakeshore
lakeshore --help
There is no `lakeshore --version`

The program never calls Commander's .version(), so lakeshore --version fails as an unknown option. Read the installed version from npm instead: npm ls -g @dreamlake/lakeshore. (Shell completion offers --version as a candidate — that is a stale entry in the generated completion tree, not a real flag.)

Global options

--dreamrc <path> is the only program-level option. It points the .dreamrc resolver at an explicit file instead of the standard lookup. Two commands redeclare it locally and fall back to the program-level value: providers test and providers instances. No other command accepts it.

Everything else is per-command. Every command and subcommand responds to --help, and Commander is configured with showHelpAfterError(), so a usage mistake prints the help for the command you got wrong.

The command surface

Resource management

GroupVerbsNotes
providersadd list show update remove edit discover test instances terminateCloud + SSH launch targets. See Providers + discover.
secretsadd list show rotate removeNamed credentials. Plaintext flows in only; list/show are metadata.
modesadd list show update removeServer-stored RunConfigs. Override flag is --field, not --kwarg.
tunnelsadd list show removeWireGuard (wg-quick) configs attached to providers.
mountsadd list show update removeMount declarations — metadata only, the daemon does the mounting.
storageadd list show update remove presign credentialsS3-compatible object storage. Singular verb, unlike its siblings.
codepush listGit-tree snapshots uploaded to a storage entry.
queuesadd ls show patch archive unarchive drain rm events statsIrregular verbs: ls and rm, not list/remove. See Queues.

Running work

Command / groupWhat it does
daemonFleet management: launch install list show setup exec kill cleanup hibernate reset update target-version set-target-version launch-log stop status.
execTop-level one-off bash on a daemon. Pops a picker, or takes --queue <name> and lets the control plane route.
runPipes a local Python script to a remote python3 - over the exec channel.
workerstart / once — supervise a native Python queue worker on this machine.
jobslist show kill bulk-cancel over dispatched Invocations.
up down ps status logsCompose verbs. They read ./lakeshore.yaml (-f to override). See Compose.
The compose verbs are top-level

There is no lakeshore compose ... command. The five verbs sit at the top level even though their source lives under src/cli/compose/.

Discovery, config, and operator tooling

Group / commandWhat it does
sshdiscover upload probe status over ~/.ssh/config.
aws gcp slurm kube dockerEach exposes exactly one read-only discover subcommand with a single --json flag.
authlogin status logout — saves a per-namespace token at ~/.config/lakeshore/auth.yml.
configshow refresh source — diagnostics for the resolved .dreamrc.
admintokens create / list / revoke, namespace create / list / delete. Requires LAKESHORE_ADMIN_TOKEN.
nymphpush list — upload a hashed nymph binary for debug-fleet OTA. Admin-authed.
dreamlakeThe DreamLake data plane (separate servers, separate credential store) — upload/download/list/vectorize.
tuiInteractive terminal dashboard. Aliases dashboard and top. See TUI dashboard.
completionbash / zsh / fish tab-completion. See Completion.

Looking for a runnable cookbook with one example per verb? /cli/examples is the flat reference — same commands, every block copy-paste-runnable once you've done the setup at the top.

How the CLI finds the control plane

Two resolution paths that do not agree, which is worth knowing before you debug an auth problem:

  • The auth commands resolve the server as --server → LAKESHORE_SERVER → the saved auth file → http://localhost:8080.
  • Every other command goes through resolveServer(), which prefers LAKESHORE_URL (with LAKESHORE_NAMESPACE, default default) and in that mode sends no bearer token at all — it deliberately bypasses the saved auth file. Without LAKESHORE_URL it falls back to the saved login, and with neither it fails outright:
server not configured — run `lakeshore auth login --server <url>` or set LAKESHORE_URL

So exporting LAKESHORE_URL is right for an open-mode local stack and wrong for a token-enforced deployment.

Short examples

Register a provider

providers add takes the name as a positional and the launcher as --launcher (one of SSH, SLURM, EC2, GCE, Kube). Names must match ^[a-z0-9][a-z0-9-]*$.

bash
# From a local AWS profile — implies --launcher EC2:
lakeshore aws discover                                  # see what's on this box
lakeshore providers add ec2-prod --from-aws-profile prod

# From a gcloud configuration — implies --launcher GCE:
lakeshore providers add gce-prod --from-gcloud-config prod

# By hand. Dotted --kwarg keys nest.
lakeshore providers add my-ec2 \
  --launcher EC2 \
  --kwarg region=us-east-1 \
  --kwarg aws_credentials.accessKeyId=AKIAEXAMPLE \
  --kwarg aws_credentials.secretAccessKey=secret-example

lakeshore providers list shows what's registered; lakeshore providers edit opens an interactive hide/unhide/delete/restore editor.

Smoke-test a provider end-to-end

providers test runs a small Python script through the provider's launch path. With no --script it uses the bundled src/cli/scripts/hello.py, which is stdlib-only on purpose (it prints hostname, Python version, platform, and whether torch sees a GPU) so it runs on a bare host.

bash
lakeshore providers test my-ec2                    # built-in hello
lakeshore providers test my-ec2 --script train.py  # your own
lakeshore providers test my-ec2 --script train.py --timeout 1200

SSH providers run directly from your machine; EC2, GCE, and Kube are server-mediated (the control plane holds the cloud SDKs). SLURM prints a stub message — that path is not wired yet.

Bring a daemon up

bash
# Provider-driven — the control plane provisions a cloud host:
lakeshore daemon launch --provider ec2-prod
lakeshore daemon launch --provider ec2-prod --count 4 --name fleet

# A host you can already SSH to (login node, on-prem box, VM):
lakeshore daemon install my-server

lakeshore daemon list shows the new rows; --watch refreshes (bare --watch means every 2 seconds). See Daemon launch for the provider path and Bootstrap a daemon on a remote host for the SSH path.

`daemon` is the fleet; `worker` is this box

lakeshore daemon ... manages nymph daemons through the control plane. To run a native Python queue worker on your own machine, use lakeshore worker start (or worker once to drain a single job and exit). There is no daemon start --local.

Run a one-off command on a daemon

exec runs a bash command on a worker and writes stdout/stderr back verbatim; the CLI exits with the remote command's exit code.

bash
lakeshore exec nvidia-smi                      # interactive picker
lakeshore daemon exec ge-debug-1 nvidia-smi    # explicit daemon

The <daemon> argument accepts a worker id, a label (set by daemon launch --name), or the host's machine_id. Add --id to skip the name lookup when a label happens to look like a worker id. If a name matches more than one daemon, the CLI prints the candidates and asks you to re-run with --id <worker-id>.

Both exec forms use Commander's passThroughOptions(): CLI flags go before the daemon argument, everything after it is the remote command, and no -- separator is used.

bash
cat input.json | lakeshore daemon exec --stdin - ge-debug-1 jq .results

lakeshore daemon exec \
  --env CUDA_VISIBLE_DEVICES=0 \
  --env BATCH=64 \
  --timeout 60 \
  ge-debug-1 python train.py

Read next