Skip to main content

Panel-based terminal forms for PHP

A dependency-light PHP engine for building panel-based terminal forms: interactive, keyboard-driven questionnaires that collect answers and hand them to your code. Describe the questions in PHP with a fluent builder, add a handler class wherever a question needs real behaviour, and the engine renders a scrollable, themeable TUI - or runs headless from a JSON payload.

It powers the Vortex project installer, but knows nothing about Vortex: the engine is generic, the project-specific questions and handlers live in the consumer, and applying the collected answers is the consumer's job, not the TUI's.

Package scaffolder panel TUI

Features

  • 🧭 Panel TUI - a full-screen, scrollable, keyboard-driven form: panels hold fields, sub-panels drill in to any depth, with a contextual key-hint footer and a ? help overlay
  • 🧩 Widgets - text, number, date, textarea, password, select, multiselect, suggest, search, multisearch, filepicker, multifilepicker, confirm, toggle, pause
  • 🏗️ Builder-driven - panels and fields are declared in PHP with a fluent builder; the common cases need no code
  • 🤖 Interactive or headless - drive the panel TUI by keyboard, or collect answers non-interactively from a JSON payload and environment variables (and emit a JSON schema for agents and forms)
  • 🔗 Derived values - compute one field from others with str2name transforms; chains settle to a fixpoint
  • 🔀 Conditional fields - show or hide fields with when rules; a fix-up pass reconciles dependent answers
  • 🔍 Discovery - detect sensible defaults from the target directory (.env keys, JSON paths, path existence, directory scans)
  • ⚙️ Declared behaviour - validation, transforms and dynamic defaults as closures on the field; per-field handler classes remain as a fallback
  • 📦 Self-describing answers - each answer carries a snapshot of its question and its provenance; summaries need no form config
  • 🎨 Themes - the whole visual representation (colours, glyphs, layout) is a theme class; ships with dark and light
  • ⌨️ Key bindings - remap navigation, edit, accept and cancel keys per widget type; ships a vim-style preset, and a bad binding fails loudly at build time
  • Unicode and ASCII - glyphs follow the terminal locale and colour honours NO_COLOR; both can be forced on the form

Quick start

Declare a form with the fluent Form builder, then drive it with the Tui facade - one class that wires the engine, resolver, schema tools and TUI for you:

use DrevOps\Tui\Builder\Form;
use DrevOps\Tui\Builder\PanelBuilder;
use DrevOps\Tui\Tui;

$form = Form::create('My form')
->panel('general', 'General', fn(PanelBuilder $p) => $p->text('name', 'Your name')->required());

$tui = new Tui($form, ['App\\Handler']);

// Interactive panel TUI on a terminal, headless otherwise.
$answers = $tui->run();

// Or call a mode directly:
echo $tui->collect('{"name":"Ada"}')->toJson(); // headless: JSON + environment
$answers = $tui->interact(); // interactive panel TUI

It also exposes schema(), agentHelp() and validate(), and - when you want finer control - the internals via config(), engine() and registry(). See Installation to get started and the playground for complete, runnable examples.