pdphilip / omniterm
This is my package OmniTerm
Fund package maintenance!
PDPhilip
Installs: 27 897
Dependents: 3
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 2
pkg:composer/pdphilip/omniterm
Requires
- php: ^8.2
- illuminate/contracts: ^10.0||^11.0||^12.0
- nunomaduro/termwind: *
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^2.9
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1||^7.10.0
- orchestra/testbench: ^9.0.0||^8.22.0
- pestphp/pest: ^2.34
- pestphp/pest-plugin-arch: ^2.7
- pestphp/pest-plugin-laravel: ^2.3
- phpstan/extension-installer: ^1.3
- phpstan/phpstan-deprecation-rules: ^1.1
- phpstan/phpstan-phpunit: ^1.3
README
OmniTerm
A terminal UI toolkit for Laravel Artisan commands
Build beautiful CLI interfaces with styled output, progress bars, spinners, and async task execution.
Installation
composer require pdphilip/omniterm
Quick Start
Add the OmniTerm trait to your Artisan command:
<?php namespace App\Console\Commands; use Illuminate\Console\Command; use OmniTerm\OmniTerm; class MyCommand extends Command { use OmniTerm; protected $signature = 'my:command'; public function handle() { $this->initOmni(); $this->omni->success('Operation completed successfully!'); } }
Try the Samples
OmniTerm includes sample commands to demo all features. Copy them to your app:
mkdir -p app/Console/Commands/OmniTermSamples
cp vendor/pdphilip/omniterm/samples/Commands/*.php app/Console/Commands/OmniTermSamples/
Then run:
php artisan omniterm:full-demo # Complete demo (simulated deployment) php artisan omniterm:status-messages # Status message examples php artisan omniterm:progress-bars # Progress bar styles php artisan omniterm:spinners # All 10 spinner animations php artisan omniterm:data-tables # Key-value tables php artisan omniterm:async-tasks # Async task execution
See samples/README.md for the full list.
Features
- Status Messages - Styled feedback messages
- Detailed Statuses - Status blocks with title, details, and help text
- Data Tables - Key-value rows with status indicators
- Visual Elements - Boxes and horizontal rules
- Progress Bars - Framed and simple styles with color support
- Spinners & Loaders - Animated spinners for async tasks
- Async Task Execution - Run tasks with visual feedback
- Interactive Prompts - Ask questions with autocomplete
- Global Functions - Render HTML directly to terminal
Status Messages
Simple one-line status messages:
$this->omni->success('Task completed'); // Green "GOOD" badge $this->omni->error('Something went wrong'); // Red "FAIL" badge $this->omni->warning('Check your config'); // Amber "WARN" badge $this->omni->info('Processing...'); // Blue "INFO" badge $this->omni->disabled('Feature disabled'); // Gray "OFF" badge
Output:
GOOD Task completed
FAIL Something went wrong
WARN Check your config
INFO Processing...
OFF Feature disabled
Detailed Statuses
Status blocks with horizontal rules, title, details, and optional help text:
$this->omni->statusSuccess( 'Migration Complete', 'All 42 records processed successfully', ['Tip: Run "php artisan cache:clear" to see changes'] ); $this->omni->statusError( 'Connection Failed', 'Could not connect to database', ['Check your .env file', 'Ensure MySQL is running'] ); $this->omni->statusWarning('Cache Stale', 'Cache is older than 24 hours'); $this->omni->statusInfo('Build Started', 'Compiling assets...'); $this->omni->statusDisabled('Feature Off', 'Enable in config/app.php');
Custom status:
$this->omni->status('success', 'Title', 'Details text', ['Help line 1', 'Help line 2']);
Data Tables
Create formatted key-value tables with status indicators:
// Header row $this->omni->header('Setting', 'Value', 'Notes'); // Basic row $this->omni->row('Database', 'mysql', 'Production server'); // Status rows $this->omni->rowSuccess('Connection', 'Active'); $this->omni->rowError('SSL Certificate', 'Expired'); $this->omni->rowWarning('Memory', '85% used'); $this->omni->rowInfo('Version', '8.2.0'); $this->omni->rowDisabled('Debug Mode'); // Additional status types $this->omni->rowEnabled('Feature X'); $this->omni->rowOk('Health Check'); $this->omni->rowFailed('Sync Task', 'Retrying in 5s');
Output:
Setting Value Notes
Database .............................. mysql [Production server]
Connection ............................ SUCCESS
SSL Certificate ....................... FAILED
Memory ................................ WARNING [85% used]
Version ............................... INFO [8.2.0]
Debug Mode ............................ DISABLED
With help text:
$this->omni->rowError('API Key', 'Missing', [ 'Set OPENAI_API_KEY in your .env file', 'Get a key at https://openai.com' ]);
Visual Elements
Boxes
// Rounded corners (default) $this->omni->roundedBox('Welcome to MyApp', 'text-cyan-500', 'text-white'); // Square corners $this->omni->box('Configuration', 'text-amber-500', 'text-gray');
Output:
╭──────────────────────────────────────╮
│ │
│ Welcome to MyApp │
│ │
╰──────────────────────────────────────╯
Horizontal Rules
$this->omni->hr(); // Gray line $this->omni->hr('text-blue'); // Custom color // Semantic colors $this->omni->hrSuccess(); // Green $this->omni->hrError(); // Red $this->omni->hrWarning(); // Amber $this->omni->hrInfo(); // Blue $this->omni->hrDisabled(); // Gray
Progress Bars
Framed Progress Bar
$this->omni->createProgressBar(100, withColors: true); $this->omni->showProgress(); foreach ($items as $item) { // Process item... $this->omni->progressAdvance(); } $this->omni->progressFinish();
Output (with colors - changes from red to green as progress increases):
╭────────────────────────────────────────╮
0/100 │▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁│ 0%
╰────────────────────────────────────────╯
Simple Progress Bar
$this->omni->createSimpleProgressBar(50, withColors: false); $this->omni->showProgress(); for ($i = 0; $i < 50; $i++) { $this->omni->progressAdvance(); } $this->omni->progressFinish();
Progress Bar Options
| Method | Description |
|---|---|
createProgressBar($total, $withColors) |
Framed style with optional color gradient |
createSimpleProgressBar($total, $withColors) |
Minimal style |
showProgress() |
Display the progress bar |
progressAdvance($by = 1) |
Increment progress |
progressFinish() |
Complete and show 100% |
Spinners & Loaders
OmniTerm includes 10 spinner animations for visual feedback during async operations.
Available Spinner Types
| Type | Preview | Description |
|---|---|---|
dots |
⠋ ⠙ ⠹ ⠸ | Classic braille dots |
dots2 |
⢀⠀ ⡀⠀ | Double braille pattern |
dots3 |
⠉⠉ ⠈⠙ | Flowing dots |
dotsCircle |
⢎⠁ ⠎⠑ | Circular dot pattern |
sand |
⠁ ⠂ ⣿ | Filling hourglass effect |
clock |
🕛 🕐 🕑 | Clock face animation |
material |
▁█▁ | Material design loader |
pong |
▐⠂ ▌ | Bouncing ball |
progress |
▰▱▱ | Progress indicator |
progressLoader |
▰▱▱ | Looping progress |
Basic Spinner Usage
$this->omni->newLoader('sand'); $result = $this->omni->runTask('Processing data...', function () { // Your long-running task sleep(3); return ['state' => 'success', 'message' => 'Data processed']; });
Spinner with Custom Colors
Colors cycle through as the spinner animates:
$this->omni->newLoader('dots', [ 'text-amber-500', 'text-emerald-500', 'text-rose-500', 'text-sky-500' ]); $this->omni->runTask('Building...', function () { // Task code return ['state' => 'success']; });
Task Return Values
Your task callback should return an array with optional keys:
$this->omni->runTask('My Task', function () { // Do work... return [ 'state' => 'success', // success, warning, or error 'message' => 'Done!', // Completion message 'details' => 'Extra info', // Optional details ]; });
States:
success- Shows green checkmark ✔warning- Shows amber warning ⚠error- Shows red X ✘
Async Task Execution
OmniTerm can run tasks asynchronously using process forking, displaying a spinner while the task executes in the background.
$this->omni->newLoader('material', ['text-sky-500', 'text-emerald-500'], 1000); $result = $this->omni->runTask('Syncing with remote server...', function () { // This runs in a forked process $data = file_get_contents('https://api.example.com/sync'); if ($data) { return [ 'state' => 'success', 'message' => 'Sync complete', 'details' => 'Downloaded 1.2MB' ]; } return [ 'state' => 'error', 'message' => 'Sync failed' ]; }); if ($result['state'] === 'success') { // Continue processing }
Note: Async execution requires the pcntl extension. On systems without it (like Windows), tasks run synchronously with a fallback display.
Interactive Prompts
Ask the user for input with optional autocomplete suggestions:
// Simple question $name = $this->omni->ask('What is your name?'); // With autocomplete options $color = $this->omni->ask('Choose a color:', ['red', 'green', 'blue']);
Global Functions
OmniTerm provides functions for direct HTML-to-terminal rendering:
render()
Render HTML with Tailwind CSS classes to the terminal:
use function OmniTerm\render; render('<div class="text-green-500 font-bold">Success!</div>'); render('<span class="bg-red-600 text-white px-2">ERROR</span> Something failed');
liveRender()
Create a live-updating display that redraws in place:
use function OmniTerm\liveRender; $live = liveRender('<div>Starting...</div>'); for ($i = 1; $i <= 100; $i++) { $live->reRender("<div>Progress: {$i}%</div>"); usleep(50000); }
asyncFunction()
Create an async renderer for custom async operations:
use function OmniTerm\asyncFunction; $async = asyncFunction(function () { // Background task return ['done' => true]; }); $result = $async->run(function () use ($async) { $async->render('<div>Working...</div>'); }, 10000); // Update every 10ms
ask()
Prompt for user input:
use function OmniTerm\ask; $answer = ask('Continue? (y/n)');
terminal()
Get terminal dimensions:
use function OmniTerm\terminal; $width = terminal()->getWidth(); $height = terminal()->getHeight();
Customizing Colors
Override the default status colors:
$this->initOmni(); $this->omni->successColor = 'green'; // Default: emerald $this->omni->errorColor = 'red'; // Default: rose $this->omni->warningColor = 'orange'; // Default: amber $this->omni->infoColor = 'blue'; // Default: sky $this->omni->disabledColor = 'gray'; // Default: zinc
Colors use Tailwind CSS color names (without the number suffix).
Complete Example
<?php namespace App\Console\Commands; use Illuminate\Console\Command; use OmniTerm\OmniTerm; class DeployCommand extends Command { use OmniTerm; protected $signature = 'app:deploy'; protected $description = 'Deploy the application'; public function handle() { $this->initOmni(); // Header $this->omni->roundedBox('Deployment Starting', 'text-cyan-500'); // Configuration check $this->omni->header('Check', 'Status'); $this->omni->rowSuccess('PHP Version', '8.2.0'); $this->omni->rowSuccess('Composer', 'Installed'); $this->omni->rowWarning('Node.js', '16.x (18.x recommended)'); $this->omni->hrInfo(); // Run migrations with spinner $this->omni->newLoader('sand', ['text-amber-500', 'text-emerald-500']); $result = $this->omni->runTask('Running migrations', function () { // Artisan::call('migrate', ['--force' => true]); sleep(2); // Simulated work return ['state' => 'success', 'message' => 'Migrations complete']; }); // Build assets with progress bar $this->omni->info('Building assets...'); $this->omni->createProgressBar(100, true); $this->omni->showProgress(); for ($i = 0; $i < 100; $i++) { usleep(20000); $this->omni->progressAdvance(); } $this->omni->progressFinish(); // Final status $this->omni->statusSuccess( 'Deployment Complete', 'Application deployed successfully', ['Visit https://myapp.com to verify'] ); return Command::SUCCESS; } }
Requirements
- PHP 8.2+
- Laravel 10, 11, or 12
Dependencies
- nunomaduro/termwind - HTML to terminal rendering
License
The MIT License (MIT). Please see License File for more information.