Skip to content

Interactive CLI commands

Your next command can have a proper UI. Forms, focus, validation, and a review step—all in a small region below the prompt.

Choosing how your app should behave? Compare full-screen and inline UIs.

Live · interactive
click & type to interact ⓘ how this demo runs

Notice how the earlier output stays above the form. Review grows the live region; finishing clears it and leaves a lasting summary.

The form blends into your terminal’s color scheme. Accents and focus highlights keep controls clear without painting a background over the whole region.

From a Fleury checkout:

Terminal window
dart run packages/samples/bin/samples.dart inline

Use Tab to move, arrow keys to choose a template, and Enter to activate a control. Escape returns from review or cancels setup. Try changing the terminal’s width while you review: the file list and configuration stack when space is tight. Scroll to inspect the full preview; the action buttons stay in view. This sample generates configuration in memory and prints a result; it writes no files.

The recording captures the native app in a real PTY. Earlier output stays in the main terminal buffer, the live region grows for review, and completion clears that region before the command prints its result.

To mix several UI steps with ordinary CLI work, see Mix UI and CLI steps: a text prompt between forms decides whether to open a fresh one, and the native command awaits runApp, reads the answer, then calls runApp again.

The form returns an InlineSetupResult and announces when its page changes. The native host owns the terminal; the browser host illustrates the same lifecycle.

await runApp(
FleuryApp(
home: ScopeBuilder<TerminalSession>(builder: (_, session) => InlineSetup(
onStepChanged: (step) => unawaited(session.resizeInline(step.rows)),
onComplete: (value) {
result = value;
exitApp();
},
)),
),
mode: const TerminalMode.inline(rows: 17, mouse: true),
enableHotReload: false,
);
print(result?.summary ?? 'Setup cancelled.');

Shared form and browser preview source · Native command source

TerminalMode.inline(rows: ...) opts into a bounded, full-width main-buffer region on macOS/Linux. Height is explicit and clamped to the terminal; widgets keep their normal layout and input behavior. Fleury restores the terminal when runApp completes, so the command can print a useful result.

Full-screen and inline guide · Minimal picker source · All showcases