Skip to content

The TUI tour

The TUI is the keyboard-first half of RunWisp. It runs in a terminal, binds to whatever daemon is on the address you point it at (default localhost:9477), and lets you do almost everything the Web UI can — trigger tasks, follow logs, restart services, browse notifications — without leaving the shell.

Two ways to start it:

Terminal window
runwisp # spawn or attach to the local daemon, then attach the TUI
runwisp tui # attach a fresh TUI to an already-running daemon

The first form is the everyday one. The second is for SSHing in to inspect a daemon you started elsewhere — runwisp tui --host … lets you point at a remote instance.

The TUI lands on Home, with the focus already on ▸ ⮕ Open Web UI:

tui-home-default.png — TUI Home page on first start: ▸ ⮕ Open Web UI focused at top, Web UI URL row, auto-generated password row, recent activity below.

Press Enter and the TUI opens your default browser straight into the dashboard, already logged in — no copy-pasting the password, no lockouts from typos. On a server with no browser available, it prints the URL instead so you can paste it from another machine.

The other rows on Home:

  • Web UI — the daemon’s URL. Enter copies it to the clipboard.
  • Password — only shown when the daemon auto-generated the password on first run. Enter copies it.

If you set the password yourself, the password row is hidden — the TUI doesn’t have your secret in plaintext form to display:

tui-home-no-password.png — TUI Home page when the password is user-supplied: only Open Web UI and Web UI URL rows visible, no password row.

Press n while on Home to expand the notifications panel at the top — a scrollable list of in-app notifications with read-state toggling.

tui-notifications.png — TUI notifications panel expanded over the Home view, showing severity, age, and read-state toggles.

A sidebar on the left, the active view on the right, a help bar at the bottom that updates with whatever you’re focused on. The sidebar lists three navigation pages (Home / Info / Debug), followed by your tasks and services bucketed by group. The triangle marker is what’s currently showing in the right pane; the highlighted row is your cursor — move it freely, nothing changes until you press Enter.

tui-shell.png — Full TUI window: 28-column sidebar with daemon identity, Home/Info/Debug nav, grouped tasks and services; right pane Home; help bar at bottom.

The default view. Two modes:

  • Daemon overview (no task selected) — the action and field rows described above, plus a recent-activity feed across all tasks.
  • Task detail (a task or service selected from the sidebar) — schedule line, a Run Now / Restart button, and the run history for that one task.

tui-task-detail.png — TUI task detail mode: schedule line, Run Now button, recent run history for the selected task.

System metrics: CPU and memory sparklines, run-count summary, uptime. Useful for “is the daemon healthy right now” without opening a browser.

tui-info.png — TUI Info page: CPU and memory sparklines, run-count summary, uptime.

The daemon’s own log stream. When you’re attached to a remote daemon, this is also where reconnect notices show up. Scrollable in both directions.

tui-debug.png — TUI Debug page streaming the daemon's own log lines.

Enter on a row in the recent-activity list (or in a task’s run history) opens the run detail view — log streamed live from the daemon, line-numbered, with a header showing run ID, start time, duration, and either a “Run Again” button (for ended runs) or a “Stop” button (for runs that are still going).

The keybindings live in the help bar at the bottom of the screen — the TUI footer is the source of truth, so look there for whatever’s currently available.

tui-run-detail.png — TUI run detail: header with run ID, start time, duration, Run Again button; line-numbered log below.

A few keys worth flagging since they aren’t obvious:

  • fFullscreen the log. Header and line numbers go away; native terminal selection works. Right move for copy-paste.
  • dDownload the run’s full log. On a graphical session this opens your browser to the download URL; on SSH it copies the URL to your clipboard or shows it in a modal you can paste from.
  • r / s — Retry / Stop the run, depending on its current state.

The log starts in follow mode — it auto-scrolls to the tail as new lines arrive. Any manual scroll (, PgUp, g, G) pauses the follow; press G to jump back to the tail and resume.

tui-run-fullscreen.png — TUI run detail in fullscreen mode: header and gutter hidden so native terminal selection works on the raw log.

Prime directive #1 is “nothing silently fails,” so it’s worth a beat on where failures actually surface in the TUI — exit code, captured output, and end reason are first-class fields, not buried.

When you land on the run detail view for a failed run, three things tell you what went wrong without scrolling:

  • The header status badge carries the end reason — failed, timeout, crashed, stopped, skipped, or log_overflow. Each is a distinct status with a distinct colour, not a generic “error.”
  • The exit code sits in the header next to duration. Sentinel codes are real: -1 is a skipped run that never ran (on_overlap = "skip" rejected it), -2 is a crashed run the daemon was killed during. A timeout shows whatever exit the OS produced when the killed process gave up — typically 143 (SIGTERM) or 137 (SIGKILL). Any other positive code is whatever the script returned.
  • The captured log below is the raw stdout/stderr of the attempt — the same bytes the script wrote, line-numbered, with ANSI colours rendered. Press f to fullscreen it for a copy/paste.

tui-run-failed.png — TUI run detail for a failed run: red status badge, exit code in the header, captured stderr in the log pane.

The sidebar’s task entry also reflects status: a task whose last run failed shows up with a coloured marker, so a glance at the sidebar tells you which tasks need attention without opening each one.

For a task with retries, every attempt is a separate row in the run history with its own end reason — attempt 0 might be failed and attempt 1 success. Read attempt 0’s log to find out why the first try failed even when the retry recovered; that’s the bug-hunting use of keep_runs.

If a run never ran at all (skipped because of on_overlap, stopped because of on_overlap = "terminate"), the row is still there with the policy’s reason in the log and a sentinel exit code. A skipped firing is not silence — it’s a row.

Run the TUI on the daemon’s host and you’re already in. Connecting from elsewhere with runwisp tui --host …? Pass --password (same password as the Web UI) or set RUNWISP_PASSWORD in your shell. If the password is wrong or you’ve been rate-limited, the TUI prints the error and exits — see Auth for the details.

When the daemon goes away (network blip, restart, hard crash), the TUI auto-retries in the background. The Debug page shows the reconnect log; everything else freezes until the stream resumes. No manual “retry” key needed — when the daemon is back, the TUI catches up on its own.

Press q (or Ctrl+C). A two-button dialog asks “Keep the daemon running in the background?” with Keep Running and Shut Down. Esc closes the dialog without acting.

tui-quit-dialog.png — TUI quit dialog: two buttons, Keep Running and Shut Down, over the dimmed UI.

If you’re attached via runwisp tui to a daemon you didn’t spawn, Shut Down is a no-op — the TUI never stops a daemon it’s a guest of.

The TUI is a control surface, not a configuration UI. It can trigger, stop, restart, and observe — but it doesn’t:

  • Edit config. runwisp.toml is the source of truth. Open it in your editor and restart the daemon to pick up changes.
  • Set up notifications. Routes and notifiers are configured in TOML.
  • Create or delete tasks. Same reason — they live in TOML.
  • Manage users or roles. RunWisp is single-operator by design.