Skip to content

Interactive TUI

Griffen Fargo edited this page Apr 22, 2026 · 2 revisions

Running strut with no arguments from a terminal opens an interactive picker: stack → command → env → confirm → run. Added in v0.19.0.

Invocation

strut                 # launches TUI when stdin is a tty
strut --print         # TUI that prints the resolved command instead of running it
strut --no-tui        # force non-TUI (falls through to `strut` usage)
STRUT_NO_TUI=1 strut  # permanent disable via env var

The TUI only launches when all of these are true:

  • $# is 0 (no arguments passed)
  • stdin is attached to a terminal (-t 0)
  • STRUT_NO_TUI=1 is not set
  • --no-tui is not in the arguments

That means piped input, scripts, cron jobs, and CI all keep their old behavior — strut with no args prints the usage and exits with status 1.

Backends

  • fzf — used automatically when fzf is on $PATH. Provides fuzzy filtering, scrollable list, vi-style navigation. Recommended.
  • POSIX select — fallback when fzf isn't available. Numbered menu; any shell supports it.

Force the fallback (useful in scripted tests or ergonomic preference) by setting STRUT_TUI_FORCE_SELECT=1.

What gets picked

Phase Source
Stack $CLI_ROOT/stacks/*/ (skips shared)
Command Static catalog: deploy, stop, health, status, logs, backup, drift, validate, shell, rollback
Env .<name>.env files in $CLI_ROOT, plus a (none) option

After the three picks, the TUI shows the resolved command and asks for confirmation before executing. Pick n and it exits with status 130 (standard "cancelled" convention).

--print for learning and copy-paste

$ strut --print
strut — interactive mode (pass --no-tui to disable)
> api-service
> deploy
> prod
strut api-service deploy --env prod

The command goes to stdout and the function returns 0 without executing. Handy for:

  • learning what the full command looks like before committing to it
  • wrapping the TUI in your own shell alias that adds extra flags
  • producing a shell history entry for the real command

Disabling

Set STRUT_NO_TUI=1 in your shell rc to always skip the picker. Use --no-tui for one-off invocations. If stdin isn't a tty (piped, redirected, < /dev/null), the TUI never launches — no need to opt out.

Why it's scoped this way

The command catalog is intentionally short — anything that rarely appears in a human operator's day (audit, migration wizard, notify test, etc.) is left for explicit CLI invocation. The picker should cover 90% of interactive use; the remaining 10% is better served by typing the full command or using shell history.

Clone this wiki locally