tanbhirhossain/laravel-live-terminal
composer require tanbhirhossain/laravel-live-terminal
php artisan vendor:publish --provider="TanbhirHossain\LiveTerminal\LiveTerminalServiceProvider" --tag="config"
config/live-terminal.php:
'allowed_commands' => [
'migrate',
'migrate:fresh',
'db:seed',
'cache:clear',
'route:list',
],
'auth_middleware' => ['auth:sanctum'], // or 'auth:admin'
routes/web.php:
Route::middleware(['web', 'auth:sanctum'])->get('/terminal', [\TanbhirHossain\LiveTerminal\Http\Controllers\TerminalController::class, 'index']);
/terminal in your browser to execute whitelisted Artisan commands (e.g., php artisan migrate).Command Whitelisting:
config/live-terminal.php (e.g., ['migrate', 'queue:work']).public function boot()
{
$this->app['live-terminal']->extend(function ($terminal) {
$terminal->allowedCommands(['tinker']); // Add dynamically
});
}
.env to toggle features:
LIVE_TERMINAL_ENABLED=true
LIVE_TERMINAL_ALLOWED_COMMANDS=migrate,db:seed
Middleware Integration:
spatie/laravel-permission:
Route::middleware(['auth:sanctum', 'can:access-terminal'])->get('/terminal', ...);
Route::middleware(['web', 'auth:sanctum', 'trusted'])->get('/terminal', ...);
Output Handling:
TerminalController).storage/logs/terminal.log:
$terminal->logCommand('migrate', $user->id, $output);
Command Arguments:
'allowed_commands' => [
'migrate' => ['args' => ['--force']],
'db:seed' => ['args' => ['--class=UserSeeder']],
],
'allowed_commands' => [
'queue:work' => ['args' => function ($args) {
return in_array($args[0] ?? '', ['--once', '--sleep=3']);
}],
],
Integration with Laravel Features:
'allowed_commands' => ['horizon:status'],
queue:work and queue:flush.Security Misconfigurations:
auth:sanctum). Avoid public routes.['allowed_commands' => ['artisan', 'exec', 'shell']] // ❌ Avoid!
storage:link, down, or up unless explicitly needed.Command Output Issues:
--no-ansi for commands with slow output (e.g., queue:work).ini_set('memory_limit', '512M') to the terminal’s TerminalController for heavy commands.Configuration Overrides:
.env and config/live-terminal.php don’t override each other unexpectedly. Use:
'allowed_commands' => explode(',', env('LIVE_TERMINAL_ALLOWED_COMMANDS', 'migrate,db:seed')),
Middleware Conflicts:
php artisan route:clear
php artisan route:list | grep terminal to verify middleware.Command Failures:
storage/logs/laravel.log for Artisan errors.config/live-terminal.php:
'debug' => env('APP_DEBUG', false),
Output Formatting:
$output = str_replace("\e[", '', $output); // Strip ANSI for web
Permission Denied:
www-data) has execute permissions for Artisan:
chmod +x artisan
Custom Terminal UI:
resources/views/vendor/live-terminal/index.blade.php) to add:
sessions).Rate Limiting:
throttle middleware to prevent abuse:
Route::middleware(['throttle:60,1'])->get('/terminal', ...);
Team Collaboration:
$terminal->log(['user_id' => auth()->id(), 'command' => $command, 'output' => $output]);
migrate:fresh).Performance Optimization:
route:list) for 5 minutes:
$cacheKey = "terminal_route_list_{$user->id}";
return Cache::remember($cacheKey, 300, fn() => Artisan::call('route:list'));
if (userIsAdmin) {
fetch('/terminal').then(html => document.getElementById('terminal').innerHTML = html);
}
Testing:
TerminalController:
$terminal = Mockery::mock(\TanbhirHossain\LiveTerminal\Terminal::class);
$terminal->shouldReceive('execute')->with('migrate')->andReturn('Success!');
$browser->visit('/terminal')->type('migrate')->press('Enter');
How can I help you explore Laravel packages today?