DreamLake

nymph tui

A live, read-only status monitor for one local daemon. It renders a status header and a scrolling, level-filterable event log by polling the daemon's loopback introspection endpoint.

bash
nymph tui
nymph tui --url http://127.0.0.1:9876 --interval 1

tui is the only subcommand the nymph binary has — running nymph with no subcommand runs the daemon itself.

This is a different tool from lakeshore tui: that one is a control-plane dashboard over all your workers and can act on them. nymph tui watches a single daemon on this host and is strictly read-only — it does not even install the daemon's tracing subscriber. It is the tool you run next to a daemon you are debugging.

Prerequisites

The daemon's introspection server must be on — [introspect] enabled = true in udf-daemon.toml. See Telemetry and introspection. When the daemon is unreachable the monitor renders a waiting banner and keeps retrying on the interval; it never panics.

Flags

FlagDefaultMeaning
--url <url>derived from configIntrospection base URL. When omitted, derived as http://<[introspect] bind>:<port>, falling back to http://127.0.0.1:9876.
--config <path>config precedencePath to udf-daemon.toml, used only to derive the default --url. Same precedence as the daemon; also honours LAKESHORED_CONFIG.
--interval <seconds>2.0Poll interval, clamped to a minimum of 0.1. Each tick fetches /status and /events together.

A config that fails to load is not fatal here — the TUI falls back to built-in defaults so it still launches.

Layout

Three stacked sections.

1. Status header. A connection banner plus the daemon's current state, from GET /status: run-state (colour-coded), version, queue, worker, uptime, last poll, backoff, and in-flight. The banner reads one of:

● connected
◌ waiting for daemon at <url> (retrying…)
✗ daemon unreachable at <url> — <reason> (retrying every Ns)

Status fields keep rendering from the last good snapshot even while unreachable, so a blip does not blank the context. Before the first successful poll the header reads "no status yet — the header populates on the first successful poll".

2. Events log. The stream from GET /events, one row per event as HH:MM:SS LEVEL target message, with a [+N fields — enter] hint when the selected event carries structured fields. The pane title shows the active filter, shown/capacity, and whether you are in ⏵follow or ⏸manual mode (plus ⏸ PAUSED when polling is frozen).

Filtering is applied at render time against the events already fetched, so switching levels is instant and never waits for a re-poll.

3. Footer legend. Always visible.

Keybindings

The footer prints them verbatim:

[e]rror [w]arn [i]nfo [d]ebug [t]race  [f]ollow  [space]pause  ↑/↓ scroll  [enter]expand  [q]uit
KeyAction
e / w / i / d / tSet the minimum severity shown. e = errors only; t = everything. Default i.
fToggle follow — snap to the newest event vs. stay put.
SpaceToggle pause — freeze polling and the view.
↑ / ↓ (or k / j)Scroll the event log. Any manual scroll drops follow mode; scrolling back to the bottom re-enables it.
EnterExpand / collapse the selected event's structured fields.
q / Esc / Ctrl-CQuit.

If the log looks empty, you are probably filtered above the events that exist — drop to [d]ebug or [t]race.

The terminal is restored on drop, including on panic, so a crash never leaves your shell in raw mode.

Read next

  • Telemetry and introspection — the /status and /events endpoints this monitor renders, and how to enable them.
  • lakeshore tui — the control-plane dashboard over all workers. It acts on resources; this monitor only observes one daemon.
  • Daemon lifecycle — the remote equivalents (lakeshore daemon list --watch, daemon show).