NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Workflows for Laravel

Artisan commands

CommandDoes
workflows:installPublishes config/workflows.php and the eight migrations, then prints the scheduler lines and the subject-registration hint. Refuses (exit 1) when any package table already exists.
workflows:wakeOne wake pass: stale claims, expired leases, lost jobs, due timers/retries/timeouts, condition polls, escalations, schedule triggers. Prints the WakeReport. Schedule every minute.
workflows:pruneForce-deletes ended instances past prune.instances_after (never one with a running child) with their step runs, waits, escalations and effect keys; expired trigger keys; dry-run logs past prune.dry_runs_after. Schedule daily.
workflows:catalogueLists every step type: key, label, side effects, outcomes, needed package, available.
workflows:validate {key?} {--owner-type=} {--owner-id=} {--draft} {--file=}Validates the current version (or the draft with --draft, or the draft when nothing is published) — or, with --file, a definition file. Exits 1 on errors.
workflows:sync {path?} {--owner-type=} {--owner-id=} {--publish} {--dry}Creates, drafts and (with --publish) publishes definitions from *.json files; lists untracked definitions; exits 1 when a file is invalid or failed. --dry writes nothing.
workflows:export {key} {--number=} {--path=} {--owner-type=} {--owner-id=}Writes the current version (or --number) as <path>/<key>.json in the template envelope — the file workflows:sync reads back.
workflows:list {--status=} {--definition=} {--owner-type=} {--owner-id=} {--limit=25}The newest instances: ULID, definition, version, status, current node, started, ended, failure code.
workflows:show {instance} {--json}One instance: status, definition, version, owner and subject as Basename#id, the path, the step log, pending waits and the next escalation. --json prints the detail resource.
workflows:retry {instance}Retries a failed instance (ULID or id).
workflows:cancel {instance} {--reason=}Cancels a running or waiting instance.
make:workflow-step {name}Generates app/Workflows/Steps/<Name>.php: a StepType with the key app.<snake_name>, a label, side effects on and a configSchema() written with ConfigSchema.
workflows:doctor {--json} {--strict}Checks the installation and the running system; exits 1 on a failure, and on a warning too under --strict. --json prints [{level, check, message}].
php artisan workflows:list --status=failed --definition=purchase-approval
php artisan workflows:show 01JC9W0Z6B2K8Q5D1F3H7M4N0P          # path, step log, waits, next escalation; --json
php artisan workflows:retry 01JC9W0Z6B2K8Q5D1F3H7M4N0P
php artisan workflows:cancel 01JC9W0Z6B2K8Q5D1F3H7M4N0P --reason="withdrawn"
php artisan workflows:catalogue
php artisan workflows:validate purchase-approval --owner-type=team --owner-id=7 --draft
php artisan workflows:doctor --json --strict

Scheduling

Nothing is scheduled automatically:

// routes/console.php
use Illuminate\Support\Facades\Schedule;

Schedule::command('workflows:wake')->everyMinute()->withoutOverlapping(10)->onOneServer();
Schedule::command('workflows:prune')->daily();

From PHP

Workflows::wake(?CarbonInterface $now) runs one pass at $now and returns the WakeReport, and Workflows::prune() the PruneReport (instances, idempotencyKeys, dryRuns) — the same work the commands do.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.