/laravel-actions
Build, refactor, and troubleshoot Laravel Actions using lorisleiva/laravel-actions. Use when implementing reusable action classes (object/controller/job/listener/command), converting service classes/controllers/jobs into actions, orchestrating workflows via faked actions, or
$ npx -y skills add coollabsio/coolify --skill laravel-actions --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/laravel-actions
Context preview
The summary Claude sees to decide when to auto-load this skill.
Build, refactor, and troubleshoot Laravel Actions using lorisleiva/laravel-actions. Use when implementing reusable action classes (object/controller/job/listener/command), converting service classes/controllers/jobs into actions, orchestrating workflows via faked actions, or
SKILL.md
laravel-actions.SKILL.mdname: laravel-actions
description: Build, refactor, and troubleshoot Laravel Actions using lorisleiva/laravel-actions. Use when implementing reusable action classes (object/controller/job/listener/command), converting service classes/controllers/jobs into actions, orchestrating workflows via faked actions, or debugging action entrypoints and wiring.
Laravel Actions or `lorisleiva/laravel-actions`
Overview
Use this skill to implement or update actions based on `lorisleiva/laravel-actions` with consistent structure and predictable testing patterns.
Quick Workflow
1. Confirm the package is installed with `composer show lorisleiva/laravel-actions`. 2. Create or edit an action class that uses `Lorisleiva\Actions\Concerns\AsAction`. 3. Implement `handle(...)` with the core business logic first. 4. Add adapter methods only when needed for the requested entrypoint:
- `asController` (+ route/invokable controller usage)
- `asJob` (+ dispatch)
- `asListener` (+ event listener wiring)
- `asCommand` (+ command signature/description)
5. Add or update tests for the chosen entrypoint. 6. When tests need isolation, use action fakes (`MyAction::fake()`) and assertions (`MyAction::assertDispatched()`).
Base Action Pattern
Use this minimal skeleton and expand only what is needed.
<?php
namespace App\Actions;
use Lorisleiva\Actions\Concerns\AsAction;
class PublishArticle
{
use AsAction;
public function handle(int $articleId): bool
{
return true;
}
}Project Conventions
- Place action classes in `App\Actions` unless an existing domain sub-namespace is already used.
- Use descriptive `VerbNoun` naming (e.g. `PublishArticle`, `SyncVehicleTaxStatus`).
- Keep domain/business logic in `handle(...)`; keep transport and framework concerns in adapter methods (`asController`, `asJob`, `asListener`, `asCommand`).
- Prefer explicit parameter and return types in all action methods.
- Prefer PHPDoc for complex data contracts (e.g. array shapes), not inline comments.
When to Use an Action
- Use an Action when the same use-case needs multiple entrypoints (HTTP, queue, event, CLI) or benefits from first-class orchestration/faking.
- Keep a plain service class when logic is local, single-entrypoint, and unlikely to be reused as an Action.
Entrypoint Patterns
Run as Object
- (prefer method) Use static helper from the trait: `PublishArticle::run($id)`.
- Use make and call handle: `PublishArticle::make()->handle($id)`.
- Call with dependency injection: `app(PublishArticle::class)->handle($id)`.
Run as Controller
- Use route to class (invokable style), e.g. `Route::post('/articles/{id}/publish', PublishArticle::class)`.
- Add `asController(...)` for HTTP-specific adaptation and return a response.
- Add request validation (`rules()` or custom validator hooks) when input comes from HTTP.
Run as Job
- Dispatch with `PublishArticle::dispatch($id)`.
- Use `asJob(...)` only for queue-specific behavior; keep domain logic in `handle(...)`.
- In this project, job Actions often define additional queue lifecycle methods and job properties for retries, uniqueness, and timing control.
Project Pattern: Job Action with Extra Methods
<?php
namespace App\Actions\Demo;
use App\Models\Demo;
use DateTime;
use Lorisleiva\Actions\Concerns\AsAction;
use Lorisleiva\Actions\Decorators\JobDecorator;
class GetDemoData
{
use AsAction;
public int $jobTries = 3;
public int $jobMaxExceptions = 3;
public function getJobRetryUntil(): DateTime
{
return now()->addMinutes(30);
}
public function getJobBackoff(): array
{
return [60, 120];
}
public function getJobUniqueId(Demo $demo): string
{
return $demo->id;
}
public function handle(Demo $demo): void
{
// Core business logic.
}
public function asJob(JobDecorator $job, Demo $demo): void
{
// Queue-specific orchestration and retry behavior.
$this->handle($demo);
}
}Use these members only when needed:
- `$jobTries`: max attempts for the queued execution.
- `$jobMaxExceptions`: max unhandled exceptions before failing.
- `getJobRetryUntil()`: absolute retry deadline.
- `getJobBackoff()`: retry delay strategy per attempt.
- `getJobUniqueId(...)`: deduplication key for unique jobs.
- `asJob(JobDecorator $job, ...)`: access attempt metadata and queue-only branching.
Run as Listener
- Register the action class as listener in `EventServiceProvider`.
- Use `asListener(EventName $event)` and delegate to `handle(...)`.
Run as Command
- Define `$commandSignature` and `$commandDescription` properties.
- Implement `asCommand(Command $command)` and keep console IO in this method only.
- Import `Command` with `use Illuminate\Console\Command;`.
Testing Guidance
Use a two-layer strategy:
1. `handle(...)` tests for business correctness. 2. entrypoint tests (`asController`, `asJob`, `asListener`, `asCommand`) for wiring/orchestration.
Deep Dive: `AsFake` methods (2.x)
Reference: https://www.laravelactions.com/2.x/as-fake.html
Use these methods intentionally based on what you want to prove.
`mock()`
- Replaces the action with a full mock.
- Best when you need strict expectations and argument assertions.
PublishArticle::mock()
->shouldReceive('handle')
->once()
->with(42)
->andReturnTrue();`partialMock()`
- Replaces the action with a partial mock.
- Best when you want to keep most real behavior but stub one expensive/internal method.
PublishArticle::partialMock()
->shouldReceive('fetchRemoteData')
->once()
->andReturn(['ok' => true]);`spy()`
- Replaces the action with a spy.
- Best for post-execution verification ("was called with X") without predefining all expectations.
$spy = PublishArticle::spy()->allows('handle')->andReturnTrue();
// execute code that triggers the actioRead more
name: laravel-actions description: Build, refactor, and troubleshoot Laravel Actions using lorisleiva/laravel-actions. Use when implementing reusable action classes (object/controller/job/listener/command), converting service classes/controllers/jobs into actions, orchestrating workflows via faked actions, or debugging action entrypoints and wiring.
Laravel Actions or `lorisleiva/laravel-actions`
Overview
Use this skill to implement or update actions based on `lorisleiva/laravel-actions` with consistent structure and predictable testing patterns.
Quick Workflow
1. Confirm the package is installed with `composer show lorisleiva/laravel-actions`. 2. Create or edit an action class that uses `Lorisleiva\Actions\Concerns\AsAction`. 3. Implement `handle(...)` with the core business logic first. 4. Add adapter methods only when needed for the requested entrypoint:
- `asController` (+ route/invokable controller usage)
- `asJob` (+ dispatch)
- `asListener` (+ event listener wiring)
- `asCommand` (+ command signature/description)
5. Add or update tests for the chosen entrypoint. 6. When tests need isolation, use action fakes (`MyAction::fake()`) and assertions (`MyAction::assertDispatched()`).
Base Action Pattern
Use this minimal skeleton and expand only what is needed.
<?php
namespace App\Actions;
use Lorisleiva\Actions\Concerns\AsAction;
class PublishArticle
{
use AsAction;
public function handle(int $articleId): bool
{
return true;
}
}Project Conventions
- Place action classes in `App\Actions` unless an existing domain sub-namespace is already used.
- Use descriptive `VerbNoun` naming (e.g. `PublishArticle`, `SyncVehicleTaxStatus`).
- Keep domain/business logic in `handle(...)`; keep transport and framework concerns in adapter methods (`asController`, `asJob`, `asListener`, `asCommand`).
- Prefer explicit parameter and return types in all action methods.
- Prefer PHPDoc for complex data contracts (e.g. array shapes), not inline comments.
When to Use an Action
- Use an Action when the same use-case needs multiple entrypoints (HTTP, queue, event, CLI) or benefits from first-class orchestration/faking.
- Keep a plain service class when logic is local, single-entrypoint, and unlikely to be reused as an Action.
Entrypoint Patterns
Run as Object
- (prefer method) Use static helper from the trait: `PublishArticle::run($id)`.
- Use make and call handle: `PublishArticle::make()->handle($id)`.
- Call with dependency injection: `app(PublishArticle::class)->handle($id)`.
Run as Controller
- Use route to class (invokable style), e.g. `Route::post('/articles/{id}/publish', PublishArticle::class)`.
- Add `asController(...)` for HTTP-specific adaptation and return a response.
- Add request validation (`rules()` or custom validator hooks) when input comes from HTTP.
Run as Job
- Dispatch with `PublishArticle::dispatch($id)`.
- Use `asJob(...)` only for queue-specific behavior; keep domain logic in `handle(...)`.
- In this project, job Actions often define additional queue lifecycle methods and job properties for retries, uniqueness, and timing control.
Project Pattern: Job Action with Extra Methods
<?php
namespace App\Actions\Demo;
use App\Models\Demo;
use DateTime;
use Lorisleiva\Actions\Concerns\AsAction;
use Lorisleiva\Actions\Decorators\JobDecorator;
class GetDemoData
{
use AsAction;
public int $jobTries = 3;
public int $jobMaxExceptions = 3;
public function getJobRetryUntil(): DateTime
{
return now()->addMinutes(30);
}
public function getJobBackoff(): array
{
return [60, 120];
}
public function getJobUniqueId(Demo $demo): string
{
return $demo->id;
}
public function handle(Demo $demo): void
{
// Core business logic.
}
public function asJob(JobDecorator $job, Demo $demo): void
{
// Queue-specific orchestration and retry behavior.
$this->handle($demo);
}
}Use these members only when needed:
- `$jobTries`: max attempts for the queued execution.
- `$jobMaxExceptions`: max unhandled exceptions before failing.
- `getJobRetryUntil()`: absolute retry deadline.
- `getJobBackoff()`: retry delay strategy per attempt.
- `getJobUniqueId(...)`: deduplication key for unique jobs.
- `asJob(JobDecorator $job, ...)`: access attempt metadata and queue-only branching.
Run as Listener
- Register the action class as listener in `EventServiceProvider`.
- Use `asListener(EventName $event)` and delegate to `handle(...)`.
Run as Command
- Define `$commandSignature` and `$commandDescription` properties.
- Implement `asCommand(Command $command)` and keep console IO in this method only.
- Import `Command` with `use Illuminate\Console\Command;`.
Testing Guidance
Use a two-layer strategy:
1. `handle(...)` tests for business correctness. 2. entrypoint tests (`asController`, `asJob`, `asListener`, `asCommand`) for wiring/orchestration.
Deep Dive: `AsFake` methods (2.x)
Reference: https://www.laravelactions.com/2.x/as-fake.html
Use these methods intentionally based on what you want to prove.
`mock()`
- Replaces the action with a full mock.
- Best when you need strict expectations and argument assertions.
PublishArticle::mock()
->shouldReceive('handle')
->once()
->with(42)
->andReturnTrue();`partialMock()`
- Replaces the action with a partial mock.
- Best when you want to keep most real behavior but stub one expensive/internal method.
PublishArticle::partialMock()
->shouldReceive('fetchRemoteData')
->once()
->andReturn(['ok' => true]);`spy()`
- Replaces the action with a spy.
- Best for post-execution verification ("was called with X") without predefining all expectations.
$spy = PublishArticle::spy()->allows('handle')->andReturnTrue();
// execute code that triggers the actioAn open-source & self-hostable Heroku / Netlify / Vercel alternative. 
Other skills on coolify.
- /configure-nightwatch
Configures Laravel Nightwatch data collection, sampling rates, filtering rules, and redaction policies. Use when setting up Nightwatch, managing data volume, protecting sensitive data (PII), or optimizing event collection for production workloads.
Open skill - /configuring-horizon
Use this skill whenever the user mentions Horizon by name in a Laravel context. Covers the full Horizon lifecycle: installing Horizon (horizon:install, Sail setup), configuring config/horizon.php (supervisor blocks, queue assignments, balancing strategies,
Open skill - /debugging-output-and-previewing-html-using-ray
Use when user says "send to Ray," "show in Ray," "debug in Ray," "log to Ray," "display in Ray," or wants to visualize data, debug output, or show diagrams in the Ray desktop application.
Open skill - /fortify-development
ACTIVATE when the user works on authentication in Laravel. This includes login, registration, password reset, email verification, two-factor authentication (2FA/TOTP/QR codes/recovery codes), passkeys, profile updates, password confirmation, or any auth-related routes and
Open skill - /laravel-best-practices
Apply this skill whenever writing, reviewing, or refactoring Laravel PHP code. This includes creating or modifying controllers, models, migrations, form requests, policies, jobs, scheduled commands, service classes, and Eloquent queries. Triggers for N+1 and query performance
Open skill - /livewire-development
Use for any task or question involving Livewire. Activate if user mentions Livewire, wire: directives, or Livewire-specific concepts like wire:model, wire:click, invoke this skill. Covers building new components, debugging reactivity issues, real-time form validation, loading
Open skill

