always-open/laravel-totem
Laravel Totem gives your app a dashboard to manage scheduled tasks: view, create, edit, enable or disable cron entries in the browser, track run history and output, and execute due tasks via an Artisan command instead of relying only on the scheduler.
composer require always-open/laravel-totem, then run php artisan totem:install — it publishes config/totem.php, the migrations and the front-end assets, and runs the migrations that create totem_tasks and totem_task_results.AuthServiceProvider::boot() with Totem::auth(fn ($request) => $request->user()?->isAdmin()) and add your own middleware via config/totem.php./totem (adjust for route_prefix). It enumerates Schedule::events(), so anything already registered in app/Console/Kernel.php or routes/console.php appears with zero extra wiring — that's the first use case: stop grepping for the schedule definition to answer "when does this actually run?"config/totem.php for route_prefix, middleware, enabled and dashboard options; the totem_tasks table for the enable/disable state that silently overrides your code; the totem_task_results table when a run "mysteriously" produced nothing.php artisan totem:assets to publish css/dark.css, and set TOTEM_THEME_STORAGE_KEY=theme if you want the dashboard to follow Filament's theme switcher.Kernel.php/routes/console.php; Totem reads that collection and layers enable/disable state, manual runs and result history on top.totem_tasks with is_active = false and Totem filters the event out of the schedule. Great for stopping a runaway job at 2am; terrible as long-term config, because the state lives in the DB and never appears in code review.->appendOutputTo(...) and keep meaningful console output, or add an explicit $this->line() summary at the end of handle().->everyMinute() with an internal guard) if you want them runnable from the dashboard. There is no separate "ad-hoc command" registry.withoutOverlapping(). The dashboard will happily fire a manual run while cron is mid-flight; the package won't stop you.schedule:run still needs exactly one cron entry somewhere. Totem adds no worker, supervisor or lock beyond what you configure.TOTEM_THEME_STORAGE_KEY=theme the sidebar switcher (Light / Dark / Browser default) writes the same localStorage key Filament uses, so the panel and the scheduler dashboard stay in sync per-user with no custom code.php artisan totem:assets plus php artisan view:clear fixes the overwhelming majority of "the new UI isn't showing up" reports — a stale public/vendor/totem is the usual culprit.layout.blade.php or partials/sidebar.blade.php, the v13.4.0 dark-mode include and switcher markup are not merged in for you. Diff against the README's Dark Mode section or the switcher renders inert/unstyled.TOTEM_THEME_STORAGE_KEY must match the key Filament actually writes. The default is theme; if you customized Filament's key, mirror it or the two switchers will fight over the same preference and flip each other.prefers-color-scheme, so expect a light-then-dark flash on first paint for dark-mode users. That's a server-rendered page with a client-side preference — a cosmetic trade-off, not a bug.totem_tasks against your schedule definition; a task disabled six months ago during an incident is invisible in review and will eventually cause a "why didn't the report run?" ticket.totem_tasks row, leaving a dead toggle behind — clean it up in the same PR.totem_task_results grows forever on busy installs; schedule a pruning job for it as part of setup rather than after the table gets large.Totem::auth() belongs in boot(). A blank page or unexpected 403 usually means the closure isn't registered, middleware order is wrong, or it returns falsy for the active guard.route_prefix or middleware, php artisan route:clear. Config is cached; stale routes point at the old prefix.php artisan schedule:list. Totem reads the same collection, so an empty list means the problem is in your scheduler definition, not the package.How can I help you explore Laravel packages today?