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.
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.
Run it in your terminal
Section titled “Run it in your terminal”From a Fleury checkout:
dart run packages/samples/bin/samples.dart inlineUse 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.
One form. A small host boundary.
Section titled “One form. A small host boundary.”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.');SizedBox( height: step.rows, child: InlineSetup( onStepChanged: (value) => setState(() => step = value), onComplete: (value) => setState(() { result = value; finished = true; }), ),)The browser replaces the completed form with its result and an illustrated prompt. It uses Fleury’s browser renderer, not a native terminal session.
Shared form and browser preview source · Native command source
Start small
Section titled “Start small”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