npx agentspec-cli install ad6a68fe-87bf-4379-92cd-e086256d245b --file-type gemini-md→ GEMINI.md
<laravel-boost-guidelines>
=== .ai/team-conventions rules ===
## Developer Team Guidelines
The developer team is very small - just four people. So we have developed some guidelines to help us work together.
### Code Style
We follow the laravel conventions for code style and use `pint` to enforce them.
We keep our code *simple* and *readable* and we try to avoid complex or clever code.
We like our code to be able to be read aloud and make sense to a business stakeholder (where possible).
We like readable helper methods and laravel policies to help keep code simple and readable. For example:
```php
// avoid code like this
if ($user->is_admin && $user->id == $project->user_id) {
// do something
}
// prefer this
if ($user->can('edit', $project)) {
// do something
}
```
We **never** use raw SQL or the DB facade in our code. We **always** use the eloquent ORM and relationships.
Our applications are important but do not contain a lot of data. So we do not worry too much about micro-optimizations of database queries. In 99.9999% of cases doing something like `User::orderBy('surname')->get()` is fine - no need to filter/select on specific columns just to save a 100th of a millisecond.
We like early returns and guard clauses. Avoid nesting if statements or using `else` whereever possible.
### Seeding data for local development
When developing locally, we use a seeder called 'TestDataSeeder' to seed the database with data. This avoids any potential issues with running laravel's default seeder by accident.
So if you have created/modified a model or factory, please check that seeder file matches your changes.
### Eloquent model class conventions
We have a rough convention for the order of functionality in our Eloquent models. This is :
1. Model boilerplate (eg, the $fillable array)
2. Lifecycle methods (eg, using the booted method to do some extra work)
3. Relationships
4. Scopes
5. Accessors/Mutators
6. Custom methods
This convention makes it much easier to navigate the code and find the methods you are looking for.
Also note that we like 'fat models' - helper methods, methods that make the main logic read more naturally - are all fine to put on the model. Do not abstract to service classes without checking with the user first. And if there are not existing service classes in the application **NEVER** introduce them unless given explicit permission by the user.
### Livewire component class conventions
Our conventions for livewire components are:
1. Properties and attributes at the top
1.1. Any properties which are used as filters/search or active-tab parameters in the component should use the `#[Url]` livewire attribute
2. The mount() method followed by the render() method
3. Any lifecycle methods (such as updatedFoo()) next
4. Any custom methods after all that.
### Mail notifications
We always use queued mail notifications and we always use the --markdown versions for the templates. Our conventions is to use the 'emails' folder, eg `artisan make:mail SomethingHappened --markdown=emails.something-happened.blade.php`
### Testing style
We like feature tests and rarely write unit.
We always test the full side-effects and happy/unhappy paths of our code. For example, a call to a method that will create a new record and send an email notification if validation passes - we would make sure in the test that if invalid data is passed we do not create the record or send the email. Not just test that we got a validation error.
We also test that our code does not do other things that we did not expect it to do - for example, if we are testing a method which deletes a record, we would test that just that one record was deleted, not the whole collection.
We always test the existence of records using the related Eloquent model - not just doing raw database assertions. This helps catch cases where a relation is doing some extra work or should have had a side-effect.
We like our tests to be readable and easy to understand. We always follow the 'Arrange, Act, Assert' pattern.
We like to use helpful variable names in tests. For example we might have '$userWithProject' and '$userWithoutProject' to help us understand what is going on in the assertions.
When writing tests and you are getting unexpected results with assertSee or assertDontSee - consider that it might be that Laravels exception page is showing the values in the stack trace or contextual debug into. Do a quick sanity check using an assertStatus() call or assertHasNoErrors(). If that doesn't help **ask the user for help**. They can visit the page in the browser and tell you exactly what is happening and even provide you a screenshot.
Note: if you are running the whole test suite, you can use the `--compact` flag. It will still show you the full output for any failures, but will save you having to fill up your context window with all the passing test names.
### UI styling
We use the FluxUI component library for our UI and Livewire/AlpineJS for interactivity.
Always check with the laravel boost MCP tool for flux documentation.
Do not add css classes to components for visual styleing - only for spacing/alignment/positioning. Flux has it's own styling so anything that is added will make the component look out of place. Follow the flux conventions. Again - the laravel boost tool is your helper here.
Flux uses tailwindcss for styling and also uses it's css reset. Make sure that anything 'clickable' has a cursor-pointer class added to it.
Always use the appropriate flux components instead of just <p> and <a> tags. Eg:
```blade
<flux:text>Hello</flux:text>
<flux:link :href="route('home')">Home</flux:link>
```
### If in doubt...
The user us always happy to help you out. Ask questions before you add new logic or change existing code.
Most of our applications have been running in production for a long time, so there are all sorts of edge cases, features that were added, then removed, the re-added with a tweak, etc. Legacy code is a minefield - so lean on the user.
If you are having a problem with a test passing - don't just keep adding code or 'hide' the problem with try/catch etc. Ask the user for help. They will 100x prefer to be asked a question and involved in the decision than have lots of new, weird code to debug that might be hiding critical issues.
### The most important thing
Simplicity and readability of the code. If you read the code and you can't imagine saying it out loud - then we consider it bad code.
### Use of lando
We use lando for local development - but we also have functional local development environments. You can run laravel/artisan commands directly without using lando. The only thing that requires lando is interrogating the local development database - which is much better done using dump() or dd() calls in code/tests. The user will be very suspicious if you try and mess with their development database.
### Notes from your past self
• Future-me, read this before you touch the keyboard
- Start with the most obvious solution that satisfies the spec; don’t add guards, double-up "just in case" validation, or abstractions unless the user explicitly asks.
- Respect the existing guarantees in the stack (Laravel validation, Blade escaping, etc.)—don’t re-implement or double-check them “just in case.”
- In **ALL CASES**, simplicity beats “clever” logic every time.
- If a requirement says “simple,” take it literally. No defensive programming unless requested.
- For ambiguous cases, ask. THIS IS CRITICAL TO THE USER.
- Do not use the users name or the names of anyone in documents you read. Your chats with the user are logged to disk so we do not want to leak PII. Just refer to the user as 'you', or 'stakeholders', 'the person who requested the feature', etc
### Final inspiring quote
"Simplicity is the ultimate sophistication."
=== 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.10
- laravel/framework (LARAVEL) - v12
- laravel/prompts (PROMPTS) - v0
- laravel/sanctum (SANCTUM) - v4
- laravel/socialite (SOCIALITE) - v5
- livewire/flux (FLUXUI_FREE) - v2
- livewire/flux-pro (FLUXUI_PRO) - v2
- livewire/livewire (LIVEWIRE) - v3
- laravel/mcp (MCP) - v0
- laravel/pint (PINT) - v1
- laravel/sail (SAIL) - v1
- pestphp/pest (PEST) - v4
- 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/v12 rules ===
## Laravel 12
- 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 12 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.
=== fluxui-pro/core rules ===
## Flux UI Pro
- This project is using the Pro version of Flux UI. It has full access to the free components and variants, as well as full access to the Pro components and variants.
- Flux UI is a component library for Livewire. Flux is a robust, hand-crafted, UI component library for your Livewire applications. It's built using Tailwind CSS and provides a set of components that are easy to use and customize.
- You should use Flux UI components when available.
- Fallback to standard Blade components if Flux is unavailable.
- If available, use Laravel Boost's `search-docs` tool to get the exact documentation and code snippets available for this project.
- Flux UI components look like this:
<code-snippet name="Flux UI component usage example" lang="blade">
<flux:button variant="primary"/>
</code-snippet>
### Available Components
This is correct as of Boost installation, but there may be additional components within the codebase.
<available-flux-components>
accordion, autocomplete, avatar, badge, brand, breadcrumbs, button, calendar, callout, card, chart, checkbox, command, composer, context, date-picker, dropdown, editor, field, file-upload, heading, icon, input, kanban, modal, navbar, otp-input, pagination, pillbox, popover, profile, radio, select, separator, skeleton, slider, switch, table, tabs, text, textarea, time-picker, toast, tooltip
</available-flux-components>
=== livewire/core rules ===
## Livewire Core
- Use the `search-docs` tool to find exact version specific documentation for how to write Livewire & Livewire tests.
- Use the `php artisan make:livewire [Posts\CreatePost]` artisan command to create new components
- State should live on the server, with the UI reflecting it.
- All Livewire requests hit the Laravel backend, they're like regular HTTP requests. Always validate form data, and run authorization checks in Livewire actions.
## Livewire Best Practices
- Livewire components require a single root element.
- Use `wire:loading` and `wire:dirty` for delightful loading states.
- Add `wire:key` in loops:
```blade
@foreach ($items as $item)
<div wire:key="item-{{ $item->id }}">
{{ $item->name }}
</div>
@endforeach
```
- Prefer lifecycle hooks like `mount()`, `updatedFoo()` for initialization and reactive side effects:
<code-snippet name="Lifecycle hook examples" lang="php">
public function mount(User $user) { $this->user = $user; }
public function updatedSearch() { $this->resetPage(); }
</code-snippet>
## Testing Livewire
<code-snippet name="Example Livewire component test" lang="php">
Livewire::test(Counter::class)
->assertSet('count', 0)
->call('increment')
->assertSet('count', 1)
->assertSee(1)
->assertStatus(200);
</code-snippet>
<code-snippet name="Testing a Livewire component exists within a page" lang="php">
$this->get('/posts/create')
->assertSeeLivewire(CreatePost::class);
</code-snippet>
=== livewire/v3 rules ===
## Livewire 3
### Key Changes From Livewire 2
- These things changed in Livewire 2, but may not have been updated in this application. Verify this application's setup to ensure you conform with application conventions.
- Use `wire:model.live` for real-time updates, `wire:model` is now deferred by default.
- Components now use the `App\Livewire` namespace (not `App\Http\Livewire`).
- Use `$this->dispatch()` to dispatch events (not `emit` or `dispatchBrowserEvent`).
- Use the `components.layouts.app` view as the typical layout path (not `layouts.app`).
### New Directives
- `wire:show`, `wire:transition`, `wire:cloak`, `wire:offline`, `wire:target` are available for use. Use the documentation to find usage examples.
### Alpine
- Alpine is now included with Livewire, don't manually include Alpine.js.
- Plugins included with Alpine: persist, intersect, collapse, and focus.
### Lifecycle Hooks
- You can listen for `livewire:init` to hook into Livewire initialization, and `fail.status === 419` for the page expiring:
<code-snippet name="livewire:load example" lang="js">
document.addEventListener('livewire:init', function () {
Livewire.hook('request', ({ fail }) => {
if (fail && fail.status === 419) {
alert('Your session expired');
}
});
Livewire.hook('message.failed', (message, component) => {
console.error(message);
});
});
</code-snippet>
=== 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.
=== pest/core rules ===
## Pest
### Testing
- If you need to verify a feature is working, write or update a Unit / Feature test.
### Pest Tests
- All tests must be written using Pest. Use `php artisan make:test --pest {name}`.
- 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.
- Tests should test all of the happy paths, failure paths, and weird paths.
- Tests live in the `tests/Feature` and `tests/Unit` directories.
- Pest tests look and behave like this:
<code-snippet name="Basic Pest Test Example" lang="php">
it('is true', function () {
expect(true)->toBeTrue();
});
</code-snippet>
### Running Tests
- Run the minimal number of tests using an appropriate filter before finalizing code edits.
- 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).
- When the tests relating to your changes are passing, ask the user if they would like to run the entire test suite to ensure everything is still passing.
### Pest Assertions
- When asserting status codes on a response, use the specific method like `assertForbidden` and `assertNotFound` instead of using `assertStatus(403)` or similar, e.g.:
<code-snippet name="Pest Example Asserting postJson Response" lang="php">
it('returns all', function () {
$response = $this->postJson('/api/docs', []);
$response->assertSuccessful();
});
</code-snippet>
### Mocking
- Mocking can be very helpful when appropriate.
- When mocking, you can use the `Pest\Laravel\mock` Pest function, but always import it via `use function Pest\Laravel\mock;` before using it. Alternatively, you can use `$this->mock()` if existing tests do.
- You can also create partial mocks using the same import or self method.
### Datasets
- Use datasets in Pest to simplify tests which have a lot of duplicated data. This is often the case when testing validation rules, so consider going with this solution when writing tests for validation rules.
<code-snippet name="Pest Dataset Example" lang="php">
it('has emails', function (string $email) {
expect($email)->not->toBeEmpty();
})->with([
'james' => 'james@laravel.com',
'taylor' => 'taylor@laravel.com',
]);
</code-snippet>
=== pest/v4 rules ===
## Pest 4
- Pest v4 is a huge upgrade to Pest and offers: browser testing, smoke testing, visual regression testing, test sharding, and faster type coverage.
- Browser testing is incredibly powerful and useful for this project.
- Browser tests should live in `tests/Browser/`.
- Use the `search-docs` tool for detailed guidance on utilizing these features.
### Browser Testing
- You can use Laravel features like `Event::fake()`, `assertAuthenticated()`, and model factories within Pest v4 browser tests, as well as `RefreshDatabase` (when needed) to ensure a clean state for each test.
- Interact with the page (click, type, scroll, select, submit, drag-and-drop, touch gestures, etc.) when appropriate to complete the test.
- If requested, test on multiple browsers (Chrome, Firefox, Safari).
- If requested, test on different devices and viewports (like iPhone 14 Pro, tablets, or custom breakpoints).
- Switch color schemes (light/dark mode) when appropriate.
- Take screenshots or pause tests for debugging when appropriate.
### Example Tests
<code-snippet name="Pest Browser Test Example" lang="php">
it('may reset the password', function () {
Notification::fake();
$this->actingAs(User::factory()->create());
$page = visit('/sign-in'); // Visit on a real browser...
$page->assertSee('Sign In')
->assertNoJavascriptErrors() // or ->assertNoConsoleLogs()
->click('Forgot Password?')
->fill('email', 'nuno@laravel.com')
->click('Send Reset Link')
->assertSee('We have emailed your password reset link!')
Notification::assertSent(ResetPassword::class);
});
</code-snippet>
<code-snippet name="Pest Smoke Testing Example" lang="php">
$pages = visit(['/', '/about', '/contact']);
$pages->assertNoJavascriptErrors()->assertNoConsoleLogs();
</code-snippet>
</laravel-boost-guidelines>
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.
by AgentHub Crawler
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.
by AgentHub Crawler
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.
by AgentHub Crawler
Sign in to leave a comment.
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.
by AgentHub Crawler