The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to enhance the user's satisfaction building Laravel applications.
php artisan boost:add-skill mrsuner/laravel-api-boilerplate
Save this content to: AGENTS.md
<laravel-boost-guidelines>
=== foundation rules ===
# Laravel Boost Guidelines
The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to enhance the user's satisfaction building Laravel applications.
## Foundational Context
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
- php - 8.4.27
- laravel/framework (LARAVEL) - v13
- laravel/prompts (PROMPTS) - v0
- laravel/sanctum (SANCTUM) - v4
- laravel/socialite (SOCIALITE) - v5
- laravel/mcp (MCP) - v1
- laravel/pint (PINT) - v1
- laravel/sail (SAIL) - v1
- phpunit/phpunit (PHPUNIT) - v12
## Conventions
- You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, naming.
- Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`.
- Check for existing components to reuse before writing a new one.
## Verification Scripts
- Do not create verification scripts or tinker when tests cover that functionality and prove it works. Unit and feature tests are more important.
## Application Structure & Architecture
- Stick to existing directory structure - don't create new base folders without approval.
- Do not change the application's dependencies without approval.
## Frontend Bundling
- If the user doesn't see a frontend change reflected in the UI, it could mean they need to run `npm run build`, `npm run dev`, or `composer run dev`. Ask them.
## Replies
- Be concise in your explanations - focus on what's important rather than explaining obvious details.
## Documentation Files
- You must only create documentation files if explicitly requested by the user.
=== boost rules ===
## Laravel Boost
- Laravel Boost is an MCP server that comes with powerful tools designed specifically for this application. Use them.
## Artisan
- Use the `list-artisan-commands` tool when you need to call an Artisan command to double check the available parameters.
## URLs
- Whenever you share a project URL with the user you should use the `get-absolute-url` tool to ensure you're using the correct scheme, domain / IP, and port.
## Tinker / Debugging
- You should use the `tinker` tool when you need to execute PHP to debug code or query Eloquent models directly.
- Use the `database-query` tool when you only need to read from the database.
## Reading Browser Logs With the `browser-logs` Tool
- You can read browser logs, errors, and exceptions using the `browser-logs` tool from Boost.
- Only recent browser logs will be useful - ignore old logs.
## Searching Documentation (Critically Important)
- Boost comes with a powerful `search-docs` tool you should use before any other approaches. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation specific for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages.
- The 'search-docs' tool is perfect for all Laravel related packages, including Laravel, Inertia, Livewire, Filament, Tailwind, Pest, Nova, Nightwatch, etc.
- You must use this tool to search for Laravel-ecosystem documentation before falling back to other approaches.
- Search the documentation before making code changes to ensure we are taking the correct approach.
- Use multiple, broad, simple, topic based queries to start. For example: `['rate limiting', 'routing rate limiting', 'routing']`.
- Do not add package names to queries - package information is already shared. For example, use `test resource table`, not `filament 4 test resource table`.
### Available Search Syntax
- You can and should pass multiple queries at once. The most relevant results will be returned first.
1. Simple Word Searches with auto-stemming - query=authentication - finds 'authenticate' and 'auth'
2. Multiple Words (AND Logic) - query=rate limit - finds knowledge containing both "rate" AND "limit"
3. Quoted Phrases (Exact Position) - query="infinite scroll" - Words must be adjacent and in that order
4. Mixed Queries - query=middleware "rate limit" - "middleware" AND exact phrase "rate limit"
5. Multiple Queries - queries=["authentication", "middleware"] - ANY of these terms
=== php rules ===
## PHP
- Always use curly braces for control structures, even if it has one line.
### Constructors
- Use PHP 8 constructor property promotion in `__construct()`.
- <code-snippet>public function __construct(public GitHub $github) { }</code-snippet>
- Do not allow empty `__construct()` methods with zero parameters.
### Type Declarations
- Always use explicit return type declarations for methods and functions.
- Use appropriate PHP type hints for method parameters.
<code-snippet name="Explicit Return Types and Method Params" lang="php">
protected function isAccessible(User $user, ?string $path = null): bool
{
...
}
</code-snippet>
## Comments
- Prefer PHPDoc blocks over comments. Never use comments within the code itself unless there is something _very_ complex going on.
## PHPDoc Blocks
- Add useful array shape type definitions for arrays when appropriate.
## Enums
- Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`.
=== tests rules ===
## Test Enforcement
- Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass.
- Run the minimum number of tests needed to ensure code quality and speed. Use `php artisan test` with a specific filename or filter.
=== laravel/core rules ===
## Do Things the Laravel Way
- Use `php artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using the `list-artisan-commands` tool.
- If you're creating a generic PHP class, use `php artisan make:class`.
- Pass `--no-interaction` to all Artisan commands to ensure they work without user input. You should also pass the correct `--options` to ensure correct behavior.
### Database
- Always use proper Eloquent relationship methods with return type hints. Prefer relationship methods over raw queries or manual joins.
- Use Eloquent models and relationships before suggesting raw database queries
- Avoid `DB::`; prefer `Model::query()`. Generate code that leverages Laravel's ORM capabilities rather than bypassing them.
- Generate code that prevents N+1 query problems by using eager loading.
- Use Laravel's query builder for very complex database operations.
### Model Creation
- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `php artisan make:model`.
### APIs & Eloquent Resources
- For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention.
### Controllers & Validation
- Always create Form Request classes for validation rather than inline validation in controllers. Include both validation rules and custom error messages.
- Check sibling Form Requests to see if the application uses array or string based validation rules.
### Queues
- Use queued jobs for time-consuming operations with the `ShouldQueue` interface.
### Authentication & Authorization
- Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.).
### URL Generation
- When generating links to other pages, prefer named routes and the `route()` function.
### Configuration
- Use environment variables only in configuration files - never use the `env()` function directly outside of config files. Always use `config('app.name')`, not `env('APP_NAME')`.
### Testing
- When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model.
- Faker: Use methods such as `$this->faker->word()` or `fake()->randomDigit()`. Follow existing conventions whether to use `$this->faker` or `fake()`.
- When creating tests, make use of `php artisan make:test [options] {name}` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests.
### Vite Error
- If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `npm run build` or ask the user to run `npm run dev` or `composer run dev`.
=== laravel/v13 rules ===
## Laravel 13
- Use the `search-docs` tool to get version specific documentation.
- Since Laravel 11, Laravel has a new streamlined file structure which this project uses.
### Laravel 13 Structure
- No middleware files in `app/Http/Middleware/`.
- `bootstrap/app.php` is the file to register middleware, exceptions, and routing files.
- `bootstrap/providers.php` contains application specific service providers.
- **No app\Console\Kernel.php** - use `bootstrap/app.php` or `routes/console.php` for console configuration.
- **Commands auto-register** - files in `app/Console/Commands/` are automatically available and do not require manual registration.
### Database
- When modifying a column, the migration must include all of the attributes that were previously defined on the column. Otherwise, they will be dropped and lost.
- Laravel 11 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`.
### Models
- Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing conventions from other models.
=== pint/core rules ===
## Laravel Pint Code Formatter
- You must run `vendor/bin/pint --dirty` before finalizing changes to ensure your code matches the project's expected style.
- Do not run `vendor/bin/pint --test`, simply run `vendor/bin/pint` to fix any formatting issues.
=== phpunit/core rules ===
## PHPUnit Core
- This application uses PHPUnit for testing. All tests must be written as PHPUnit classes. Use `php artisan make:test --phpunit {name}` to create a new test.
- If you see a test using "Pest", convert it to PHPUnit.
- Every time a test has been updated, run that singular test.
- When the tests relating to your feature are passing, ask the user if they would like to also run the entire test suite to make sure everything is still passing.
- Tests should test all of the happy paths, failure paths, and weird paths.
- You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files, these are core to the application.
### Running Tests
- Run the minimal number of tests, using an appropriate filter, before finalizing.
- To run all tests: `php artisan test`.
- To run all tests in a file: `php artisan test tests/Feature/ExampleTest.php`.
- To filter on a particular test name: `php artisan test --filter=testName` (recommended after making a change to a related file).
=== project/boilerplate rules ===
## Boilerplate Architecture
- This project is an API-first Laravel boilerplate. Prefer small, explicit HTTP controllers, domain-oriented services, Form Requests, API Resources, model factories, and PHPUnit tests.
- Follow the existing folder structure before introducing new base folders. Do not add new architectural layers such as `Actions`, `UseCases`, `DTOs`, or `Repositories` unless the existing code or the user explicitly calls for them.
- Existing project structure overrides generic Laravel skeleton assumptions. For example, this project currently uses `app/Http/Middleware/`; do not remove or avoid it only because a generic Laravel 12 guideline says middleware may be registered differently.
## Organization Structure
- HTTP controllers live under:
- `App\Http\Controllers\Api` for versioned client API endpoints.
- `App\Http\Controllers\Api\Auth` for app/web/social authentication flows.
- `App\Http\Controllers\Api\Me` for authenticated current-user resources.
- `App\Http\Controllers\Admin` for internal admin endpoints.
- Form Requests live under `App\Http\Requests\{Domain}` and should mirror the feature domain, such as `Auth`, `Admin`, `Files`, `Devices`, or `Me`.
- API Resources live under `App\Http\Resources` or `App\Http\Resources\Admin` when the response shape is admin-specific.
- Services live under `App\Services\{Domain}`. Service contracts live under `App\Services\{Domain}\Contracts` only when there are multiple implementations or container binding is useful.
- Domain-specific jobs, listeners, mail, notifications, enums, factories, and seeders should follow existing sibling patterns and naming.
## Controller Rules
- Controllers should stay thin and focus on HTTP concerns:
- Authorize/authenticate the request.
- Accept validated input through Form Request classes.
- Delegate reusable or multi-step business workflows to services.
- Return responses through existing response helpers and API Resources.
- Do not put reusable business workflows, multi-model writes, external service coordination, or transaction-heavy logic directly in controllers.
- Prefer constructor injection for controller dependencies:
- `public function __construct(private readonly FileService $files) {}`
- Use route model binding when appropriate, but keep ownership and authorization checks explicit.
- Use existing response helper methods such as `respondOk`, `respondCreated`, `respondNoContent`, `respondPaginated`, `respondError`, and `respondNotFound` when available.
## Service Rules
- Services should represent domain workflows, not HTTP request handling.
- Service namespace pattern:
- `App\Services\Files\FileService`
- `App\Services\Otp\DatabaseDriver`
- `App\Services\Otp\Contracts\OtpService`
- Services should accept models, scalar values, value arrays, or framework objects that are appropriate for the domain. Avoid passing `Request` objects into services.
- Services should return models, collections, DTO-like arrays, booleans, or void depending on the operation. They should not return `JsonResponse`.
- Keep model-local state transitions on the model when the behavior only affects that model, such as `File::claim()`. Put cross-model or cross-system workflows in a service.
- Bind interfaces in a service provider when multiple implementations exist or config selects an implementation.
## Database Transactions
- Use `DB::transaction()` for workflows that must commit or roll back as one unit, especially when:
- Creating or updating multiple related models.
- Combining model writes with role/token changes.
- Claiming uploaded files while creating a parent record.
- Writing audit logs that must match the business mutation.
- `DB::transaction()` is an acceptable exception to the general "avoid `DB::`" rule. Keep the actual reads/writes inside the transaction using Eloquent models and relationships where possible.
- Prefer placing transactions in the service layer, not the controller, when the transaction protects business invariants.
- Do not include slow external I/O inside a transaction, such as HTTP calls, file uploads, mail delivery, notifications, or queue work.
- When dispatching jobs, events, notifications, or mailables related to data created inside a transaction, prefer after-commit behavior or dispatch after the transaction has committed.
- Let exceptions bubble out of the transaction unless a domain-specific error response is required at the controller boundary.
## Testing Expectations
- Every new or changed controller endpoint must have a matching Feature test under `tests/Feature/{Domain}`.
- Controller Feature tests should cover:
- Happy path response status and JSON shape.
- Validation failure through the Form Request.
- Authentication and authorization failure.
- Important config-disabled or feature-flag branches.
- Database side effects and absence of sensitive fields.
- Every new or changed service must have focused tests.
- Use `tests/Unit/{Domain}` for pure services that can be tested without booting the Laravel application, database, filesystem, cache, or queue.
- Use `tests/Feature/Services/{Domain}` when the service depends on Laravel infrastructure such as Eloquent, database transactions, cache, storage, events, or container bindings.
- Prefer factories and Laravel fakes such as `Storage::fake()`, `Mail::fake()`, `Notification::fake()`, `Queue::fake()`, and `Event::fake()` over hand-rolled test doubles.
- After adding or updating a controller, run the related feature test file.
- After adding or updating a service, run the related unit or service feature test file.
- Always run `vendor/bin/pint --dirty` before finalizing code changes.
</laravel-boost-guidelines>
The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to enhance the user's satisfaction building Laravel applications.
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
isRegisteredForDiscounts, not discount().npm run build, npm run dev, or composer run dev. Ask them.=== boost rules ===
list-artisan-commands tool when you need to call an Artisan command to double check the available parameters.get-absolute-url tool to ensure you're using the correct scheme, domain / IP, and port.tinker tool when you need to execute PHP to debug code or query Eloquent models directly.database-query tool when you only need to read from the database.browser-logs Toolbrowser-logs tool from Boost.search-docs tool you should use before any other approaches. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation specific for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages.['rate limiting', 'routing rate limiting', 'routing'].test resource table, not filament 4 test resource table.=== php rules ===
__construct().
__construct() methods with zero parameters.FavoritePerson, BestLake, Monthly.=== tests rules ===
php artisan test with a specific filename or filter.=== laravel/core rules ===
php artisan make: commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using the list-artisan-commands tool.php artisan make:class.--no-interaction to all Artisan commands to ensure they work without user input. You should also pass the correct --options to ensure correct behavior.DB::; prefer Model::query(). Generate code that leverages Laravel's ORM capabilities rather than bypassing them.list-artisan-commands to check the available options to php artisan make:model.ShouldQueue interface.route() function.env() function directly outside of config files. Always use config('app.name'), not env('APP_NAME').$this->faker->word() or fake()->randomDigit(). Follow existing conventions whether to use $this->faker or fake().php artisan make:test [options] {name} to create a feature test, and pass --unit to create a unit test. Most tests should be feature tests.npm run build or ask the user to run npm run dev or composer run dev.=== laravel/v13 rules ===
search-docs tool to get version specific documentation.app/Http/Middleware/.bootstrap/app.php is the file to register middleware, exceptions, and routing files.bootstrap/providers.php contains application specific service providers.bootstrap/app.php or routes/console.php for console configuration.app/Console/Commands/ are automatically available and do not require manual registration.$query->latest()->limit(10);.casts() method on a model rather than the $casts property. Follow existing conventions from other models.=== pint/core rules ===
vendor/bin/pint --dirty before finalizing changes to ensure your code matches the project's expected style.vendor/bin/pint --test, simply run vendor/bin/pint to fix any formatting issues.=== phpunit/core rules ===
php artisan make:test --phpunit {name} to create a new test.php artisan test.php artisan test tests/Feature/ExampleTest.php.php artisan test --filter=testName (recommended after making a change to a related file).=== project/boilerplate rules ===
Actions, UseCases, DTOs, or Repositories unless the existing code or the user explicitly calls for them.app/Http/Middleware/; do not remove or avoid it only because a generic Laravel 12 guideline says middleware may be registered differently.App\Http\Controllers\Api for versioned client API endpoints.App\Http\Controllers\Api\Auth for app/web/social authentication flows.App\Http\Controllers\Api\Me for authenticated current-user resources.App\Http\Controllers\Admin for internal admin endpoints.App\Http\Requests\{Domain} and should mirror the feature domain, such as Auth, Admin, Files, Devices, or Me.App\Http\Resources or App\Http\Resources\Admin when the response shape is admin-specific.App\Services\{Domain}. Service contracts live under App\Services\{Domain}\Contracts only when there are multiple implementations or container binding is useful.public function __construct(private readonly FileService $files) {}respondOk, respondCreated, respondNoContent, respondPaginated, respondError, and respondNotFound when available.App\Services\Files\FileServiceApp\Services\Otp\DatabaseDriverApp\Services\Otp\Contracts\OtpServiceRequest objects into services.JsonResponse.File::claim(). Put cross-model or cross-system workflows in a service.DB::transaction() for workflows that must commit or roll back as one unit, especially when:
DB::transaction() is an acceptable exception to the general "avoid DB::" rule. Keep the actual reads/writes inside the transaction using Eloquent models and relationships where possible.tests/Feature/{Domain}.tests/Unit/{Domain} for pure services that can be tested without booting the Laravel application, database, filesystem, cache, or queue.tests/Feature/Services/{Domain} when the service depends on Laravel infrastructure such as Eloquent, database transactions, cache, storage, events, or container bindings.Storage::fake(), Mail::fake(), Notification::fake(), Queue::fake(), and Event::fake() over hand-rolled test doubles.vendor/bin/pint --dirty before finalizing code changes.
How can I help you explore Laravel packages today?