Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Tomato Artisan Module Laravel Package

tomatophp/tomato-artisan-module

A Tomato PHP module that brings Laravel Artisan into your admin panel, letting you browse and run commands from a web interface instead of the terminal. Integrates with Tomato's modular ecosystem for quick setup and management.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install into a Laravel app that already has Filament set up (TomatoPHP modules are Filament plugins):
    composer require tomatophp/tomato-artisan-module
    
  2. Publish assets/config (tags vary by module; check the package README for the exact tag names — typically config, migrations, translations):
    php artisan vendor:publish --provider="TomatoPHP\TomatoArtisan\TomatoArtisanServiceProvider"
    
  3. Register the plugin on your Filament panel (usually AdminPanelProvider):
    ->plugin(\TomatoPHP\TomatoArtisan\TomatoArtisanPlugin::make())
    
  4. Look first at the generated config/tomato-artisan.php — this is where you control which commands are exposed, whether the module is enabled, and any authorization gates. Then open the module's Filament page/resource to see the default listing of whitelisted commands.

First use case: expose a handful of safe operational commands (e.g. cache:clear, optimize, queue:restart) to admins so they don't need SSH. Add those command names to the config whitelist and verify they run from the panel.

Implementation Patterns

  • Whitelist-only, not wildcard. Keep the config's allowed-commands list explicit and grow it deliberately. Treat every entry as an attack surface until proven safe (idempotent, no destructive args, no interactive prompts).
  • Gate the panel page. Wrap the plugin behind a Filament policy or a Gate::define('run-artisan') check so that only trusted roles see the module. Combine with Filament's ->authorize() on the plugin/resource.
  • Parameter passing. If the UI exposes command arguments, prefer a fixed form of known-safe options over a free-text field. If free text is unavoidable, validate against an allowlist of options and reject anything containing shell metacharacters (;, |, &&, $(), backticks).
  • Long-running commands → jobs. Wrap anything slow (imports, migrate on big schemas, backups) in a queued job dispatched from the Filament action, and poll for output. Don't block the request with Artisan::call() from a web action.
  • Programmatic triggers. Where the module exposes a service or an action class, call it from your own Filament resources or console commands rather than duplicating logic. This is how you reuse the module in scheduled tasks (->everyFiveMinutes() calling the same command registry).
  • Custom command registration. If the module auto-discovers commands, verify your app's own commands appear; otherwise add them via the config list. This is the cleanest integration point with a project-specific toolkit.
  • Audit trail. Pipe every execution through a listener/model so you have who-ran-what-when. The module is a privileged surface; the log is your only forensic trail.

Gotchas and Tips

  • This is a remote-code-execution surface by design. Never enable it on production without auth + authorization + environment guards (e.g. abort_unless(app()->isLocal() || Gate::allows('run-artisan'))). Treat a misconfigured whitelist as a full compromise.
  • Cached command list. Filament/Laravel caches the artisan command list in some flows; newly added commands may not appear until you run php artisan optimize:clear or reload. If a command "doesn't show up," clear caches first.
  • Interactive commands hang. Commands that prompt for confirmation (migrate on production, db:wipe, etc.) will block a web request indefinitely. Exclude them or pass --force/--no-interaction deliberately.
  • Output buffering & streaming. Artisan::output() returns a string, so long output can exceed memory or truncate. If the module streams output, check the chunk/buffer config; otherwise paginate or write to a log file and link it.
  • Shell vs. Artisan facade. If the module shells out (exec, Process), output and exit codes behave differently than Artisan::call() — and shell escaping becomes your responsibility. Prefer the facade where possible.
  • Config cache footgun. Changes to the whitelist in config/tomato-artisan.php won't take effect under config:cache. Run php artisan config:clear in dev; in deploy pipelines cache after editing.
  • Multi-tenant / multi-panel. If you run multiple Filament panels, register the plugin per-panel; don't accidentally expose the artisan page on a customer-facing panel.
  • Extension points. The cleanest way to extend is usually a custom Filament action or a policy gate around the plugin rather than editing vendor files — re-publish config only, and keep overrides in a project service provider so composer updates don't clobber them.
  • Version note. v1.0.0 is the initial tagged release (changelog only, no migration notes). Pin it ("^1.0") and read the source of the execution path once before wiring it into production — the security posture matters more here than in most packages.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager