pdphilip/omniterm
Laravel terminal UI toolkit: write Artisan/CLI output as HTML with Tailwind-style classes and OmniTerm renders it to ANSI. Includes truecolor with fallback, gradients, arbitrary RGB, and content repeat, plus ready-made components like status messages, tables, progress bars, spinners, and live tasks.
Installation:
composer require pdphilip/omniterm
Add the HasOmniTerm trait to any Artisan command:
use OmniTerm\HasOmniTerm;
class MyCommand extends Command
{
use HasOmniTerm;
}
First Use Case: Display a success message:
$this->omni->success('Task completed');
This renders a green "GOOD" badge with the message.
php artisan omniterm:full-demo
text-sky-500, bg-gradient-to-r).Status Messages: Use for one-line feedback or detailed status blocks:
// One-liner
$this->omni->warning('Check your config');
// Detailed block
$this->omni->statusError('Connection Failed', 'Could not reach database', ['Check .env', 'Ensure MySQL is running']);
Progress Bars: Fluent API for tracking progress with customizable styles:
$bar = $this->omni->progressBar(100)->framed()->gradient('rose', 'sky');
$bar->start();
foreach ($items as $item) { $bar->advance(); }
$bar->finish();
Live Tasks: Run async operations with real-time feedback:
$result = $this->omni->task('Processing data...', fn() => sleep(3), Spinner::Sand);
Data Tables: Display structured data with status indicators:
$this->omni->tableHeader('Setting', 'Value', 'Notes');
$this->omni->tableRowSuccess('Connection', 'Active');
Blade Templates: Render reusable CLI views:
$this->omni->view('cli.deploy-status', ['badge' => 'DEPLOY', 'color' => 'emerald']);
Store templates in resources/views/cli/.
Dynamic Content:
Use liveView() for real-time updates:
$live = $this->omni->liveView('<div>Starting...</div>');
for ($i = 0; $i < 100; $i++) {
$live->reRender("<div>Progress: {$i}%</div>");
}
Terminal Dimensions: Adapt layouts to screen size:
$width = $this->omni->terminal()->getWidth();
$this->omni->render('<div class="w-' . min($width, 80) . '">...</div>');
Async Operations: Combine with Laravel queues for long-running tasks:
$job = ProcessData::dispatch();
$this->omni->task('Processing in queue...', fn() => $job->wait());
| Pattern | Example |
|---|---|
| Conditional Rendering | $this->omni->render($error ? '<div class="text-red-500">...</div>' : '...'); |
| Color Themes | Use text-[R,G,B] for dynamic colors (e.g., text-[255,100,50]). |
| Nested Components | Combine tables, boxes, and status messages in a single view. |
| Interactive Input | $name = $this->omni->ask('Enter name:'); |
Terminal Compatibility:
text-sky-500) for reliability.Performance:
reRender() calls can lag. Batch updates or use usleep() for delays:
usleep(100000); // 100ms delay
Blade Caching:
php artisan view:clear
Spinner Sync:
runTask) may desync if the callback completes faster than the spinner’s animation frame. Add small delays if needed:
$this->omni->runTask('Slow task...', fn() => usleep(500000) || true);
Gradient Limits:
bg-gradient-to-r) work best on single-line elements. Multi-line gradients may render unevenly.ANSI Output Inspection: Pipe output to a file to debug ANSI sequences:
php artisan my:command > output.ansi
Use a tool like ANSI Escape to visualize.
Terminal Emulator:
Logging Raw HTML: Log the HTML before rendering to verify classes:
$html = '<div class="text-[255,0,0]">Test</div>';
$this->info($html); // Log raw HTML
$this->omni->render($html);
Component Isolation: Test components in isolation using the sample commands:
php artisan omniterm:progress-bars
Custom Spinners:
Extend the Spinner enum or create a custom animation by overriding the render() method in a subclass of OmniTerm\Async\Spinner.
New Components:
Build reusable components by combining render() and Blade templates:
// app/Console/Components/HealthCheck.php
class HealthCheck {
public function __invoke(OmniTerm $omni, array $services) {
$omni->titleBar('Service Health');
foreach ($services as $name => $status) {
$omni->tableRow($name, $status['status'], $status['details'] ?? '');
}
}
}
Color Palettes: Create a helper to generate consistent color schemes:
function getThemeColors(string $theme): array {
return match ($theme) {
'dark' => ['bg-zinc-900', 'text-zinc-100'],
'light' => ['bg-white', 'text-zinc-800'],
default => ['bg-gray-100', 'text-gray-900'],
};
}
Event Listeners:
Hook into OmniTerm’s lifecycle (e.g., after rendering) by extending the OmniTerm class and overriding methods like render().
Custom Terminal Detection:
Override OmniTerm\Terminal::detect() to add support for niche terminals or enforce specific modes.
No Config File: OmniTerm is zero-config. All settings are runtime-based (e.g., terminal detection, color fallback).
Global Defaults: Set defaults for all commands via a service provider:
OmniTerm::setDefaultSpinner(Spinner::DotsCircle);
OmniTerm::setDefaultProgressColor('indigo');
Environment-Specific Rendering: Use Laravel’s environment detection to adjust output:
if (app()->environment('local')) {
$this->omni->render('<div class="text-yellow-500">DEBUG MODE</div>');
}
Combine with Laravel Notifications: Render OmniTerm output in scheduled jobs or notifications:
$notification = new OmniTermNotification($this->omni->parse('<div class="text-red-500">Alert!</div>'));
CI/CD Integration: Use OmniTerm in GitHub Actions
How can I help you explore Laravel packages today?