# Shell completion

`lakeshore completion <shell>` prints a sourceable completion script.
`bash`, `zsh`, and `fish` are accepted (case-insensitively); anything
else exits 2.

## Install

Pick your shell and drop the eval into your rc file once:

```bash
# bash
echo 'eval "$(lakeshore completion bash)"' >> ~/.bashrc

# zsh
echo 'eval "$(lakeshore completion zsh)"'  >> ~/.zshrc

# fish
lakeshore completion fish | source                                       # this shell only
lakeshore completion fish > ~/.config/fish/completions/lakeshore.fish    # persistent
```

Restart the shell (or `source` the rc file).

## What the tree covers

The completion script is **generated from a hand-maintained table**, not
introspected from Commander at runtime. Today that table covers these
top-level groups:

```text
providers  secrets  modes  auth  config  daemon  worker
jobs  tunnels  mounts  ssh  aws  gcp  slurm  kube  docker  completion
```

> **Warning:** Groups that exist on the CLI but are **missing** from the completion
> tree: `storage`, `code`, `queues`, `exec`, `run`, `dreamlake`, `nymph`,
> `admin`, `tui`, and the compose verbs `up` / `down` / `ps` / `status` /
> `logs`. They work fine when typed in full — they just do not tab-expand.
> 
> The tree also contains two entries you should ignore: `--version`,
> which is not a real flag on this program, and `daemon ota`, which is a
> hidden back-compat alias for `daemon update`.

Subcommands that do complete, per group:

```text
lakeshore providers   → test instances add list show remove update terminate edit discover
lakeshore secrets     → add list show rotate remove
lakeshore modes       → add list show remove update
lakeshore auth        → login status logout
lakeshore config      → show refresh source
lakeshore daemon      → stop status list show launch install kill cleanup
                             hibernate ota target-version set-target-version
lakeshore worker      → start once
lakeshore jobs        → list show kill
lakeshore tunnels     → add list show remove
lakeshore mounts      → add list show remove update
lakeshore ssh         → discover upload probe status
lakeshore aws|gcp|slurm|kube|docker   → discover
lakeshore completion  → bash zsh fish
```

Long flag names complete per (group, subcommand) pair — only long
flags, since short-flag completion is noise.

## Dynamic values

Some argument and flag positions complete against real names:

```text
lakeshore providers show                        → live provider names
lakeshore secrets rotate                        → live secret names
lakeshore modes update                          → live mode names
lakeshore tunnels remove                        → live tunnel names
lakeshore mounts show                           → live mount names
lakeshore daemon show|kill|hibernate            → live worker ids
lakeshore jobs show|kill                        → live invocation ids
lakeshore daemon install                        → SSH aliases from ~/.ssh/config
lakeshore ssh upload|probe                      → SSH aliases from ~/.ssh/config
lakeshore providers add --from-aws-profile      → AWS profile names
lakeshore providers add --from-gcloud-config    → gcloud configurations
lakeshore providers update foo --tunnel         → live tunnel names
lakeshore jobs list --state                     → queued running succeeded failed killed timeout
```

The generated scripts get these by shelling out to a hidden subcommand:

```bash
lakeshore completion __suggest <kind>
```

`__suggest` is an implementation detail, not a user-facing command.
Valid kinds are `providers`, `secrets`, `modes`, `tunnels`, `mounts`,
`daemons`, `invocations`, `ssh-aliases`, `aws-profiles`,
`gcloud-configs`, `kube-contexts`, `docker-contexts`, and `job-states`.

Server-backed kinds do one `GET` against the control plane and cache
the result for **30 seconds** at
`$XDG_CACHE_HOME/lakeshore/completion-<kind>.txt`, one name per line,
so repeated tabs don't hammer the server. The invocations list is
capped at 50 entries.

Local kinds (`ssh-aliases`, `aws-profiles`, `gcloud-configs`,
`kube-contexts`, `docker-contexts`) skip the cache and read your config
files directly. `job-states` is a hardcoded static list.

If the control plane is unreachable or auth isn't set up, the
suggestion path returns nothing and tab simply does nothing — your
shell stays responsive.

## Forcing a cache refresh

The 30-second window is usually invisible. If you just registered a
provider and want it to tab-complete right now:

```bash
rm -f "${XDG_CACHE_HOME:-$HOME/.cache}/lakeshore/completion-providers.txt"
```

…or wait 30 seconds.

## Extending it

The subcommand tree, the per-command flag lists, and the
argument→suggestion mapping all live in `src/cli/completion/index.ts` in
the `lakeshore` repo. The shell scripts are generated from those
tables, so a new subcommand or flag has to be added there before it
tab-completes.

## Read next

- [`lakeshore` CLI](/cli.md) — the full command surface, including the
  groups the completion tree doesn't yet know about.
- [CLI examples](/cli/examples.md) — the runnable cookbook.
