PHPackages                             farsi/nova-command-center - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [CLI &amp; Console](/categories/cli)
4. /
5. farsi/nova-command-center

ActiveLibrary[CLI &amp; Console](/categories/cli)

farsi/nova-command-center
=========================

A secure, modern Laravel Nova tool to run Artisan and shell commands from the Nova dashboard. Compatible with Nova v4 and v5.

v1.2.1(3w ago)8856MITPHPPHP ^8.1CI passing

Since Jul 2Pushed 1mo agoCompare

[ Source](https://github.com/farsidev/nova-command-center)[ Packagist](https://packagist.org/packages/farsi/nova-command-center)[ Docs](https://github.com/farsidev/nova-command-center)[ RSS](/packages/farsi-nova-command-center/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (3)Dependencies (30)Versions (9)Used By (0)

Nova Command Center
===================

[](#nova-command-center)

[![Tests](https://github.com/farsidev/nova-command-center/actions/workflows/tests.yml/badge.svg)](https://github.com/farsidev/nova-command-center/actions/workflows/tests.yml)[![Static Analysis](https://github.com/farsidev/nova-command-center/actions/workflows/static-analysis.yml/badge.svg)](https://github.com/farsidev/nova-command-center/actions/workflows/static-analysis.yml)[![Latest Version](https://camo.githubusercontent.com/e2a5e12701c3608b5fd74a4ef6b543dca98607f5595070a2e5f575b651bad686/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f66617273692f6e6f76612d636f6d6d616e642d63656e7465722e737667)](https://packagist.org/packages/farsi/nova-command-center)[![License](https://camo.githubusercontent.com/3c43af4c0f2fcd8e67303764c574e97fafa93c4ecf14306aab5ce84830c8dc35/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f66617273692f6e6f76612d636f6d6d616e642d63656e7465722e737667)](LICENSE.md)

Run pre-approved Artisan and shell commands directly from your Laravel Nova dashboard — safely. Built for and tested against **Nova v4 and v5**.

This package is a security-first, clean-room reimagining of the command-center idea. It fixes the long-standing problems of earlier tools: shell injection, Nova 5 incompatibility (the [`__ is not defined`](docs/frontend.md#nova-5-and-__-is-not-defined)crash from Nova 5 removing the global JS translation helper), null-value crashes, missing optional variables and the absence of authorization hooks.

[![Command Center](docs/screenshots/command-center.png)](docs/screenshots/command-center.png)

**▶ See it in action** — searching, model-backed variables, confirmation and live output[![Demo](docs/screenshots/demo.gif)](docs/screenshots/demo.gif)

Searchable model variablesStructured command editor[![Model search](docs/screenshots/model-search.png)](docs/screenshots/model-search.png)[![Command editor](docs/screenshots/command-editor.png)](docs/screenshots/command-editor.png)---

Highlights
----------

[](#highlights)

- 🔒 **Injection-proof by design.** User input is never interpolated into a shell string. Commands run through Symfony Process as an argument vector, so a value like `; rm -rf /` is passed as one literal argument and nothing else.
- ✅ **Allow-list only.** Only commands you define in config can run. Free-form commands and shell (`bash`) execution are **off by default**.
- 🧩 **Nova 4 &amp; 5 compatible.** One code path, Laravel Mix build, and a translation shim that survives Nova 5 removing the global `__` helper.
- 🧵 **Sync &amp; queued execution** with live, polled output and progress bars.
- 🛡️ **Authorization** via a gate and optional per-command policies.
- 🕓 **History** without a database migration.
- 🔧 **Variables &amp; flags**, including optional variables and `select` inputs.
- 🚦 **Concurrency control** (`without_overlapping`) and **rate limiting**.
- 🎨 **Polished, responsive UI** that follows Nova's light/dark theme, with live output, copy-to-clipboard and progress bars.

---

Requirements
------------

[](#requirements)

PackageVersionPHP8.1+Laravel10, 11 or 12Laravel Nova4.x or 5.xInstallation
------------

[](#installation)

```
composer require farsi/nova-command-center
```

Register the tool in `app/Providers/NovaServiceProvider.php`:

```
use Farsi\NovaCommandCenter\CommandCenter;

public function tools(): array
{
    return [
        (new CommandCenter)->canSee(function ($request) {
            return $request->user()?->isAdmin() ?? false;
        }),
    ];
}
```

Publish the configuration:

```
php artisan vendor:publish --tag=nova-command-center-config
```

Configuration
-------------

[](#configuration)

All commands live in `config/nova-command-center.php`. A command is keyed by its display name; only `run` is required.

```
'commands' => [

    'Clear Application Cache' => [
        'run' => 'cache:clear',
        'group' => 'Cache',
        'type' => 'warning',
        'help' => 'Flush the application cache.',
    ],

    'Forget Cache Key' => [
        'run' => 'cache:forget {key}',
        'group' => 'Cache',
        'variables' => [
            'key' => [
                'label' => 'Cache key',
                'type' => 'text',
                'required' => true,
                'rules' => ['string', 'max:255'],
            ],
        ],
    ],

    'Run Migrations' => [
        'run' => 'migrate',
        'group' => 'Database',
        'type' => 'danger',
        'flags' => [
            ['label' => 'Force in production', 'flag' => '--force', 'default' => true],
        ],
    ],

],
```

### Command options

[](#command-options)

KeyTypeDescription`run`stringCommand to run. Use `{name}` placeholders for variables.`command_type``artisan`/`bash`Defaults to `artisan`.`group`stringUI grouping.`type`stringButton style: `primary`, `danger`, `warning`, …`help`stringDescription shown under the command.`timeout`intMax seconds before the process is killed.`output_size`intNumber of trailing output lines to display.`queue`bool / arrayRun on the queue. Array may set `connection` / `queue`.`can`stringGate ability required to run this specific command.`confirm`boolForce/skip the confirmation modal. Default: `danger`/`warning` types confirm, others don't.`variables`arrayUser input, keyed by placeholder name (see below).`flags`arrayOptional flags rendered as checkboxes.### Where commands come from

[](#where-commands-come-from)

By default the allow-list is read from the config file — version-controlled, reviewed in pull requests, and immutable at runtime. This is the recommended, safest posture. The source is pluggable via the `source` key:

```
'source' => [
    'driver' => 'config', // 'config' (default), 'database', or a custom class-string
    'model'  => \Farsi\NovaCommandCenter\Models\Command::class,
],
```

Anything that reads command definitions implements the tiny [`CommandSource`](src/Contracts/CommandSource.php) contract, so raw definitions can come from anywhere. Regardless of the source, every definition still passes through the same coercion, validation and security model — a custom source can never widen the trust boundary or bypass the bash/rate-limit/authorization gates.

```
use Farsi\NovaCommandCenter\Contracts\CommandSource;

final class YamlCommandSource implements CommandSource
{
    public function definitions(): iterable
    {
        return yaml_parse_file(base_path('commands.yaml'));
    }
}

// config/nova-command-center.php
'source' => ['driver' => YamlCommandSource::class],
```

### Managing commands in the database

[](#managing-commands-in-the-database)

Prefer editing commands from the Nova UI instead of a config file? Opt into the database source. **Read the security note first.**

1. Publish and run the migration:

    ```
    php artisan vendor:publish --tag=nova-command-center-migrations
    php artisan migrate
    ```
2. Switch the driver in `config/nova-command-center.php`:

    ```
    'source' => ['driver' => 'database'],
    ```
3. Register the bundled Nova resource from your own `NovaServiceProvider` — ideally behind a strict policy so only trusted operators can edit the allow-list:

    ```
    use Farsi\NovaCommandCenter\Nova\Command;

    Nova::resources([Command::class]);
    ```

Rows in the `nova_command_center_commands` table map one-to-one onto the config keys documented above (`run`, `command_type`, `group`, `variables`, `flags`, …), plus `enabled` (bool) and `position` (int) to toggle and order them.

Variables and flags are edited through structured, repeatable sub-forms — add a variable block, pick its type (`text`, `select` or searchable `model`), fill in labels, options and validation rules as plain inputs, and drag to reorder. No JSON required. See [command sources](docs/command-sources.md) for details.

> ⚠️ **Security:** the database driver moves the allow-list out of version control. Anyone who can create or edit those rows decides what the tool will run — that is remote code execution by design. Protect the resource with a policy (`CommandPolicy`), restrict it to super-admins, keep bash **disabled** unless you truly need it, and remember every run still emits audit events. If you don't need UI-managed commands, stay on the `config` driver.

### Variables

[](#variables)

Variables are referenced in `run` with `{name}` placeholders. Because substitution happens **after** the command is tokenised, a variable can only ever become the content of a single argument — never a new one.

```
'variables' => [
    'email' => [
        'label' => 'User email',
        'type' => 'text',            // 'text', 'select' or 'model'
        'required' => false,         // optional variables are fully supported
        'default' => null,
        'options' => [               // for 'select'
            ['value' => 'daily', 'label' => 'Daily'],
            ['value' => 'weekly', 'label' => 'Weekly'],
        ],
        'rules' => ['email'],        // extra Laravel validation rules
    ],
],
```

An optional variable that is left blank simply removes its placeholder token, so `foo --tag={tag}` becomes `foo` when `tag` is empty.

A `type => 'model'` variable renders as a type-ahead search box backed by a real Eloquent model instead of a plain text input — useful when the argument is a record id picked from a large or dynamic table. Its backing model must be explicitly allow-listed via `searchable_models`, and matching is always case-insensitive regardless of database driver. See "Searchable model variables" in [`docs/configuration.md`](docs/configuration.md) for the full schema and security notes.

### Authorization

[](#authorization)

Every request is checked against the tool's `canSee` callback. In addition, you may define a global gate ability (default `runCommand`) and/or per-command `can`abilities:

```
// AuthServiceProvider
Gate::define('runCommand', fn ($user) => $user->isAdmin());
Gate::define('deploy', fn ($user) => $user->isOwner());
```

```
// config
'authorize' => 'runCommand',
'commands' => [
    'Deploy' => ['run' => 'deploy:run', 'can' => 'deploy'],
],
```

### Shell (bash) commands

[](#shell-bash-commands)

Shell execution is **disabled by default**. When enabled, only allow-listed commands run, and arguments are always escaped. Shell features such as pipes and redirection are intentionally unsupported — wrap those in a script file instead.

```
'bash' => ['enabled' => true],

'commands' => [
    'Disk Usage' => ['run' => 'df -h', 'command_type' => 'bash', 'group' => 'System'],
],
```

### Queued execution &amp; progress bars

[](#queued-execution--progress-bars)

Mark a command as `queue => true` to run it on a worker with live, polled output. To report progress from your own Artisan command, use the provided trait:

```
use Farsi\NovaCommandCenter\Concerns\InteractsWithProgress;

class RebuildSearchIndex extends Command
{
    use InteractsWithProgress;

    public function handle(): int
    {
        $this->novaProgressStart($items->count());

        foreach ($items as $item) {
            // ...
            $this->novaProgressAdvance();
        }

        $this->novaProgressFinish('Done');

        return self::SUCCESS;
    }
}
```

Validate your configuration
---------------------------

[](#validate-your-configuration)

The allow-list is code — lint it like code:

```
php artisan nova-command-center:check
```

The check reports everything that would otherwise fail silently at runtime: a command dropped for having no `run` string, a `{placeholder}` with no matching variable (it would be passed to the process literally), a required select that can never be satisfied, a `model` variable whose class is missing or not allow-listed in `searchable_models`, bash commands while bash is disabled, a per-command `can` ability no gate defines, `without_overlapping` on a cache store that can't lock, and a database source whose migration hasn't run.

It exits non-zero when it finds errors, so it can gate CI. Add `--strict` to fail on warnings too:

```
php artisan nova-command-center:check --strict
```

Events
------

[](#events)

Every execution dispatches `Farsi\NovaCommandCenter\Events\CommandStarted` and `CommandFinished`, each carrying the command definition, the execution result and the operator — handy for audit logging.

Documentation
-------------

[](#documentation)

Deep-dive guides live in [`docs/`](docs/README.md):

- [Configuration](docs/configuration.md) — every config key.
- [Command sources](docs/command-sources.md) — config, database (Nova resource) and custom sources.
- [Security model](docs/security.md) — the full threat model.
- [Authorization](docs/authorization.md) — gate, ability and per-command policies.
- [Queued execution &amp; progress bars](docs/progress-bars.md) — queueing and live progress.
- [Frontend, theming &amp; dark mode](docs/frontend.md) — building and customising the UI.

Security
--------

[](#security)

See [SECURITY.md](SECURITY.md) for the threat model and how to report a vulnerability. In short: allow-list only, no shell interpolation, bash off by default, authorization required, and every value is validated before it runs.

Development
-----------

[](#development)

The frontend is built with Laravel Mix (the build system Nova uses on both v4 and v5):

```
npm install
npm run dev      # or: npm run watch / npm run prod
```

Backend quality tools:

```
composer test      # Pest
composer analyse   # PHPStan
composer lint      # Pint (dry run)
```

> Nova is a paid, private package. Running the test suite locally requires Nova credentials, or the provided `composer.testing.json` scaffold that swaps in a lightweight stub. See [CONTRIBUTING.md](CONTRIBUTING.md).

License
-------

[](#license)

The MIT License. See [LICENSE.md](LICENSE.md).

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance93

Actively maintained with recent releases

Popularity26

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 97.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~5 days

Total

5

Last Release

27d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/90d288522bd317ce5f88a1f746d39bfcfebae03de58b9e8c9881dc776cf8e9f2?d=identicon)[farsi](/maintainers/farsi)

---

Top Contributors

[![aliwesome](https://avatars.githubusercontent.com/u/21131502?v=4)](https://github.com/aliwesome "aliwesome (37 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")

---

Tags

artisancommand-runnerlaravellaravel-novanova-toolphplaravelartisancommandsnovalaravel-novanova-toolcommand-center

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/farsi-nova-command-center/health.svg)

```
[![Health](https://phpackages.com/badges/farsi-nova-command-center/health.svg)](https://phpackages.com/packages/farsi-nova-command-center)
```

###  Alternatives

[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

79227.1M231](/packages/laravel-mcp)[illuminate/queue

The Illuminate Queue package.

20433.0M1.8k](/packages/illuminate-queue)[laravel/ai

The official AI SDK for Laravel.

1.1k4.6M327](/packages/laravel-ai)[laravel/horizon

Dashboard and code-driven configuration for Laravel queues.

4.2k99.8M355](/packages/laravel-horizon)[laravel/sail

Docker files for running a basic Laravel application.

1.9k212.4M1.5k](/packages/laravel-sail)[spatie/laravel-health

Monitor the health of a Laravel application

88212.7M189](/packages/spatie-laravel-health)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
