# `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](https://github.com/tj/commander.js). It ships a single
binary, `lakeshore`.

```bash
npm i -g @dreamlake/lakeshore
lakeshore --help
```

> **Warning:** 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

| Group        | Verbs                                                            | Notes                                                                                   |
| ------------ | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `providers`  | `add` `list` `show` `update` `remove` `edit` `discover` `test` `instances` `terminate` | Cloud + SSH launch targets. See [Providers + discover](/cli/examples/providers-and-discover.md). |
| `secrets`    | `add` `list` `show` `rotate` `remove`                            | Named credentials. Plaintext flows in only; `list`/`show` are metadata.                 |
| `modes`      | `add` `list` `show` `update` `remove`                            | Server-stored RunConfigs. Override flag is `--field`, not `--kwarg`.                     |
| `tunnels`    | `add` `list` `show` `remove`                                     | WireGuard (`wg-quick`) configs attached to providers.                                    |
| `mounts`     | `add` `list` `show` `update` `remove`                            | Mount declarations — metadata only, the daemon does the mounting.                        |
| `storage`    | `add` `list` `show` `update` `remove` `presign` `credentials`    | S3-compatible object storage. **Singular verb**, unlike its siblings.                    |
| `code`       | `push` `list`                                                    | Git-tree snapshots uploaded to a storage entry.                                          |
| `queues`     | `add` `ls` `show` `patch` `archive` `unarchive` `drain` `rm` `events` `stats` | **Irregular verbs**: `ls` and `rm`, not `list`/`remove`. See [Queues](/get-started/queues.md). |

### Running work

| Command / group | What it does                                                                                                        |
| --------------- | -------------------------------------------------------------------------------------------------------------------- |
| `daemon`        | Fleet management: `launch` `install` `list` `show` `setup` `exec` `kill` `cleanup` `hibernate` `reset` `update` `target-version` `set-target-version` `launch-log` `stop` `status`. |
| `exec`          | Top-level one-off bash on a daemon. Pops a picker, or takes `--queue <name>` and lets the control plane route.       |
| `run`           | Pipes a local **Python** script to a remote `python3 -` over the exec channel.                                       |
| `worker`        | `start` / `once` — supervise a native Python queue worker on **this** machine.                                       |
| `jobs`          | `list` `show` `kill` `bulk-cancel` over dispatched Invocations.                                                      |
| `up` `down` `ps` `status` `logs` | Compose verbs. They read `./lakeshore.yaml` (`-f` to override). See [Compose](/get-started/compose.md). |

> **Note:** 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 / command | What it does                                                                                     |
| --------------- | -------------------------------------------------------------------------------------------------- |
| `ssh`           | `discover` `upload` `probe` `status` over `~/.ssh/config`.                                        |
| `aws` `gcp` `slurm` `kube` `docker` | Each exposes exactly one read-only `discover` subcommand with a single `--json` flag. |
| `auth`          | `login` `status` `logout` — saves a per-namespace token at `~/.config/lakeshore/auth.yml`.        |
| `config`        | `show` `refresh` `source` — diagnostics for the resolved `.dreamrc`.                              |
| `admin`         | `tokens create` / `list` / `revoke`, `namespace create` / `list` / `delete`. Requires `LAKESHORE_ADMIN_TOKEN`. |
| `nymph`         | `push` `list` — upload a hashed nymph binary for debug-fleet OTA. Admin-authed.                   |
| `dreamlake`     | The DreamLake data plane (separate servers, separate credential store) — upload/download/list/vectorize. |
| `tui`           | Interactive terminal dashboard. Aliases `dashboard` and `top`. See [TUI dashboard](/cli/tui.md).     |
| `completion`    | `bash` / `zsh` / `fish` tab-completion. See [Completion](/cli/completion.md).                        |

> Looking for a **runnable cookbook** with one example per verb?
> [`/cli/examples`](/cli/examples.md) 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:

```text
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](/nymph/daemons.md)
for the provider path and
[Bootstrap a daemon on a remote host](/nymph/install-remote-daemon.md)
for the SSH path.

> **Note:** `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

- [Installation](/cli/installation.md) — install and authenticate.
- [CLI examples](/cli/examples.md) — the runnable cookbook, one example per verb.
- [TUI dashboard](/cli/tui.md) — `lakeshore tui` and its inline per-item actions.
- [Completion](/cli/completion.md) — tab-completion install and how it works.
- [Python SDK](/python-sdk.md) — what you can launch from the Python side.
- [Daemon launch](/nymph/daemons.md) · [Daemon lifecycle](/nymph/daemon-lifecycle.md)
- [Providers](https://docs.dreamlake.ai/lakeshore/providers) — the EC2 / GCE / SLURM / Kube / SSH launchers.
