pdphilip/omniterm
Composer 安装命令:
composer require pdphilip/omniterm
包简介
This is my package OmniTerm
README 文档
README
Terminal UI toolkit for Laravel
Rich CLI output using HTML and Tailwind CSS classes, rendered as ANSI in your terminal.

About
OmniTerm is a terminal rendering engine for Laravel. Write your CLI output as HTML with Tailwind CSS classes and OmniTerm compiles it to ANSI escape sequences.
The Tailwind-for-terminal concept was pioneered by Termwind. OmniTerm builds on that idea with its own rendering engine that adds:
- 16 million color support - full RGB truecolor, with automatic 256-color fallback for older terminals
- Gradients -
bg-gradient-to-r,from-{color},via-{color},to-{color}for smooth per-character color transitions - Arbitrary RGB classes -
text-[R,G,B]andbg-[R,G,B]for computed/dynamic colors - Content repeat -
content-repeat-[char]to fill widths with box-drawing characters
On top of the rendering engine, OmniTerm ships with a set of pre-built components for common CLI patterns: status messages, data tables, progress bars, spinners, live tasks, and an interactive split-pane browser.
Requirements
- PHP 8.2+
- Laravel 10, 11, or 12
Installation
composer require pdphilip/omniterm
Built-in Components
Add the HasOmniTerm trait to any Artisan command:
use OmniTerm\HasOmniTerm;
class MyCommand extends Command
{
use HasOmniTerm;
public function handle()
{
$this->omni->success('Ready');
}
}
Status Messages
One-line status badges:
$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 off'); // Gray OFF badge
Detailed status blocks with title, message, and help lines:
$this->omni->statusSuccess('Migration Complete', 'All 42 records processed', ['Run cache:clear']);
$this->omni->statusError('Connection Failed', 'Could not reach database', ['Check .env', 'Ensure MySQL is running']);

Data Tables
Key-value rows with status indicators:
$this->omni->tableHeader('Setting', 'Value', 'Notes');
$this->omni->tableRow('Database', 'mysql', 'Production server');
$this->omni->tableRowSuccess('Connection', 'Active');
$this->omni->tableRowError('SSL Certificate', 'Expired');
$this->omni->tableRowWarning('Memory', '85% used');

Visual Elements
Title bars, boxes, and horizontal rules:
$this->omni->titleBar('My Application', 'sky');
$this->omni->roundedBox('Welcome', 'text-cyan-500', 'text-white');
$this->omni->hr();
$this->omni->hrSuccess();

Progress Bars
Fluent builder API with three styles: simple, framed, and gradient. Color steps transition from rose through amber to emerald as progress increases.
$bar = $this->omni->progressBar(100)->framed()->steps();
$bar->start();
foreach ($items as $item) {
// work...
$bar->advance();
}
$bar->finish();
Other variants:
$this->omni->progressBar(50); // Simple bar (sky)
$this->omni->progressBar(50)->steps(); // Simple with color steps
$this->omni->progressBar(50)->framed()->color('indigo'); // Framed with custom color
$this->omni->progressBar(50)->gradient(); // Gradient (amber → emerald)
$this->omni->progressBar(50)->framed()->gradient('rose', 'sky'); // Custom gradient

Live Tasks
Run a callback in a background process with an animated spinner:
use OmniTerm\Async\Spinner;
$this->omni->newLoader(Spinner::Sand);
$result = $this->omni->runTask('Processing data...', function () {
sleep(3);
return ['state' => 'success', 'message' => 'Done'];
});
One-liner with task():
$this->omni->task('Processing batch job', function () {
sleep(3);
return ['state' => 'success', 'message' => 'Batch complete', 'details' => '500 records'];
}, Spinner::DotsCircle, ['text-indigo-500', 'text-violet-500']);
For fine-grained control with live-updating counters:
$task = $this->omni->liveTask('Processing records', spinner: Spinner::Dots3)
->row('Created', 0, 'text-sky-500')
->row('Updated', 0, 'text-emerald-500')
->row('Skipped', 0, 'text-amber-500')
->row('Failed', 0, 'text-rose-500');
// Simulate 5 chunked batches
for ($batch = 0; $batch < 5; $batch++) {
$result = $task->run(function () {
usleep(800000);
return [
'created' => rand(10, 50),
'updated' => rand(5, 20),
'skipped' => rand(0, 5),
'failed' => rand(0, 2),
];
});
$task->increment('Created', $result['created']);
$task->increment('Updated', $result['updated']);
$task->increment('Skipped', $result['skipped']);
$task->increment('Failed', $result['failed']);
}
$task->finish('Processing complete');
The Spinner enum provides 10 animation types: Dots, Dots2, Dots3, DotsCircle, Sand, Clock, Material, Pong, Progress, ProgressLoader.
Interactive Browser
Split-pane TUI: scrollable list on the left, detail view on the right. Items can be closures (rendered with full omni output), associative arrays (auto-formatted), or plain arrays.
+-- Server Dashboard ---------------+-----------------------------------+
| > web-01 | ✓ GOOD Healthy |
| web-02 | All checks passing |
| db-primary | |
| cache-01 | Metric Value |
+-----------------------------------+ CPU 23% |
+-----------------------------------+
↑/↓ Navigate Enter Select q/Esc Exit
use OmniTerm\OmniTerm;
$selected = $this->omni->browse('Server Dashboard', [
'web-01' => function (OmniTerm $omni) {
$omni->statusSuccess('Healthy', 'All checks passing');
$omni->tableHeader('Metric', 'Value');
$omni->tableRowSuccess('CPU', '23%');
$omni->tableRow('Memory', '4.2 GB / 8 GB');
},
'db-primary' => ['status' => 'running', 'cpu' => '45%', 'memory' => '28 GB / 32 GB'],
]);
// Returns selected key, or null on Esc
Interactive Prompts
$name = $this->omni->ask('What is your name?');
$color = $this->omni->ask('Choose a color:', ['red', 'green', 'blue']);
DIY - The Rendering Engine
The built-in components are just Blade templates compiled through OmniTerm's rendering engine. You can use the same engine directly to build anything.
render()
Write HTML with Tailwind classes, get ANSI output:
$this->omni->render('<div class="flex">
<span class="bg-emerald-600 text-white font-bold px-1">PASS</span>
<span class="flex-1 text-zinc-400 px-1">Database connection verified</span>
<span class="text-zinc-600 text-right w-12">12ms</span>
</div>');
liveView()
Redraws in place, for live-updating displays:
$live = $this->omni->liveView('<div>Starting...</div>');
for ($i = 1; $i <= 100; $i++) {
$live->reRender("<div>Progress: {$i}%</div>");
usleep(50000);
}
$this->omni->endLiveView();
parse()
Convert HTML to an ANSI string without printing:
$ansi = $this->omni->parse('<span class="text-sky-500">Hello</span>');
terminal()
Terminal dimensions:
$width = $this->omni->terminal()->getWidth();
$height = $this->omni->terminal()->getHeight();
Supported Classes

Layout
| Class | Effect |
|---|---|
flex | Horizontal layout |
flex-1 | Fill remaining space |
w-{n} | Fixed width in characters |
space-x-{n} | Gap between children |
Spacing
| Class | Effect |
|---|---|
px-{n}, pl-{n}, pr-{n} | Horizontal padding |
mx-{n}, ml-{n}, mr-{n} | Horizontal margin |
mt-{n}, mb-{n} | Vertical margin (blank lines) |
Typography
| Class | Effect |
|---|---|
font-bold | Bold |
text-center | Center-align |
text-right | Right-align |
Colors
All Tailwind colors with shades 50-950: slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose.
| Class | Effect |
|---|---|
text-{color}-{shade} | Text color, e.g. text-sky-500 |
bg-{color}-{shade} | Background color, e.g. bg-red-600 |
text-[R,G,B] | Arbitrary RGB text, e.g. text-[255,100,50] |
bg-[R,G,B] | Arbitrary RGB background |
Gradients
Per-character color interpolation across an element's width.
| Class | Effect |
|---|---|
bg-gradient-to-r | Left-to-right gradient |
bg-gradient-to-l | Right-to-left gradient |
from-{color}-{shade} | Start color |
via-{color}-{shade} | Midpoint color |
to-{color}-{shade} | End color |
$this->omni->render('<div class="flex">
<span class="flex-1 bg-gradient-to-r from-indigo-800 via-purple-500 to-pink-400 text-white text-center">
Smooth gradient
</span>
</div>');
Content
| Class | Effect |
|---|---|
content-repeat-[char] | Repeat character to fill width |
Color Mode Detection
OmniTerm auto-detects your terminal's color capability:
- Truecolor (16M) - full RGB. iTerm2, Kitty, WezTerm, most modern terminals.
- 256-color - automatic fallback for older terminals (e.g. Apple Terminal). Colors mapped to nearest match.
No configuration needed.
Using Blade Templates
Since OmniTerm is a Laravel package, you can write your CLI output as Blade views and render them through the engine. This is how all the built-in components work:
// resources/views/cli/deploy-status.blade.php
<div class="flex">
<span class="bg-{{ $color }}-600 text-white font-bold px-1">{{ $badge }}</span>
<span class="flex-1 text-zinc-400 px-1">{{ $message }}</span>
</div>
// In your command
$this->omni->view('cli.deploy-status', [
'badge' => 'DEPLOY',
'color' => 'emerald',
'message' => 'Production updated',
]);
Samples
OmniTerm includes sample commands for every feature. Copy them into your app:
mkdir -p app/Console/Commands/OmniTermSamples
cp vendor/pdphilip/omniterm/samples/Commands/*.php app/Console/Commands/OmniTermSamples/
Update the namespace in each file to App\Console\Commands\OmniTermSamples, then:
php artisan omniterm:full-demo # One of every feature
php artisan omniterm:status-messages # Status messages
php artisan omniterm:data-tables # Key-value tables
php artisan omniterm:visual-elements # Boxes and horizontal rules
php artisan omniterm:title-bars # Title bar colors
php artisan omniterm:progress-bars # All progress bar styles
php artisan omniterm:spinners # All 10 spinner animations
php artisan omniterm:async-tasks # Async task execution
php artisan omniterm:live-task-demo # LiveTask with feedback rows
php artisan omniterm:browser-demo # Interactive split-pane browser
php artisan omniterm:tailwind-classes # Every supported CSS class
php artisan omniterm:interactive # Interactive prompts
php artisan omniterm:custom-colors # Custom color schemes
php artisan omniterm:global-functions # Render & live view functions
Testing
composer test # Lint + PHPStan + Pest
composer test:unit # Pest only
composer types # PHPStan only
composer format # Laravel Pint
License
MIT. See License File.
pdphilip/omniterm 适用场景与选型建议
pdphilip/omniterm 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 57.86k 次下载、GitHub Stars 达 1, 最近一次更新时间为 2024 年 09 月 17 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「laravel」 「PDPhilip」 「omniterm」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 pdphilip/omniterm 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 pdphilip/omniterm 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 pdphilip/omniterm 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Search your Laravel models with the convenience of Eloquent and the power of Elasticsearch
Cloudflare Laravel Request
OmniEvent for Laravel is a Laravel Model event tracking and searching with Elasticsearch module
Eloquent style management of data sets in Laravel
Alfabank REST API integration
This is my package OmniTerm
统计信息
- 总下载量: 57.86k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 8
- 依赖项目数: 6
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2024-09-17