roshan-dhungana / route-commands
A Laravel package for executing Artisan commands from a browser-based interface
Package info
github.com/dhunganaroshan341/Route-Commands-Composer
Language:Blade
pkg:composer/roshan-dhungana/route-commands
Requires
- php: ^8.2
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A beautiful browser-based Artisan command runner for Laravel.
Laravel Route Commands provides a web interface for executing Laravel Artisan commands directly from your browser.
Instead of opening a terminal every time you need to run a common command such as:
php artisan cache:clear php artisan route:list php artisan config:clear php artisan migrate
you can open the Route Commands dashboard and execute permitted commands from a modern glass-style interface.
Important: Because this package executes Artisan commands, it should only be exposed to trusted and authenticated users. Production installations should also use the command allowlist.
Features
- โก Execute Laravel Artisan commands from your browser
- ๐จ Modern glassmorphism interface
- ๐ One-click execution for predefined commands
- ๐ฅ๏ธ Terminal-style command output
- ๐ Copy command output
- ๐งน Clear terminal output
- ๐ ๏ธ Execute custom permitted Artisan commands
- ๐งฉ Support for Artisan arguments and options
- ๐ Built-in Laravel authentication
- ๐ค Uses the host application's existing users/authentication system
- ๐ช Login and logout support
- ๐ก๏ธ Configurable Artisan command allowlist
- ๐ Protected dashboard and command execution routes
- ๐ฆ Easy Composer installation
- ๐งฑ Built using Laravel's Service Provider architecture
Requirements
Before installing this package, make sure your application has:
- PHP 8.2+
- Laravel 10+
- Composer
The package supports Laravel 10, 11, 12, and 13, subject to the PHP requirements of the Laravel version being used.
The package is designed to work as a Laravel package and uses Laravel's package discovery mechanism.
Installation
Install the package using Composer:
composer require roshan-dhungana/route-commands
Laravel should automatically discover the package service provider through Composer package discovery.
After installation, clear the Laravel application cache:
php artisan optimize:clear
Verify that the package routes are registered:
php artisan route:list --path=route-commands
Authentication
Starting with v1.1.0, Route Commands includes built-in authentication.
The package uses the host Laravel application's existing authentication system.
It does not create a separate users table.
By default, it uses Laravel's:
web
authentication guard.
The authentication flow is:
User
โ
/route-commands/login
โ
Laravel web authentication
โ
Existing application users table
โ
Authenticated session
โ
/route-commands
This means users can log in using the same credentials managed by the Laravel application.
Authentication Configuration
The package configuration is located at:
config/route-commands.php
The authentication configuration can be defined as:
'auth' => [ 'enabled' => true, 'guard' => 'web', 'middleware' => [ 'web', ], ],
Configuration options
| Option | Description |
|---|---|
enabled |
Enables package authentication |
guard |
Laravel authentication guard to use |
middleware |
Middleware used by the package authentication routes |
The default guard is:
'web'
If your Laravel application uses another appropriate session-based guard, you can configure it here.
For example:
'auth' => [ 'enabled' => true, 'guard' => 'admin', 'middleware' => [ 'web', ], ],
The selected guard must already be configured by the host Laravel application.
Login
When authentication is enabled, open:
http://127.0.0.1:8000/route-commands/login
or:
https://your-domain.com/route-commands/login
The package displays a login page.
After successful authentication, the user is redirected to:
/route-commands
The login request uses Laravel's normal session-based authentication and CSRF protection.
Logout
Authenticated users can log out using the package logout functionality.
The package:
- Logs the user out through the configured guard.
- Invalidates the session.
- Regenerates the CSRF token.
- Redirects the user back to the login page.
Protected Routes
The package protects the command dashboard and command execution endpoints using authentication middleware.
The main routes are:
GET /route-commands/login
POST /route-commands/login
GET /route-commands
POST /route-commands/run
POST /route-commands/logout
The protected routes require an authenticated session.
Command Allowlist
Authentication alone is not sufficient protection for an Artisan command runner.
An authenticated user should not automatically be allowed to execute every Artisan command available in the Laravel application.
Route Commands therefore supports an allowed command list.
Configure permitted commands in:
config/route-commands.php
Example:
'allowed_commands' => [ 'cache:clear', 'config:clear', 'route:clear', 'view:clear', 'event:clear', 'optimize:clear', 'about', 'route:list', 'migrate:status', 'schedule:list', 'migrate', 'storage:link', 'queue:restart', 'queue:failed', 'queue:flush', ],
Before executing a command, the package checks whether the requested command exists in the configured allowlist.
If the command is not allowed, the package returns:
403 Forbidden
with:
This command is not allowed.
This prevents authenticated users from simply submitting arbitrary Artisan commands.
Security Recommendation
The Route Commands dashboard should be treated as an administrative interface.
Do not expose it publicly without authentication.
For production environments:
- Enable authentication.
- Use a trusted authentication guard.
- Configure a restrictive command allowlist.
- Avoid exposing destructive commands unnecessarily.
- Do not allow arbitrary command execution.
- Review every command added to the allowlist.
- Consider restricting access further using Laravel authorization, network controls, or a VPN.
For example, avoid exposing potentially destructive commands unless there is a specific operational requirement.
Recommended Production Allowlist
A conservative production configuration could be:
'allowed_commands' => [ 'cache:clear', 'config:clear', 'route:clear', 'view:clear', 'about', 'route:list', 'migrate:status', ],
Commands that modify the database or filesystem should only be exposed when required.
For example:
migrate
storage:link
queue:flush
should be reviewed carefully before being enabled.
Using the Dashboard
After authentication, open:
/route-commands
The dashboard contains predefined command cards.
For example:
cache:clear
config:clear
route:clear
view:clear
event:clear
optimize:clear
Clicking a command card executes the command immediately, provided the command is included in the configured allowlist.
For example:
cache:clear
is equivalent to:
php artisan cache:clear
Inspection Commands
The dashboard can provide useful Laravel inspection commands such as:
php artisan about
php artisan route:list
php artisan migrate:status
php artisan schedule:list
The command output is displayed directly inside the browser terminal.
Database Commands
Database-related commands can also be exposed when explicitly added to the allowlist.
For example:
php artisan migrate
and:
php artisan storage:link
Only add commands that your application's trusted users actually need.
Always understand the consequences of a command before adding it to the allowlist, especially commands that modify or delete data.
Queue Commands
Queue-related commands can be exposed through the dashboard.
Examples:
php artisan queue:restart
php artisan queue:failed
php artisan queue:flush
Add only the required commands to:
'allowed_commands' => [ // ... ],
Custom Commands
The dashboard provides a custom command input.
For example:
cache:clear
or:
route:list
or:
migrate:status
Enter the command and click:
Execute Command
The command is executed only if it is included in the configured allowlist.
The output is then displayed in the terminal panel.
Command Arguments and Options
The package supports passing Artisan arguments and options as JSON.
For example, Laravel's:
php artisan make:model Post --migration
can be represented as:
command:
make:model
with:
{
"name": "Post",
"--migration": true
}
Another example:
php artisan make:controller UserController
can be represented as:
command:
make:controller
with:
{
"name": "UserController"
}
The command itself must still be permitted by the configured command allowlist.
How It Works
The package provides authentication and command execution routes.
Login
GET /route-commands/login
Displays the login page.
Login Submission
POST /route-commands/login
Authenticates the user using the configured Laravel guard.
Dashboard
GET /route-commands
Displays the command runner interface.
This route requires authentication.
Execute Command
POST /route-commands/run
The request contains:
command
options
Example:
command=route:list
options=
The package first verifies that the user is authenticated and that the requested command is allowed.
It then internally executes:
Artisan::call($command, $parameters);
The Artisan output is returned as plain text.
The frontend reads the response using:
const responseText = await response.text();
rather than:
const data = await response.json();
This is intentional because Artisan commands such as route:list generate terminal-style text output rather than JSON.
Architecture
The package follows a simple Laravel package structure:
route-commands/
โ
โโโ config/
โ โโโ route-commands.php
โ
โโโ resources/
โ โโโ views/
โ โโโ auth/
โ โ โโโ login.blade.php
โ โโโ index.blade.php
โ
โโโ src/
โ โ
โ โโโ Console/
โ โ
โ โโโ Http/
โ โ โโโ Controllers/
โ โ โ โโโ AuthController.php
โ โ โ โโโ CommandController.php
โ โ โ
โ โ โโโ Middleware/
โ โ โโโ RouteCommandsAuthenticate.php
โ โ
โ โโโ Services/
โ โ โโโ CommandExecutor.php
โ โ
โ โโโ routes/
โ โ โโโ web.php
โ โ
โ โโโ RouteCommandsServiceProvider.php
โ
โโโ composer.json
โโโ README.md
Service Provider
The package service provider registers the package resources.
<?php namespace RoshanDhungana\RouteCommands; use Illuminate\Support\ServiceProvider; class RouteCommandsServiceProvider extends ServiceProvider { public function register(): void { $this->mergeConfigFrom( __DIR__ . '/../config/route-commands.php', 'route-commands' ); } public function boot(): void { $this->loadRoutesFrom( __DIR__ . '/routes/web.php' ); $this->loadViewsFrom( __DIR__ . '/../resources/views', 'route-commands' ); $this->publishes([ __DIR__ . '/../config/route-commands.php' => config_path('route-commands.php'), ], 'route-commands-config'); } }
Laravel package service providers are the standard integration point for registering package resources such as:
- Configuration
- Routes
- Views
- Service bindings
- Publishable assets
Configuration Publishing
The package configuration can be published into the host Laravel application.
Run:
php artisan vendor:publish --tag=route-commands-config
This publishes:
config/route-commands.php
into the application's:
config/
directory.
After changing the configuration, clear Laravel's cached configuration:
php artisan optimize:clear
Routes
The package registers authentication and protected command routes.
Conceptually:
Route::middleware(['web']) ->prefix('route-commands') ->group(function () { Route::get('/login', [ AuthController::class, 'showLogin', ])->name('route-commands.login'); Route::post('/login', [ AuthController::class, 'login', ])->name('route-commands.login.submit'); });
Protected routes use the package authentication middleware:
Route::middleware([ 'web', RouteCommandsAuthenticate::class, ]) ->prefix('route-commands') ->group(function () { Route::get('/', [ CommandController::class, 'index', ])->name('route-commands.index'); Route::post('/run', [ CommandController::class, 'run', ])->name('route-commands.run'); Route::post('/logout', [ AuthController::class, 'logout', ])->name('route-commands.logout'); });
Development
Clone the repository:
git clone https://github.com/dhunganaroshan341/Route-Commands-Composer.git
Enter the directory:
cd Route-Commands-Composer
Install dependencies:
composer install
Local Package Development
If you are developing Route Commands alongside another Laravel application, Composer's path repository feature can be used.
Example:
{
"repositories": [
{
"type": "path",
"url": "../route-commands",
"options": {
"symlink": true
}
}
]
}
Then require the development version:
composer require roshan-dhungana/route-commands:@dev
With symlink enabled, changes made to the local package are immediately available to the Laravel application.
After making package changes, it can be useful to run:
composer dump-autoload
and:
php artisan optimize:clear
Testing the Package
After installing the package:
php artisan optimize:clear
Check the registered routes:
php artisan route:list --path=route-commands
You should see routes similar to:
GET|HEAD route-commands/login
POST route-commands/login
GET|HEAD route-commands
POST route-commands/run
POST route-commands/logout
Open:
http://127.0.0.1:8000/route-commands/login
Log in using an existing Laravel application user.
Then test permitted commands such as:
cache:clear
route:list
about
Finally, test a command that is not in the allowlist.
It should return:
403
with:
This command is not allowed.
Example Workflow
Install the package:
composer require roshan-dhungana/route-commands
Clear Laravel caches:
php artisan optimize:clear
Publish the configuration if customization is required:
php artisan vendor:publish --tag=route-commands-config
Configure authentication and allowed commands in:
config/route-commands.php
Start Laravel:
php artisan serve
Open:
http://127.0.0.1:8000/route-commands/login
Authenticate using an existing application user.
Then select a permitted command such as:
Route List
The package executes:
php artisan route:list
and displays the result inside the browser terminal.
Troubleshooting
Route does not exist
Clear the application cache:
php artisan optimize:clear
Then regenerate Composer's autoloader:
composer dump-autoload
Verify:
php artisan route:list --path=route-commands
Package service provider is not loaded
Check the package composer.json.
It should contain:
{
"autoload": {
"psr-4": {
"RoshanDhungana\\RouteCommands\\": "src/"
}
},
"extra": {
"laravel": {
"providers": [
"RoshanDhungana\\RouteCommands\\RouteCommandsServiceProvider"
]
}
}
}
Then run:
composer dump-autoload
and:
php artisan optimize:clear
Laravel package discovery should then register the service provider automatically.
Login returns 419 Page Expired
A 419 response generally indicates a session or CSRF issue in the host Laravel application.
Check that the application has a working Laravel session configuration.
For local development, for example:
SESSION_DRIVER=file SESSION_DOMAIN= SESSION_SECURE_COOKIE=false SESSION_SAME_SITE=lax
If using:
SESSION_DRIVER=database
make sure the application's sessions table exists.
Also clear the configuration cache:
php artisan optimize:clear
Make sure you consistently use the same local hostname, for example:
http://127.0.0.1:8000
rather than switching between:
http://127.0.0.1:8000
and:
http://localhost:8000
Login page loads but authentication fails
Check the configured guard:
'auth' => [ 'enabled' => true, 'guard' => 'web', ],
The selected guard must exist in the host application's:
config/auth.php
Also verify that the application already has valid users available to that guard.
Command returns "This command is not allowed"
Check:
config/route-commands.php
and verify that the command has been added to:
'allowed_commands' => [ // permitted commands ],
For example:
'allowed_commands' => [ 'cache:clear', 'route:list', 'about', ],
Then clear configuration:
php artisan optimize:clear
route:list Response Error
If the browser reports an error such as:
Unexpected non-whitespace character after JSON
make sure the controller returns Artisan output as plain text:
return response( $output, 200 )->header( 'Content-Type', 'text/plain; charset=UTF-8' );
The frontend should read the response using:
const responseText = await response.text();
Do not use:
const data = await response.json();
for Artisan command output.
Security Model
The package uses two primary security layers:
Route Commands
โ
โผ
Authentication
โ
โผ
Authenticated User
โ
โผ
Command Allowlist
โ
โโโโโโโโโดโโโโโโโโ
โ โ
Allowed Not Allowed
โ โ
โผ โผ
Artisan::call() 403
This is intentionally preferable to simply checking whether a user is logged in.
An authenticated user should only be able to execute commands that the application administrator has explicitly permitted.
Versioning
Route Commands follows semantic versioning.
Example:
v1.0.7
represents the previous stable release.
Authentication and command allowlisting are introduced in:
v1.1.0
The package can therefore be upgraded using:
composer require roshan-dhungana/route-commands:^1.1
Roadmap
Potential future improvements:
- Authorization / role-based command access
- Laravel Gate integration
- Command execution history
- Execution timestamps
- Execution duration
- Success/failure history
- Download command output
- Search commands
- Favorite commands
- Custom command groups
- Configurable dashboard
- Dark/light themes
- AJAX command execution
- Audit logging
- Per-command authorization
- Command execution restrictions by environment
Contributing
Contributions are welcome.
Fork the repository, create a feature branch, make your changes, and submit a pull request.
Create a feature branch:
git checkout -b feature/my-feature
Make your changes and commit:
git add . git commit -m "feat: add my feature"
Push the branch:
git push origin feature/my-feature
Then open a pull request.
License
This package is open-sourced software licensed under the MIT license.
Author
Roshan Dhungana
Laravel / PHP Developer
Useful Links
- Laravel Documentation
- Laravel Package Development
- Composer
- Packagist
- GitHub Repository
Summary
Laravel Route Commands provides a browser-based interface for running controlled Laravel Artisan commands.
The v1.1 architecture is:
Laravel Application
โ
โผ
/route-commands/login
โ
โผ
Laravel Authentication
โ
โผ
Authenticated User
โ
โผ
/route-commands
โ
โผ
CommandController
โ
โผ
Command Allowlist
โ
โโโโโโดโโโโโ
โ โ
Allowed Denied
โ โ
โผ โผ
Command 403
Executor
โ
โผ
Artisan::call()
โ
โผ
Artisan Output
โ
โผ
Browser Terminal
The package is particularly useful for development, internal administration, and controlled server maintenance.
Because it provides access to Artisan command execution, installations should always use authentication and a restrictive command allowlist, especially in production environments.