# `lakeshore tui`

> A terminal dashboard mirroring the web UI — Workers, Queues,
> Invocations, and Storage in four tabs — where every list row
> advertises, inline, the actions you can take on it.

```bash
lakeshore tui                # opens on the Workers tab
lakeshore dashboard          # alias
lakeshore top                # alias
```

`tui` is a live, read-and-act dashboard built on
[Ink](https://github.com/vadimdemedes/ink). React and Ink are imported
lazily, so the rest of the CLI never pays the cost of loading them.

The command needs an interactive terminal and a configured control
plane, and it checks both **before** rendering anything:

- Under a pipe or in CI (stdout is not a TTY) it exits 2 with a message
  pointing you at the non-interactive equivalents — `lakeshore daemon
  list`, `lakeshore queues ls`, `lakeshore jobs list`, `lakeshore
  storage list` — instead of spewing escape codes.
- With no server configured it exits 2 telling you to run
  `lakeshore auth login --server <url>` or set `LAKESHORE_URL`.

## Flags

| Flag                   | Default   | Meaning                                                                                                        |
| ---------------------- | --------- | ---------------------------------------------------------------------------------------------------------------- |
| `--interval <seconds>` | `4`       | Live-refresh interval for the active tab. Clamped to a minimum of 1 second.                                     |
| `--tab <name>`         | `workers` | Start on a specific tab: `workers`, `queues`, `invocations`, or `storage`. An unknown value warns and falls back to `workers`. |

```bash
lakeshore tui --tab queues --interval 2
```

## The four panes

The dashboard renders a tab bar (`lakeshore · <namespace>`), the active
pane, a confirm/status line, and a footer legend. **All four tabs load
once at startup; only the active tab re-polls** on the interval.

| Tab             | Columns                                                                               |
| --------------- | ------------------------------------------------------------------------------------- |
| **Workers**     | `LABEL`, `STATE`, `RUNNERS`, `QUEUES`, `VER` (daemon version), `SEEN` (last-seen age) |
| **Queues**      | `NAME`, `KIND`, `STATE`, `MEMBERS`, `PROVIDER`, `ELASTICITY`                          |
| **Invocations** | `ID`, `STATE`, `WORKER`, `QUEUE`, `ATT` (attempt), `SUBMIT` (age)                     |
| **Storage**     | `NAME` (`<ns>/<name>`), `KIND`, `TARGET` (`s3://bucket/prefix`), `AGE`                |

Columns are fixed-width; the inline action hint for each row is
appended after the cells. `LABEL` falls back to the first 12 characters
of the `machine_id` when a worker has no label, and `VER` reads
`capabilities.versions.daemon` (shown as `—` when absent).

## Keybindings

| Key                 | Action                                                             |
| ------------------- | ------------------------------------------------------------------ |
| `Tab` / `Shift+Tab` | Next / previous tab                                                |
| `1`–`4`             | Jump to a tab by number (Workers / Queues / Invocations / Storage) |
| `↑` / `↓`           | Move the selection within the list                                 |
| `R` (capital)       | Refresh the active tab now                                         |
| _letter_            | Run the matching inline action on the **selected** row (see below) |
| `q` / `Ctrl-C`      | Quit                                                               |

Navigation deliberately uses the **arrow keys only** — the letter keys
are reserved for per-item actions, so a worker row's `[k]ill` really
does fire on `k`.

## Inline actions

Each row prints its available actions as bracketed key hints — e.g. a
live provider-backed worker shows `[k]ill [t]erminate [h]ibernate
r[e]set`, while a terminal worker shows just `[r]emove`. The hint
string and the keypress dispatch are derived from the **same** action
table, so they can't drift apart. Availability is item-aware:
`[u]narchive` only appears on an archived (or draining) queue,
`[t]erminate` only on a worker a provider backs.

**Destructive** actions open a confirm bar (`… [y/n]`) that swallows
every other key until you answer `y`, `n`, or `Esc`; non-destructive
ones run immediately. After an action the active tab re-polls and a
one-line `✓`/`✗` status reports the outcome.

### Workers

| Key | Action    | Destructive | What it does                                                                                                  |
| --- | --------- | ----------- | --------------------------------------------------------------------------------------------------------------- |
| `k` | kill      | yes         | Drops the Worker row; the cloud instance (if any) stays up.                                                    |
| `t` | terminate | yes         | Drops the row **and** terminates the cloud instance. Offered only when `providerName` is set on the worker.    |
| `h` | hibernate | no          | Hibernates the daemon for 30 minutes (`+30m`).                                                                 |
| `e` | reset     | no          | Resets poll backoff on a daemon stuck in exponential backoff.                                                  |
| `r` | remove    | yes         | Drops a **terminal** (`gone` / `terminated`) Worker row. Shown only on terminal workers.                       |

`kill` / `terminate` / `hibernate` / `reset` are offered only on
non-terminal workers; `remove` only on terminal ones.

### Queues

| Key | Action    | Destructive | What it does                                                                                                        |
| --- | --------- | ----------- | ------------------------------------------------------------------------------------------------------------------- |
| `d` | drain     | no          | Finish in-flight work, stop admitting new. `active` queues only.                                                    |
| `a` | archive   | yes         | Soft-delete; stops accepting work. Non-archived queues only.                                                        |
| `u` | unarchive | no          | Re-activate. Archived or draining queues only.                                                                      |
| `r` | remove    | yes         | Delete the queue. Cascades — drops membership from its workers when the queue has members, so the delete can't 409. |

### Invocations

| Key | Action            | Destructive | What it does                                                                                                    |
| --- | ----------------- | ----------- | --------------------------------------------------------------------------------------------------------------- |
| `k` | kill              | yes         | Kill the selected invocation. Queued → killed; a running invocation returns 409. Non-terminal invocations only. |
| `c` | cancel-all-queued | yes         | Bulk-cancel **all** queued invocations in the namespace, regardless of which row is selected.                   |

### Storage

| Key | Action | Destructive | What it does                                                           |
| --- | ------ | ----------- | ---------------------------------------------------------------------- |
| `r` | remove | yes         | Remove the storage **record** only — the S3 bucket itself is retained. |

These actions mirror the web dashboard's per-resource menus, so the
control-plane calls are identical to clicking the equivalent button in
the browser UI.

## Read next

- [`lakeshore` CLI](/cli.md) — the full command surface.
- [`nymph tui`](/nymph/status-tui.md) — a different TUI: one daemon,
  read-only, talks to the daemon's local introspection endpoint rather
  than the control plane.
- [Daemon lifecycle](/nymph/daemon-lifecycle.md) — the non-interactive
  install / list / kill / cleanup verbs.
