diff --git a/.agents/skills/pest-testing/SKILL.md b/.agents/skills/pest-testing/SKILL.md new file mode 100644 index 0000000..5619861 --- /dev/null +++ b/.agents/skills/pest-testing/SKILL.md @@ -0,0 +1,167 @@ +--- +name: pest-testing +description: "Tests applications using the Pest 4 PHP framework. Activates when writing tests, creating unit or feature tests, adding assertions, testing Livewire components, browser testing, debugging test failures, working with datasets or mocking; or when the user mentions test, spec, TDD, expects, assertion, coverage, or needs to verify functionality works." +license: MIT +metadata: + author: laravel +--- + +# Pest Testing 4 + +## When to Apply + +Activate this skill when: + +- Creating new tests (unit, feature, or browser) +- Modifying existing tests +- Debugging test failures +- Working with browser testing or smoke testing +- Writing architecture tests or visual regression tests + +## Documentation + +Use `search-docs` for detailed Pest 4 patterns and documentation. + +## Basic Usage + +### Creating Tests + +All tests must be written using Pest. Use `php artisan make:test --pest {name}`. + +### Test Organization + +- Unit/Feature tests: `tests/Feature` and `tests/Unit` directories. +- Browser tests: `tests/Browser/` directory. +- Do NOT remove tests without approval - these are core application code. + +### Basic Test Structure + + +```php +it('is true', function () { + expect(true)->toBeTrue(); +}); +``` + +### Running Tests + +- Run minimal tests with filter before finalizing: `php artisan test --compact --filter=testName`. +- Run all tests: `php artisan test --compact`. +- Run file: `php artisan test --compact tests/Feature/ExampleTest.php`. + +## Assertions + +Use specific assertions (`assertSuccessful()`, `assertNotFound()`) instead of `assertStatus()`: + + +```php +it('returns all', function () { + $this->postJson('/api/docs', [])->assertSuccessful(); +}); +``` + +| Use | Instead of | +|-----|------------| +| `assertSuccessful()` | `assertStatus(200)` | +| `assertNotFound()` | `assertStatus(404)` | +| `assertForbidden()` | `assertStatus(403)` | + +## Mocking + +Import mock function before use: `use function Pest\Laravel\mock;` + +## Datasets + +Use datasets for repetitive tests (validation rules, etc.): + + +```php +it('has emails', function (string $email) { + expect($email)->not->toBeEmpty(); +})->with([ + 'james' => 'james@laravel.com', + 'taylor' => 'taylor@laravel.com', +]); +``` + +## Pest 4 Features + +| Feature | Purpose | +|---------|---------| +| Browser Testing | Full integration tests in real browsers | +| Smoke Testing | Validate multiple pages quickly | +| Visual Regression | Compare screenshots for visual changes | +| Test Sharding | Parallel CI runs | +| Architecture Testing | Enforce code conventions | + +### Browser Test Example + +Browser tests run in real browsers for full integration testing: + +- Browser tests live in `tests/Browser/`. +- Use Laravel features like `Event::fake()`, `assertAuthenticated()`, and model factories. +- Use `RefreshDatabase` for clean state per test. +- Interact with page: click, type, scroll, select, submit, drag-and-drop, touch gestures. +- Test on multiple browsers (Chrome, Firefox, Safari) if requested. +- Test on different devices/viewports (iPhone 14 Pro, tablets) if requested. +- Switch color schemes (light/dark mode) when appropriate. +- Take screenshots or pause tests for debugging. + + +```php +it('may reset the password', function () { + Notification::fake(); + + $this->actingAs(User::factory()->create()); + + $page = visit('/sign-in'); + + $page->assertSee('Sign In') + ->assertNoJavaScriptErrors() + ->click('Forgot Password?') + ->fill('email', 'nuno@laravel.com') + ->click('Send Reset Link') + ->assertSee('We have emailed your password reset link!'); + + Notification::assertSent(ResetPassword::class); +}); +``` + +### Smoke Testing + +Quickly validate multiple pages have no JavaScript errors: + + +```php +$pages = visit(['/', '/about', '/contact']); + +$pages->assertNoJavaScriptErrors()->assertNoConsoleLogs(); +``` + +### Visual Regression Testing + +Capture and compare screenshots to detect visual changes. + +### Test Sharding + +Split tests across parallel processes for faster CI runs. + +### Architecture Testing + +Pest 4 includes architecture testing (from Pest 3): + + +```php +arch('controllers') + ->expect('App\Http\Controllers') + ->toExtendNothing() + ->toHaveSuffix('Controller'); +``` + +## Common Pitfalls + +- Not importing `use function Pest\Laravel\mock;` before using mock +- Using `assertStatus(200)` instead of `assertSuccessful()` +- Forgetting datasets for repetitive validation tests +- Deleting tests without approval +- Forgetting `assertNoJavaScriptErrors()` in browser tests \ No newline at end of file diff --git a/.agents/skills/tailwindcss-development/SKILL.md b/.agents/skills/tailwindcss-development/SKILL.md new file mode 100644 index 0000000..21a7e46 --- /dev/null +++ b/.agents/skills/tailwindcss-development/SKILL.md @@ -0,0 +1,129 @@ +--- +name: tailwindcss-development +description: "Styles applications using Tailwind CSS v4 utilities. Activates when adding styles, restyling components, working with gradients, spacing, layout, flex, grid, responsive design, dark mode, colors, typography, or borders; or when the user mentions CSS, styling, classes, Tailwind, restyle, hero section, cards, buttons, or any visual/UI changes." +license: MIT +metadata: + author: laravel +--- + +# Tailwind CSS Development + +## When to Apply + +Activate this skill when: + +- Adding styles to components or pages +- Working with responsive design +- Implementing dark mode +- Extracting repeated patterns into components +- Debugging spacing or layout issues + +## Documentation + +Use `search-docs` for detailed Tailwind CSS v4 patterns and documentation. + +## Basic Usage + +- Use Tailwind CSS classes to style HTML. Check and follow existing Tailwind conventions in the project before introducing new patterns. +- Offer to extract repeated patterns into components that match the project's conventions (e.g., Blade, JSX, Vue). +- Consider class placement, order, priority, and defaults. Remove redundant classes, add classes to parent or child elements carefully to reduce repetition, and group elements logically. + +## Tailwind CSS v4 Specifics + +- Always use Tailwind CSS v4 and avoid deprecated utilities. +- `corePlugins` is not supported in Tailwind v4. + +### CSS-First Configuration + +In Tailwind v4, configuration is CSS-first using the `@theme` directive — no separate `tailwind.config.js` file is needed: + + +```css +@theme { + --color-brand: oklch(0.72 0.11 178); +} +``` + +### Import Syntax + +In Tailwind v4, import Tailwind with a regular CSS `@import` statement instead of the `@tailwind` directives used in v3: + + +```diff +- @tailwind base; +- @tailwind components; +- @tailwind utilities; ++ @import "tailwindcss"; +``` + +### Replaced Utilities + +Tailwind v4 removed deprecated utilities. Use the replacements shown below. Opacity values remain numeric. + +| Deprecated | Replacement | +|------------|-------------| +| bg-opacity-* | bg-black/* | +| text-opacity-* | text-black/* | +| border-opacity-* | border-black/* | +| divide-opacity-* | divide-black/* | +| ring-opacity-* | ring-black/* | +| placeholder-opacity-* | placeholder-black/* | +| flex-shrink-* | shrink-* | +| flex-grow-* | grow-* | +| overflow-ellipsis | text-ellipsis | +| decoration-slice | box-decoration-slice | +| decoration-clone | box-decoration-clone | + +## Spacing + +Use `gap` utilities instead of margins for spacing between siblings: + + +```html +
+
Item 1
+
Item 2
+
+``` + +## Dark Mode + +If existing pages and components support dark mode, new pages and components must support it the same way, typically using the `dark:` variant: + + +```html +
+ Content adapts to color scheme +
+``` + +## Common Patterns + +### Flexbox Layout + + +```html +
+
Left content
+
Right content
+
+``` + +### Grid Layout + + +```html +
+
Card 1
+
Card 2
+
Card 3
+
+``` + +## Common Pitfalls + +- Using deprecated v3 utilities (bg-opacity-*, flex-shrink-*, etc.) +- Using `@tailwind` directives instead of `@import "tailwindcss"` +- Trying to use `tailwind.config.js` instead of CSS `@theme` directive +- Using margins for spacing between siblings instead of gap utilities +- Forgetting to add dark mode variants when the project uses dark mode \ No newline at end of file diff --git a/.codex/config.toml b/.codex/config.toml new file mode 100644 index 0000000..795d550 --- /dev/null +++ b/.codex/config.toml @@ -0,0 +1,4 @@ +[mcp_servers.laravel-boost] +command = "vendor/bin/sail" +args = ["artisan", "boost:mcp"] +cwd = "/Users/ahmeddarrazi/Documents/projects/TenantAtlas" diff --git a/.github/skills/pest-testing/SKILL.md b/.github/skills/pest-testing/SKILL.md new file mode 100644 index 0000000..5619861 --- /dev/null +++ b/.github/skills/pest-testing/SKILL.md @@ -0,0 +1,167 @@ +--- +name: pest-testing +description: "Tests applications using the Pest 4 PHP framework. Activates when writing tests, creating unit or feature tests, adding assertions, testing Livewire components, browser testing, debugging test failures, working with datasets or mocking; or when the user mentions test, spec, TDD, expects, assertion, coverage, or needs to verify functionality works." +license: MIT +metadata: + author: laravel +--- + +# Pest Testing 4 + +## When to Apply + +Activate this skill when: + +- Creating new tests (unit, feature, or browser) +- Modifying existing tests +- Debugging test failures +- Working with browser testing or smoke testing +- Writing architecture tests or visual regression tests + +## Documentation + +Use `search-docs` for detailed Pest 4 patterns and documentation. + +## Basic Usage + +### Creating Tests + +All tests must be written using Pest. Use `php artisan make:test --pest {name}`. + +### Test Organization + +- Unit/Feature tests: `tests/Feature` and `tests/Unit` directories. +- Browser tests: `tests/Browser/` directory. +- Do NOT remove tests without approval - these are core application code. + +### Basic Test Structure + + +```php +it('is true', function () { + expect(true)->toBeTrue(); +}); +``` + +### Running Tests + +- Run minimal tests with filter before finalizing: `php artisan test --compact --filter=testName`. +- Run all tests: `php artisan test --compact`. +- Run file: `php artisan test --compact tests/Feature/ExampleTest.php`. + +## Assertions + +Use specific assertions (`assertSuccessful()`, `assertNotFound()`) instead of `assertStatus()`: + + +```php +it('returns all', function () { + $this->postJson('/api/docs', [])->assertSuccessful(); +}); +``` + +| Use | Instead of | +|-----|------------| +| `assertSuccessful()` | `assertStatus(200)` | +| `assertNotFound()` | `assertStatus(404)` | +| `assertForbidden()` | `assertStatus(403)` | + +## Mocking + +Import mock function before use: `use function Pest\Laravel\mock;` + +## Datasets + +Use datasets for repetitive tests (validation rules, etc.): + + +```php +it('has emails', function (string $email) { + expect($email)->not->toBeEmpty(); +})->with([ + 'james' => 'james@laravel.com', + 'taylor' => 'taylor@laravel.com', +]); +``` + +## Pest 4 Features + +| Feature | Purpose | +|---------|---------| +| Browser Testing | Full integration tests in real browsers | +| Smoke Testing | Validate multiple pages quickly | +| Visual Regression | Compare screenshots for visual changes | +| Test Sharding | Parallel CI runs | +| Architecture Testing | Enforce code conventions | + +### Browser Test Example + +Browser tests run in real browsers for full integration testing: + +- Browser tests live in `tests/Browser/`. +- Use Laravel features like `Event::fake()`, `assertAuthenticated()`, and model factories. +- Use `RefreshDatabase` for clean state per test. +- Interact with page: click, type, scroll, select, submit, drag-and-drop, touch gestures. +- Test on multiple browsers (Chrome, Firefox, Safari) if requested. +- Test on different devices/viewports (iPhone 14 Pro, tablets) if requested. +- Switch color schemes (light/dark mode) when appropriate. +- Take screenshots or pause tests for debugging. + + +```php +it('may reset the password', function () { + Notification::fake(); + + $this->actingAs(User::factory()->create()); + + $page = visit('/sign-in'); + + $page->assertSee('Sign In') + ->assertNoJavaScriptErrors() + ->click('Forgot Password?') + ->fill('email', 'nuno@laravel.com') + ->click('Send Reset Link') + ->assertSee('We have emailed your password reset link!'); + + Notification::assertSent(ResetPassword::class); +}); +``` + +### Smoke Testing + +Quickly validate multiple pages have no JavaScript errors: + + +```php +$pages = visit(['/', '/about', '/contact']); + +$pages->assertNoJavaScriptErrors()->assertNoConsoleLogs(); +``` + +### Visual Regression Testing + +Capture and compare screenshots to detect visual changes. + +### Test Sharding + +Split tests across parallel processes for faster CI runs. + +### Architecture Testing + +Pest 4 includes architecture testing (from Pest 3): + + +```php +arch('controllers') + ->expect('App\Http\Controllers') + ->toExtendNothing() + ->toHaveSuffix('Controller'); +``` + +## Common Pitfalls + +- Not importing `use function Pest\Laravel\mock;` before using mock +- Using `assertStatus(200)` instead of `assertSuccessful()` +- Forgetting datasets for repetitive validation tests +- Deleting tests without approval +- Forgetting `assertNoJavaScriptErrors()` in browser tests \ No newline at end of file diff --git a/.github/skills/tailwindcss-development/SKILL.md b/.github/skills/tailwindcss-development/SKILL.md new file mode 100644 index 0000000..21a7e46 --- /dev/null +++ b/.github/skills/tailwindcss-development/SKILL.md @@ -0,0 +1,129 @@ +--- +name: tailwindcss-development +description: "Styles applications using Tailwind CSS v4 utilities. Activates when adding styles, restyling components, working with gradients, spacing, layout, flex, grid, responsive design, dark mode, colors, typography, or borders; or when the user mentions CSS, styling, classes, Tailwind, restyle, hero section, cards, buttons, or any visual/UI changes." +license: MIT +metadata: + author: laravel +--- + +# Tailwind CSS Development + +## When to Apply + +Activate this skill when: + +- Adding styles to components or pages +- Working with responsive design +- Implementing dark mode +- Extracting repeated patterns into components +- Debugging spacing or layout issues + +## Documentation + +Use `search-docs` for detailed Tailwind CSS v4 patterns and documentation. + +## Basic Usage + +- Use Tailwind CSS classes to style HTML. Check and follow existing Tailwind conventions in the project before introducing new patterns. +- Offer to extract repeated patterns into components that match the project's conventions (e.g., Blade, JSX, Vue). +- Consider class placement, order, priority, and defaults. Remove redundant classes, add classes to parent or child elements carefully to reduce repetition, and group elements logically. + +## Tailwind CSS v4 Specifics + +- Always use Tailwind CSS v4 and avoid deprecated utilities. +- `corePlugins` is not supported in Tailwind v4. + +### CSS-First Configuration + +In Tailwind v4, configuration is CSS-first using the `@theme` directive — no separate `tailwind.config.js` file is needed: + + +```css +@theme { + --color-brand: oklch(0.72 0.11 178); +} +``` + +### Import Syntax + +In Tailwind v4, import Tailwind with a regular CSS `@import` statement instead of the `@tailwind` directives used in v3: + + +```diff +- @tailwind base; +- @tailwind components; +- @tailwind utilities; ++ @import "tailwindcss"; +``` + +### Replaced Utilities + +Tailwind v4 removed deprecated utilities. Use the replacements shown below. Opacity values remain numeric. + +| Deprecated | Replacement | +|------------|-------------| +| bg-opacity-* | bg-black/* | +| text-opacity-* | text-black/* | +| border-opacity-* | border-black/* | +| divide-opacity-* | divide-black/* | +| ring-opacity-* | ring-black/* | +| placeholder-opacity-* | placeholder-black/* | +| flex-shrink-* | shrink-* | +| flex-grow-* | grow-* | +| overflow-ellipsis | text-ellipsis | +| decoration-slice | box-decoration-slice | +| decoration-clone | box-decoration-clone | + +## Spacing + +Use `gap` utilities instead of margins for spacing between siblings: + + +```html +
+
Item 1
+
Item 2
+
+``` + +## Dark Mode + +If existing pages and components support dark mode, new pages and components must support it the same way, typically using the `dark:` variant: + + +```html +
+ Content adapts to color scheme +
+``` + +## Common Patterns + +### Flexbox Layout + + +```html +
+
Left content
+
Right content
+
+``` + +### Grid Layout + + +```html +
+
Card 1
+
Card 2
+
Card 3
+
+``` + +## Common Pitfalls + +- Using deprecated v3 utilities (bg-opacity-*, flex-shrink-*, etc.) +- Using `@tailwind` directives instead of `@import "tailwindcss"` +- Trying to use `tailwind.config.js` instead of CSS `@theme` directive +- Using margins for spacing between siblings instead of gap utilities +- Forgetting to add dark mode variants when the project uses dark mode \ No newline at end of file diff --git a/Agents.md b/Agents.md index c546c58..539e8b0 100644 --- a/Agents.md +++ b/Agents.md @@ -389,6 +389,7 @@ ## Reference Materials === .ai/filament-v5-blueprint rules === ## Source of Truth + If any Filament behavior is uncertain, lookup the exact section in: - docs/research/filament-v5-notes.md and prefer that over guesses. @@ -398,6 +399,7 @@ # SECTION B — FILAMENT V5 BLUEPRINT (EXECUTABLE RULES) # Filament Blueprint (v5) ## 1) Non-negotiables + - Filament v5 requires Livewire v4.0+. - Laravel 11+: register panel providers in `bootstrap/providers.php` (never `bootstrap/app.php`). - Global search hard rule: If a Resource should appear in Global Search, it must have an Edit or View page; otherwise it will return no results. @@ -413,6 +415,7 @@ ## 1) Non-negotiables - https://filamentphp.com/docs/5.x/styling/css-hooks ## 2) Directory & naming conventions + - Default to Filament discovery conventions for Resources/Pages/Widgets unless you adopt modular architecture. - Clusters: directory layout is recommended, not mandatory; functional behavior depends on `$cluster`. @@ -421,6 +424,7 @@ ## 2) Directory & naming conventions - https://filamentphp.com/docs/5.x/advanced/modular-architecture ## 3) Panel setup defaults + - Default to a single `/admin` panel unless multiple audiences/configs demand multiple panels. - Verify provider registration (Laravel 11+: `bootstrap/providers.php`) when adding a panel. - Use `path()` carefully; treat `path('')` as a high-risk change requiring route conflict review. @@ -434,6 +438,7 @@ ## 3) Panel setup defaults - https://filamentphp.com/docs/5.x/advanced/assets ## 4) Navigation & information architecture + - Use nav groups + sort order intentionally; apply conditional visibility for clarity, but enforce authorization separately. - Use clusters to introduce hierarchy and sub-navigation when sidebar complexity grows. - Treat cluster code structure as a recommendation (organizational benefit), not a required rule. @@ -447,6 +452,7 @@ ## 4) Navigation & information architecture - https://filamentphp.com/docs/5.x/navigation/user-menu ## 5) Resource patterns + - Default to Resources for CRUD; use custom pages for non-CRUD tools/workflows. - Global search: - If a resource is intended for global search: ensure Edit/View page exists. @@ -459,6 +465,7 @@ ## 5) Resource patterns - https://filamentphp.com/docs/5.x/resources/global-search ## 6) Page lifecycle & query rules + - Treat relationship-backed rendering in aggregate contexts (global search details, list summaries) as requiring eager loading. - Prefer render hooks for layout injection; avoid publishing internal views. @@ -467,6 +474,7 @@ ## 6) Page lifecycle & query rules - https://filamentphp.com/docs/5.x/advanced/render-hooks ## 7) Infolists vs RelationManagers (decision tree) + - Interactive CRUD / attach / detach under owner record → RelationManager. - Pick existing related record(s) inside owner form → Select / CheckboxList relationship fields. - Inline CRUD inside owner form → Repeater. @@ -477,6 +485,7 @@ ## 7) Infolists vs RelationManagers (decision tree) - https://filamentphp.com/docs/5.x/infolists/overview ## 8) Form patterns (validation, reactivity, state) + - Default: minimize server-driven reactivity; only use it when schema/visibility/requirements must change server-side. - Prefer “on blur” semantics for chatty inputs when using reactive behavior (per docs patterns). - Custom field views must obey state binding modifiers. @@ -486,6 +495,7 @@ ## 8) Form patterns (validation, reactivity, state) - https://filamentphp.com/docs/5.x/forms/custom-fields ## 9) Table & action patterns + - Tables: always define a meaningful empty state (and empty-state actions where appropriate). - Actions: - Execution actions use `->action(...)`. @@ -498,6 +508,7 @@ ## 9) Table & action patterns - https://filamentphp.com/docs/5.x/actions/modals ## 10) Authorization & security + - Enforce panel access in non-local environments as documented. - UI visibility is not security; enforce policies/access checks in addition to hiding UI. - Bulk operations: explicitly decide between “Any” policy methods vs per-record authorization. @@ -507,6 +518,7 @@ ## 10) Authorization & security - https://filamentphp.com/docs/5.x/resources/deleting-records ## 11) Notifications & UX feedback + - Default to explicit success/error notifications for user-triggered mutations that aren’t instantly obvious. - Treat polling as a cost; set intervals intentionally where polling is used. @@ -515,6 +527,7 @@ ## 11) Notifications & UX feedback - https://filamentphp.com/docs/5.x/widgets/stats-overview ## 12) Performance defaults + - Heavy assets: prefer on-demand loading (`loadedOnRequest()` + `x-load-css` / `x-load-js`) for heavy dependencies. - Styling overrides use CSS hook classes; layout injection uses render hooks; avoid view publishing. @@ -524,6 +537,7 @@ ## 12) Performance defaults - https://filamentphp.com/docs/5.x/advanced/render-hooks ## 13) Testing requirements + - Test pages/relation managers/widgets as Livewire components. - Test actions using Filament’s action testing guidance. - Do not mount non-Livewire classes in Livewire tests. @@ -533,6 +547,7 @@ ## 13) Testing requirements - https://filamentphp.com/docs/5.x/testing/testing-actions ## 14) Forbidden patterns + - Mixing Filament v3/v4 APIs into v5 code. - Any mention of Livewire v3 for Filament v5. - Registering panel providers in `bootstrap/app.php` on Laravel 11+. @@ -547,6 +562,7 @@ ## 14) Forbidden patterns - https://filamentphp.com/docs/5.x/advanced/assets ## 15) Agent output contract + For any implementation request, the agent must explicitly state: 1) Livewire v4.0+ compliance. 2) Provider registration location (Laravel 11+: `bootstrap/providers.php`). @@ -567,6 +583,7 @@ ## 15) Agent output contract # SECTION C — AI REVIEW CHECKLIST (STRICT CHECKBOXES) ## Version Safety + - [ ] Filament v5 explicitly targets Livewire v4.0+ (no Livewire v3 references anywhere). - Source: https://filamentphp.com/docs/5.x/upgrade-guide — “Upgrading Livewire” - [ ] All references are Filament `/docs/5.x/` only (no v3/v4 docs, no legacy APIs). @@ -574,6 +591,7 @@ ## Version Safety - Source: https://filamentphp.com/docs/5.x/upgrade-guide — “New requirements” ## Panel & Navigation + - [ ] Laravel 11+: panel providers are registered in `bootstrap/providers.php` (not `bootstrap/app.php`). - Source: https://filamentphp.com/docs/5.x/panel-configuration — “Creating a new panel” - [ ] Panel `path()` choices are intentional and do not conflict with existing routes (especially `path('')`). @@ -588,6 +606,7 @@ ## Panel & Navigation - Source: https://filamentphp.com/docs/5.x/navigation/user-menu — “Introduction” ## Resource Structure + - [ ] `$recordTitleAttribute` is set for any resource intended for global search. - Source: https://filamentphp.com/docs/5.x/resources/overview — “Record titles” - [ ] Hard rule enforced: every globally searchable resource has an Edit or View page; otherwise global search is disabled for it. @@ -596,18 +615,21 @@ ## Resource Structure - Source: https://filamentphp.com/docs/5.x/resources/global-search — “Adding extra details to global search results” ## Infolists & Relations + - [ ] Each relationship uses the correct tool (RelationManager vs Select/CheckboxList vs Repeater) based on required interaction. - Source: https://filamentphp.com/docs/5.x/resources/managing-relationships — “Choosing the right tool for the job” - [ ] RelationManagers remain lazy-loaded by default unless there’s an explicit UX justification. - Source: https://filamentphp.com/docs/5.x/resources/managing-relationships — “Disabling lazy loading” ## Forms + - [ ] Server-driven reactivity is minimal; chatty inputs do not trigger network requests unnecessarily. - Source: https://filamentphp.com/docs/5.x/forms/overview — “Reactive fields on blur” - [ ] Custom field views obey state binding modifiers (no hardcoded `wire:model` without modifiers). - Source: https://filamentphp.com/docs/5.x/forms/custom-fields — “Obeying state binding modifiers” ## Tables & Actions + - [ ] Tables define a meaningful empty state (and empty-state actions where appropriate). - Source: https://filamentphp.com/docs/5.x/tables/empty-state — “Adding empty state actions” - [ ] All destructive actions execute via `->action(...)` and include `->requiresConfirmation()`. @@ -616,6 +638,7 @@ ## Tables & Actions - Source: https://filamentphp.com/docs/5.x/actions/modals — “Confirmation modals” ## Authorization & Security + - [ ] Panel access is enforced for non-local environments as documented. - Source: https://filamentphp.com/docs/5.x/users/overview — “Authorizing access to the panel” - [ ] UI visibility is not treated as authorization; policies/access checks still enforce boundaries. @@ -623,24 +646,28 @@ ## Authorization & Security - Source: https://filamentphp.com/docs/5.x/resources/deleting-records — “Authorization” ## UX & Notifications + - [ ] User-triggered mutations provide explicit success/error notifications when outcomes aren’t instantly obvious. - Source: https://filamentphp.com/docs/5.x/notifications/overview — “Introduction” - [ ] Polling (widgets/notifications) is configured intentionally (interval set or disabled) to control load. - Source: https://filamentphp.com/docs/5.x/widgets/stats-overview — “Live updating stats (polling)” ## Performance + - [ ] Heavy frontend assets are loaded on-demand using `loadedOnRequest()` + `x-load-css` / `x-load-js` where appropriate. - Source: https://filamentphp.com/docs/5.x/advanced/assets — “Lazy loading CSS” / “Lazy loading JavaScript” - [ ] Styling overrides use CSS hook classes discovered via DevTools (no brittle selectors by default). - Source: https://filamentphp.com/docs/5.x/styling/css-hooks — “Discovering hook classes” ## Testing + - [ ] Livewire tests mount Filament pages/relation managers/widgets (Livewire components), not static resource classes. - Source: https://filamentphp.com/docs/5.x/testing/overview — “What is a Livewire component when using Filament?” - [ ] Actions that mutate data are covered using Filament’s action testing guidance. - Source: https://filamentphp.com/docs/5.x/testing/testing-actions — “Testing actions” ## Deployment / Ops + - [ ] `php artisan filament:assets` is included in the deployment process when using registered assets. - Source: https://filamentphp.com/docs/5.x/advanced/assets — “The FilamentAsset facade” @@ -648,12 +675,13 @@ ## Deployment / Ops # 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. +The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to ensure the best experience when 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.15 +- php - 8.4.1 - filament/filament (FILAMENT) - v5 - laravel/framework (LARAVEL) - v12 - laravel/prompts (PROMPTS) - v0 @@ -666,56 +694,73 @@ ## Foundational Context - phpunit/phpunit (PHPUNIT) - v12 - tailwindcss (TAILWINDCSS) - v4 +## Skills Activation + +This project has domain-specific skills available. You MUST activate the relevant skill whenever you work in that domain—don't wait until you're stuck. + +- `pest-testing` — Tests applications using the Pest 4 PHP framework. Activates when writing tests, creating unit or feature tests, adding assertions, testing Livewire components, browser testing, debugging test failures, working with datasets or mocking; or when the user mentions test, spec, TDD, expects, assertion, coverage, or needs to verify functionality works. +- `tailwindcss-development` — Styles applications using Tailwind CSS v4 utilities. Activates when adding styles, restyling components, working with gradients, spacing, layout, flex, grid, responsive design, dark mode, colors, typography, or borders; or when the user mentions CSS, styling, classes, Tailwind, restyle, hero section, cards, buttons, or any visual/UI changes. + ## 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, and 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. + +- Do not create verification scripts or tinker when tests cover that functionality and prove they work. 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 `vendor/bin/sail npm run build`, `vendor/bin/sail npm run dev`, or `vendor/bin/sail 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. +## Replies + +- Be concise in your explanations - focus on what's important rather than explaining obvious details. + === boost rules === -## Laravel Boost +# 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. +- Use the `database-schema` tool to inspect table structure before writing migrations or models. ## 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 when dealing with Laravel or Laravel ecosystem packages. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation 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. + +- Boost comes with a powerful `search-docs` tool you should use before trying other approaches when working with Laravel or Laravel ecosystem packages. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages. - 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']`. +- Use multiple, broad, simple, topic-based queries at once. For example: `['rate limiting', 'routing rate limiting', 'routing']`. The most relevant results will be returned first. - 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". @@ -725,38 +770,44 @@ ### Available Search Syntax === php rules === -## PHP +# PHP -- Always use curly braces for control structures, even if it has one line. +- Always use curly braces for control structures, even for single-line bodies. + +## Constructors -### Constructors - Use PHP 8 constructor property promotion in `__construct()`. - - public function __construct(public GitHub $github) { } + - `public function __construct(public GitHub $github) { }` - Do not allow empty `__construct()` methods with zero parameters unless the constructor is private. -### Type Declarations +## Type Declarations + - Always use explicit return type declarations for methods and functions. - Use appropriate PHP type hints for method parameters. - + +```php protected function isAccessible(User $user, ?string $path = null): bool { ... } - - -## Comments -- Prefer PHPDoc blocks over inline 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`. +## Comments + +- Prefer PHPDoc blocks over inline comments. Never use comments within the code itself unless the logic is exceptionally complex. + +## PHPDoc Blocks + +- Add useful array shape type definitions when appropriate. + === sail rules === -## Laravel Sail +# Laravel Sail - This project runs inside Laravel Sail's Docker containers. You MUST execute all commands through Sail. - Start services using `vendor/bin/sail up -d` and stop them with `vendor/bin/sail stop`. @@ -770,20 +821,21 @@ ## Laravel Sail === tests rules === -## Test Enforcement +# 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 `vendor/bin/sail artisan test --compact` with a specific filename or filter. === laravel/core rules === -## Do Things the Laravel Way +# Do Things the Laravel Way - Use `vendor/bin/sail 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 `vendor/bin/sail 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 +## 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. @@ -791,43 +843,53 @@ ### Database - 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 `vendor/bin/sail 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 +## 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 -### Authentication & Authorization - Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.). -### URL Generation +## URL Generation + - When generating links to other pages, prefer named routes and the `route()` function. -### Configuration +## Queues + +- Use queued jobs for time-consuming operations with the `ShouldQueue` interface. + +## 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 +## 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 `vendor/bin/sail 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 +## Vite Error + - If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `vendor/bin/sail npm run build` or ask the user to run `vendor/bin/sail npm run dev` or `vendor/bin/sail composer run dev`. === laravel/v12 rules === -## Laravel 12 +# Laravel 12 -- Use the `search-docs` tool to get version-specific documentation. +- CRITICAL: ALWAYS use `search-docs` tool for version-specific Laravel documentation and updated code examples. - Since Laravel 11, Laravel has a new streamlined file structure which this project uses. -### Laravel 12 Structure +## Laravel 12 Structure + - In Laravel 12, middleware are no longer registered in `app/Http/Kernel.php`. - Middleware are configured declaratively in `bootstrap/app.php` using `Application::configure()->withMiddleware()`. - `bootstrap/app.php` is the file to register middleware, exceptions, and routing files. @@ -835,224 +897,39 @@ ### Laravel 12 Structure - The `app\Console\Kernel.php` file no longer exists; use `bootstrap/app.php` or `routes/console.php` for console configuration. - Console commands in `app/Console/Commands/` are automatically available and do not require manual registration. -### Database +## 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 12 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. -=== livewire/core rules === - -## Livewire - -- Use the `search-docs` tool to find exact version-specific documentation for how to write Livewire and Livewire tests. -- Use the `vendor/bin/sail 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) -
- {{ $item->name }} -
- @endforeach - ``` - -- Prefer lifecycle hooks like `mount()`, `updatedFoo()` for initialization and reactive side effects: - - - public function mount(User $user) { $this->user = $user; } - public function updatedSearch() { $this->resetPage(); } - - -## Testing Livewire - - - Livewire::test(Counter::class) - ->assertSet('count', 0) - ->call('increment') - ->assertSet('count', 1) - ->assertSee(1) - ->assertStatus(200); - - - - $this->get('/posts/create') - ->assertSeeLivewire(CreatePost::class); - - === pint/core rules === -## Laravel Pint Code Formatter +# Laravel Pint Code Formatter -- You must run `vendor/bin/sail bin pint --dirty` before finalizing changes to ensure your code matches the project's expected style. -- Do not run `vendor/bin/sail bin pint --test`, simply run `vendor/bin/sail bin pint` to fix any formatting issues. +- You must run `vendor/bin/sail bin pint --dirty --format agent` before finalizing changes to ensure your code matches the project's expected style. +- Do not run `vendor/bin/sail bin pint --test --format agent`, simply run `vendor/bin/sail bin pint --format agent` 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 `vendor/bin/sail 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: - -it('is true', function () { - expect(true)->toBeTrue(); -}); - - -### Running Tests -- Run the minimal number of tests using an appropriate filter before finalizing code edits. -- To run all tests: `vendor/bin/sail artisan test --compact`. -- To run all tests in a file: `vendor/bin/sail artisan test --compact tests/Feature/ExampleTest.php`. -- To filter on a particular test name: `vendor/bin/sail artisan test --compact --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.: - -it('returns all', function () { - $response = $this->postJson('/api/docs', []); - - $response->assertSuccessful(); -}); - - -### 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 that have a lot of duplicated data. This is often the case when testing validation rules, so consider this solution when writing tests for validation rules. - - -it('has emails', function (string $email) { - expect($email)->not->toBeEmpty(); -})->with([ - 'james' => 'james@laravel.com', - 'taylor' => 'taylor@laravel.com', -]); - - -=== pest/v4 rules === - -## Pest 4 - -- Pest 4 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 4 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 - - -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); -}); - - - -$pages = visit(['/', '/about', '/contact']); - -$pages->assertNoJavascriptErrors()->assertNoConsoleLogs(); - +- This project uses Pest for testing. Create tests: `vendor/bin/sail artisan make:test --pest {name}`. +- Run tests: `vendor/bin/sail artisan test --compact` or filter: `vendor/bin/sail artisan test --compact --filter=testName`. +- Do NOT delete tests without approval. +- CRITICAL: ALWAYS use `search-docs` tool for version-specific Pest documentation and updated code examples. +- IMPORTANT: Activate `pest-testing` every time you're working with a Pest or testing-related task. === tailwindcss/core rules === -## Tailwind CSS +# Tailwind CSS -- Use Tailwind CSS classes to style HTML; check and use existing Tailwind conventions within the project before writing your own. -- Offer to extract repeated patterns into components that match the project's conventions (i.e. Blade, JSX, Vue, etc.). -- Think through class placement, order, priority, and defaults. Remove redundant classes, add classes to parent or child carefully to limit repetition, and group elements logically. -- You can use the `search-docs` tool to get exact examples from the official documentation when needed. - -### Spacing -- When listing items, use gap utilities for spacing; don't use margins. - - -
-
Superior
-
Michigan
-
Erie
-
-
- -### Dark Mode -- If existing pages and components support dark mode, new pages and components must support dark mode in a similar way, typically using `dark:`. - -=== tailwindcss/v4 rules === - -## Tailwind CSS 4 - -- Always use Tailwind CSS v4; do not use the deprecated utilities. -- `corePlugins` is not supported in Tailwind v4. -- In Tailwind v4, configuration is CSS-first using the `@theme` directive — no separate `tailwind.config.js` file is needed. - - -@theme { - --color-brand: oklch(0.72 0.11 178); -} - - -- In Tailwind v4, you import Tailwind using a regular CSS `@import` statement, not using the `@tailwind` directives used in v3: - - - - @tailwind base; - - @tailwind components; - - @tailwind utilities; - + @import "tailwindcss"; - - -### Replaced Utilities -- Tailwind v4 removed deprecated utilities. Do not use the deprecated option; use the replacement. -- Opacity values are still numeric. - -| Deprecated | Replacement | -|------------+--------------| -| bg-opacity-* | bg-black/* | -| text-opacity-* | text-black/* | -| border-opacity-* | border-black/* | -| divide-opacity-* | divide-black/* | -| ring-opacity-* | ring-black/* | -| placeholder-opacity-* | placeholder-black/* | -| flex-shrink-* | shrink-* | -| flex-grow-* | grow-* | -| overflow-ellipsis | text-ellipsis | -| decoration-slice | box-decoration-slice | -| decoration-clone | box-decoration-clone | +- Always use existing Tailwind conventions; check project patterns before adding new ones. +- IMPORTANT: Always use `search-docs` tool for version-specific Tailwind CSS documentation and updated code examples. Never rely on training data. +- IMPORTANT: Activate `tailwindcss-development` every time you're working with a Tailwind CSS or styling-related task. ## Active Technologies diff --git a/GEMINI.md b/GEMINI.md index 1ed6555..f03eea5 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -229,6 +229,7 @@ ## Reference Materials === .ai/filament-v5-blueprint rules === ## Source of Truth + If any Filament behavior is uncertain, lookup the exact section in: - docs/research/filament-v5-notes.md and prefer that over guesses. @@ -238,6 +239,7 @@ # SECTION B — FILAMENT V5 BLUEPRINT (EXECUTABLE RULES) # Filament Blueprint (v5) ## 1) Non-negotiables + - Filament v5 requires Livewire v4.0+. - Laravel 11+: register panel providers in `bootstrap/providers.php` (never `bootstrap/app.php`). - Global search hard rule: If a Resource should appear in Global Search, it must have an Edit or View page; otherwise it will return no results. @@ -253,6 +255,7 @@ ## 1) Non-negotiables - https://filamentphp.com/docs/5.x/styling/css-hooks ## 2) Directory & naming conventions + - Default to Filament discovery conventions for Resources/Pages/Widgets unless you adopt modular architecture. - Clusters: directory layout is recommended, not mandatory; functional behavior depends on `$cluster`. @@ -261,6 +264,7 @@ ## 2) Directory & naming conventions - https://filamentphp.com/docs/5.x/advanced/modular-architecture ## 3) Panel setup defaults + - Default to a single `/admin` panel unless multiple audiences/configs demand multiple panels. - Verify provider registration (Laravel 11+: `bootstrap/providers.php`) when adding a panel. - Use `path()` carefully; treat `path('')` as a high-risk change requiring route conflict review. @@ -274,6 +278,7 @@ ## 3) Panel setup defaults - https://filamentphp.com/docs/5.x/advanced/assets ## 4) Navigation & information architecture + - Use nav groups + sort order intentionally; apply conditional visibility for clarity, but enforce authorization separately. - Use clusters to introduce hierarchy and sub-navigation when sidebar complexity grows. - Treat cluster code structure as a recommendation (organizational benefit), not a required rule. @@ -287,6 +292,7 @@ ## 4) Navigation & information architecture - https://filamentphp.com/docs/5.x/navigation/user-menu ## 5) Resource patterns + - Default to Resources for CRUD; use custom pages for non-CRUD tools/workflows. - Global search: - If a resource is intended for global search: ensure Edit/View page exists. @@ -299,6 +305,7 @@ ## 5) Resource patterns - https://filamentphp.com/docs/5.x/resources/global-search ## 6) Page lifecycle & query rules + - Treat relationship-backed rendering in aggregate contexts (global search details, list summaries) as requiring eager loading. - Prefer render hooks for layout injection; avoid publishing internal views. @@ -307,6 +314,7 @@ ## 6) Page lifecycle & query rules - https://filamentphp.com/docs/5.x/advanced/render-hooks ## 7) Infolists vs RelationManagers (decision tree) + - Interactive CRUD / attach / detach under owner record → RelationManager. - Pick existing related record(s) inside owner form → Select / CheckboxList relationship fields. - Inline CRUD inside owner form → Repeater. @@ -317,6 +325,7 @@ ## 7) Infolists vs RelationManagers (decision tree) - https://filamentphp.com/docs/5.x/infolists/overview ## 8) Form patterns (validation, reactivity, state) + - Default: minimize server-driven reactivity; only use it when schema/visibility/requirements must change server-side. - Prefer “on blur” semantics for chatty inputs when using reactive behavior (per docs patterns). - Custom field views must obey state binding modifiers. @@ -326,6 +335,7 @@ ## 8) Form patterns (validation, reactivity, state) - https://filamentphp.com/docs/5.x/forms/custom-fields ## 9) Table & action patterns + - Tables: always define a meaningful empty state (and empty-state actions where appropriate). - Actions: - Execution actions use `->action(...)`. @@ -338,6 +348,7 @@ ## 9) Table & action patterns - https://filamentphp.com/docs/5.x/actions/modals ## 10) Authorization & security + - Enforce panel access in non-local environments as documented. - UI visibility is not security; enforce policies/access checks in addition to hiding UI. - Bulk operations: explicitly decide between “Any” policy methods vs per-record authorization. @@ -347,6 +358,7 @@ ## 10) Authorization & security - https://filamentphp.com/docs/5.x/resources/deleting-records ## 11) Notifications & UX feedback + - Default to explicit success/error notifications for user-triggered mutations that aren’t instantly obvious. - Treat polling as a cost; set intervals intentionally where polling is used. @@ -355,6 +367,7 @@ ## 11) Notifications & UX feedback - https://filamentphp.com/docs/5.x/widgets/stats-overview ## 12) Performance defaults + - Heavy assets: prefer on-demand loading (`loadedOnRequest()` + `x-load-css` / `x-load-js`) for heavy dependencies. - Styling overrides use CSS hook classes; layout injection uses render hooks; avoid view publishing. @@ -364,6 +377,7 @@ ## 12) Performance defaults - https://filamentphp.com/docs/5.x/advanced/render-hooks ## 13) Testing requirements + - Test pages/relation managers/widgets as Livewire components. - Test actions using Filament’s action testing guidance. - Do not mount non-Livewire classes in Livewire tests. @@ -373,6 +387,7 @@ ## 13) Testing requirements - https://filamentphp.com/docs/5.x/testing/testing-actions ## 14) Forbidden patterns + - Mixing Filament v3/v4 APIs into v5 code. - Any mention of Livewire v3 for Filament v5. - Registering panel providers in `bootstrap/app.php` on Laravel 11+. @@ -387,6 +402,7 @@ ## 14) Forbidden patterns - https://filamentphp.com/docs/5.x/advanced/assets ## 15) Agent output contract + For any implementation request, the agent must explicitly state: 1) Livewire v4.0+ compliance. 2) Provider registration location (Laravel 11+: `bootstrap/providers.php`). @@ -407,6 +423,7 @@ ## 15) Agent output contract # SECTION C — AI REVIEW CHECKLIST (STRICT CHECKBOXES) ## Version Safety + - [ ] Filament v5 explicitly targets Livewire v4.0+ (no Livewire v3 references anywhere). - Source: https://filamentphp.com/docs/5.x/upgrade-guide — “Upgrading Livewire” - [ ] All references are Filament `/docs/5.x/` only (no v3/v4 docs, no legacy APIs). @@ -414,6 +431,7 @@ ## Version Safety - Source: https://filamentphp.com/docs/5.x/upgrade-guide — “New requirements” ## Panel & Navigation + - [ ] Laravel 11+: panel providers are registered in `bootstrap/providers.php` (not `bootstrap/app.php`). - Source: https://filamentphp.com/docs/5.x/panel-configuration — “Creating a new panel” - [ ] Panel `path()` choices are intentional and do not conflict with existing routes (especially `path('')`). @@ -428,6 +446,7 @@ ## Panel & Navigation - Source: https://filamentphp.com/docs/5.x/navigation/user-menu — “Introduction” ## Resource Structure + - [ ] `$recordTitleAttribute` is set for any resource intended for global search. - Source: https://filamentphp.com/docs/5.x/resources/overview — “Record titles” - [ ] Hard rule enforced: every globally searchable resource has an Edit or View page; otherwise global search is disabled for it. @@ -436,18 +455,21 @@ ## Resource Structure - Source: https://filamentphp.com/docs/5.x/resources/global-search — “Adding extra details to global search results” ## Infolists & Relations + - [ ] Each relationship uses the correct tool (RelationManager vs Select/CheckboxList vs Repeater) based on required interaction. - Source: https://filamentphp.com/docs/5.x/resources/managing-relationships — “Choosing the right tool for the job” - [ ] RelationManagers remain lazy-loaded by default unless there’s an explicit UX justification. - Source: https://filamentphp.com/docs/5.x/resources/managing-relationships — “Disabling lazy loading” ## Forms + - [ ] Server-driven reactivity is minimal; chatty inputs do not trigger network requests unnecessarily. - Source: https://filamentphp.com/docs/5.x/forms/overview — “Reactive fields on blur” - [ ] Custom field views obey state binding modifiers (no hardcoded `wire:model` without modifiers). - Source: https://filamentphp.com/docs/5.x/forms/custom-fields — “Obeying state binding modifiers” ## Tables & Actions + - [ ] Tables define a meaningful empty state (and empty-state actions where appropriate). - Source: https://filamentphp.com/docs/5.x/tables/empty-state — “Adding empty state actions” - [ ] All destructive actions execute via `->action(...)` and include `->requiresConfirmation()`. @@ -456,6 +478,7 @@ ## Tables & Actions - Source: https://filamentphp.com/docs/5.x/actions/modals — “Confirmation modals” ## Authorization & Security + - [ ] Panel access is enforced for non-local environments as documented. - Source: https://filamentphp.com/docs/5.x/users/overview — “Authorizing access to the panel” - [ ] UI visibility is not treated as authorization; policies/access checks still enforce boundaries. @@ -463,24 +486,28 @@ ## Authorization & Security - Source: https://filamentphp.com/docs/5.x/resources/deleting-records — “Authorization” ## UX & Notifications + - [ ] User-triggered mutations provide explicit success/error notifications when outcomes aren’t instantly obvious. - Source: https://filamentphp.com/docs/5.x/notifications/overview — “Introduction” - [ ] Polling (widgets/notifications) is configured intentionally (interval set or disabled) to control load. - Source: https://filamentphp.com/docs/5.x/widgets/stats-overview — “Live updating stats (polling)” ## Performance + - [ ] Heavy frontend assets are loaded on-demand using `loadedOnRequest()` + `x-load-css` / `x-load-js` where appropriate. - Source: https://filamentphp.com/docs/5.x/advanced/assets — “Lazy loading CSS” / “Lazy loading JavaScript” - [ ] Styling overrides use CSS hook classes discovered via DevTools (no brittle selectors by default). - Source: https://filamentphp.com/docs/5.x/styling/css-hooks — “Discovering hook classes” ## Testing + - [ ] Livewire tests mount Filament pages/relation managers/widgets (Livewire components), not static resource classes. - Source: https://filamentphp.com/docs/5.x/testing/overview — “What is a Livewire component when using Filament?” - [ ] Actions that mutate data are covered using Filament’s action testing guidance. - Source: https://filamentphp.com/docs/5.x/testing/testing-actions — “Testing actions” ## Deployment / Ops + - [ ] `php artisan filament:assets` is included in the deployment process when using registered assets. - Source: https://filamentphp.com/docs/5.x/advanced/assets — “The FilamentAsset facade” @@ -488,12 +515,13 @@ ## Deployment / Ops # 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. +The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to ensure the best experience when 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.15 +- php - 8.4.1 - filament/filament (FILAMENT) - v5 - laravel/framework (LARAVEL) - v12 - laravel/prompts (PROMPTS) - v0 @@ -506,56 +534,73 @@ ## Foundational Context - phpunit/phpunit (PHPUNIT) - v12 - tailwindcss (TAILWINDCSS) - v4 +## Skills Activation + +This project has domain-specific skills available. You MUST activate the relevant skill whenever you work in that domain—don't wait until you're stuck. + +- `pest-testing` — Tests applications using the Pest 4 PHP framework. Activates when writing tests, creating unit or feature tests, adding assertions, testing Livewire components, browser testing, debugging test failures, working with datasets or mocking; or when the user mentions test, spec, TDD, expects, assertion, coverage, or needs to verify functionality works. +- `tailwindcss-development` — Styles applications using Tailwind CSS v4 utilities. Activates when adding styles, restyling components, working with gradients, spacing, layout, flex, grid, responsive design, dark mode, colors, typography, or borders; or when the user mentions CSS, styling, classes, Tailwind, restyle, hero section, cards, buttons, or any visual/UI changes. + ## 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, and 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. + +- Do not create verification scripts or tinker when tests cover that functionality and prove they work. 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 `vendor/bin/sail npm run build`, `vendor/bin/sail npm run dev`, or `vendor/bin/sail 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. +## Replies + +- Be concise in your explanations - focus on what's important rather than explaining obvious details. + === boost rules === -## Laravel Boost +# 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. +- Use the `database-schema` tool to inspect table structure before writing migrations or models. ## 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 when dealing with Laravel or Laravel ecosystem packages. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation 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. + +- Boost comes with a powerful `search-docs` tool you should use before trying other approaches when working with Laravel or Laravel ecosystem packages. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages. - 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']`. +- Use multiple, broad, simple, topic-based queries at once. For example: `['rate limiting', 'routing rate limiting', 'routing']`. The most relevant results will be returned first. - 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". @@ -565,38 +610,44 @@ ### Available Search Syntax === php rules === -## PHP +# PHP -- Always use curly braces for control structures, even if it has one line. +- Always use curly braces for control structures, even for single-line bodies. + +## Constructors -### Constructors - Use PHP 8 constructor property promotion in `__construct()`. - - public function __construct(public GitHub $github) { } + - `public function __construct(public GitHub $github) { }` - Do not allow empty `__construct()` methods with zero parameters unless the constructor is private. -### Type Declarations +## Type Declarations + - Always use explicit return type declarations for methods and functions. - Use appropriate PHP type hints for method parameters. - + +```php protected function isAccessible(User $user, ?string $path = null): bool { ... } - - -## Comments -- Prefer PHPDoc blocks over inline 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`. +## Comments + +- Prefer PHPDoc blocks over inline comments. Never use comments within the code itself unless the logic is exceptionally complex. + +## PHPDoc Blocks + +- Add useful array shape type definitions when appropriate. + === sail rules === -## Laravel Sail +# Laravel Sail - This project runs inside Laravel Sail's Docker containers. You MUST execute all commands through Sail. - Start services using `vendor/bin/sail up -d` and stop them with `vendor/bin/sail stop`. @@ -610,20 +661,21 @@ ## Laravel Sail === tests rules === -## Test Enforcement +# 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 `vendor/bin/sail artisan test --compact` with a specific filename or filter. === laravel/core rules === -## Do Things the Laravel Way +# Do Things the Laravel Way - Use `vendor/bin/sail 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 `vendor/bin/sail 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 +## 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. @@ -631,43 +683,53 @@ ### Database - 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 `vendor/bin/sail 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 +## 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 -### Authentication & Authorization - Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.). -### URL Generation +## URL Generation + - When generating links to other pages, prefer named routes and the `route()` function. -### Configuration +## Queues + +- Use queued jobs for time-consuming operations with the `ShouldQueue` interface. + +## 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 +## 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 `vendor/bin/sail 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 +## Vite Error + - If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `vendor/bin/sail npm run build` or ask the user to run `vendor/bin/sail npm run dev` or `vendor/bin/sail composer run dev`. === laravel/v12 rules === -## Laravel 12 +# Laravel 12 -- Use the `search-docs` tool to get version-specific documentation. +- CRITICAL: ALWAYS use `search-docs` tool for version-specific Laravel documentation and updated code examples. - Since Laravel 11, Laravel has a new streamlined file structure which this project uses. -### Laravel 12 Structure +## Laravel 12 Structure + - In Laravel 12, middleware are no longer registered in `app/Http/Kernel.php`. - Middleware are configured declaratively in `bootstrap/app.php` using `Application::configure()->withMiddleware()`. - `bootstrap/app.php` is the file to register middleware, exceptions, and routing files. @@ -675,224 +737,39 @@ ### Laravel 12 Structure - The `app\Console\Kernel.php` file no longer exists; use `bootstrap/app.php` or `routes/console.php` for console configuration. - Console commands in `app/Console/Commands/` are automatically available and do not require manual registration. -### Database +## 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 12 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. -=== livewire/core rules === - -## Livewire - -- Use the `search-docs` tool to find exact version-specific documentation for how to write Livewire and Livewire tests. -- Use the `vendor/bin/sail 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) -
- {{ $item->name }} -
- @endforeach - ``` - -- Prefer lifecycle hooks like `mount()`, `updatedFoo()` for initialization and reactive side effects: - - - public function mount(User $user) { $this->user = $user; } - public function updatedSearch() { $this->resetPage(); } - - -## Testing Livewire - - - Livewire::test(Counter::class) - ->assertSet('count', 0) - ->call('increment') - ->assertSet('count', 1) - ->assertSee(1) - ->assertStatus(200); - - - - $this->get('/posts/create') - ->assertSeeLivewire(CreatePost::class); - - === pint/core rules === -## Laravel Pint Code Formatter +# Laravel Pint Code Formatter -- You must run `vendor/bin/sail bin pint --dirty` before finalizing changes to ensure your code matches the project's expected style. -- Do not run `vendor/bin/sail bin pint --test`, simply run `vendor/bin/sail bin pint` to fix any formatting issues. +- You must run `vendor/bin/sail bin pint --dirty --format agent` before finalizing changes to ensure your code matches the project's expected style. +- Do not run `vendor/bin/sail bin pint --test --format agent`, simply run `vendor/bin/sail bin pint --format agent` 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 `vendor/bin/sail 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: - -it('is true', function () { - expect(true)->toBeTrue(); -}); - - -### Running Tests -- Run the minimal number of tests using an appropriate filter before finalizing code edits. -- To run all tests: `vendor/bin/sail artisan test --compact`. -- To run all tests in a file: `vendor/bin/sail artisan test --compact tests/Feature/ExampleTest.php`. -- To filter on a particular test name: `vendor/bin/sail artisan test --compact --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.: - -it('returns all', function () { - $response = $this->postJson('/api/docs', []); - - $response->assertSuccessful(); -}); - - -### 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 that have a lot of duplicated data. This is often the case when testing validation rules, so consider this solution when writing tests for validation rules. - - -it('has emails', function (string $email) { - expect($email)->not->toBeEmpty(); -})->with([ - 'james' => 'james@laravel.com', - 'taylor' => 'taylor@laravel.com', -]); - - -=== pest/v4 rules === - -## Pest 4 - -- Pest 4 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 4 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 - - -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); -}); - - - -$pages = visit(['/', '/about', '/contact']); - -$pages->assertNoJavascriptErrors()->assertNoConsoleLogs(); - +- This project uses Pest for testing. Create tests: `vendor/bin/sail artisan make:test --pest {name}`. +- Run tests: `vendor/bin/sail artisan test --compact` or filter: `vendor/bin/sail artisan test --compact --filter=testName`. +- Do NOT delete tests without approval. +- CRITICAL: ALWAYS use `search-docs` tool for version-specific Pest documentation and updated code examples. +- IMPORTANT: Activate `pest-testing` every time you're working with a Pest or testing-related task. === tailwindcss/core rules === -## Tailwind CSS +# Tailwind CSS -- Use Tailwind CSS classes to style HTML; check and use existing Tailwind conventions within the project before writing your own. -- Offer to extract repeated patterns into components that match the project's conventions (i.e. Blade, JSX, Vue, etc.). -- Think through class placement, order, priority, and defaults. Remove redundant classes, add classes to parent or child carefully to limit repetition, and group elements logically. -- You can use the `search-docs` tool to get exact examples from the official documentation when needed. - -### Spacing -- When listing items, use gap utilities for spacing; don't use margins. - - -
-
Superior
-
Michigan
-
Erie
-
-
- -### Dark Mode -- If existing pages and components support dark mode, new pages and components must support dark mode in a similar way, typically using `dark:`. - -=== tailwindcss/v4 rules === - -## Tailwind CSS 4 - -- Always use Tailwind CSS v4; do not use the deprecated utilities. -- `corePlugins` is not supported in Tailwind v4. -- In Tailwind v4, configuration is CSS-first using the `@theme` directive — no separate `tailwind.config.js` file is needed. - - -@theme { - --color-brand: oklch(0.72 0.11 178); -} - - -- In Tailwind v4, you import Tailwind using a regular CSS `@import` statement, not using the `@tailwind` directives used in v3: - - - - @tailwind base; - - @tailwind components; - - @tailwind utilities; - + @import "tailwindcss"; - - -### Replaced Utilities -- Tailwind v4 removed deprecated utilities. Do not use the deprecated option; use the replacement. -- Opacity values are still numeric. - -| Deprecated | Replacement | -|------------+--------------| -| bg-opacity-* | bg-black/* | -| text-opacity-* | text-black/* | -| border-opacity-* | border-black/* | -| divide-opacity-* | divide-black/* | -| ring-opacity-* | ring-black/* | -| placeholder-opacity-* | placeholder-black/* | -| flex-shrink-* | shrink-* | -| flex-grow-* | grow-* | -| overflow-ellipsis | text-ellipsis | -| decoration-slice | box-decoration-slice | -| decoration-clone | box-decoration-clone | +- Always use existing Tailwind conventions; check project patterns before adding new ones. +- IMPORTANT: Always use `search-docs` tool for version-specific Tailwind CSS documentation and updated code examples. Never rely on training data. +- IMPORTANT: Activate `tailwindcss-development` every time you're working with a Tailwind CSS or styling-related task. ## Recent Changes diff --git a/app/Filament/Resources/BaselineProfileResource.php b/app/Filament/Resources/BaselineProfileResource.php index aea3d14..564fb13 100644 --- a/app/Filament/Resources/BaselineProfileResource.php +++ b/app/Filament/Resources/BaselineProfileResource.php @@ -28,10 +28,10 @@ use Filament\Forms\Components\Select; use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; -use Filament\Infolists\Components\Section; use Filament\Infolists\Components\TextEntry; use Filament\Notifications\Notification; use Filament\Resources\Resource; +use Filament\Schemas\Components\Section; use Filament\Schemas\Schema; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; diff --git a/boost.json b/boost.json index 0a16d2e..c2de208 100644 --- a/boost.json +++ b/boost.json @@ -5,12 +5,12 @@ "gemini", "opencode" ], - "editors": [ - "codex", - "gemini", - "opencode", - "vscode" - ], - "guidelines": [], - "sail": true + "guidelines": true, + "herd_mcp": false, + "mcp": true, + "sail": true, + "skills": [ + "pest-testing", + "tailwindcss-development" + ] } diff --git a/composer.json b/composer.json index e883eae..8c2ca94 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "require-dev": { "barryvdh/laravel-debugbar": "^3.16", "fakerphp/faker": "^1.23", - "laravel/boost": "^1.8", + "laravel/boost": "^2.1", "laravel/pail": "^1.2.2", "laravel/pint": "^1.24", "laravel/sail": "^1.41", diff --git a/composer.lock b/composer.lock index 38d1177..74a276e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f1060097603f7d29074d1b2a1dd53bf8", + "content-hash": "83257f7b8eac0f483898bdf2d4adfb7e", "packages": [ { "name": "anourvalar/eloquent-serialize", @@ -9312,33 +9312,33 @@ }, { "name": "laravel/boost", - "version": "v1.8.10", + "version": "v2.1.2", "source": { "type": "git", "url": "https://github.com/laravel/boost.git", - "reference": "aad8b2a423b0a886c2ce7ee92abbfde69992ff32" + "reference": "81ecf79e82c979efd92afaeac012605cc7b2f31f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/boost/zipball/aad8b2a423b0a886c2ce7ee92abbfde69992ff32", - "reference": "aad8b2a423b0a886c2ce7ee92abbfde69992ff32", + "url": "https://api.github.com/repos/laravel/boost/zipball/81ecf79e82c979efd92afaeac012605cc7b2f31f", + "reference": "81ecf79e82c979efd92afaeac012605cc7b2f31f", "shasum": "" }, "require": { "guzzlehttp/guzzle": "^7.9", - "illuminate/console": "^10.49.0|^11.45.3|^12.41.1", - "illuminate/contracts": "^10.49.0|^11.45.3|^12.41.1", - "illuminate/routing": "^10.49.0|^11.45.3|^12.41.1", - "illuminate/support": "^10.49.0|^11.45.3|^12.41.1", + "illuminate/console": "^11.45.3|^12.41.1", + "illuminate/contracts": "^11.45.3|^12.41.1", + "illuminate/routing": "^11.45.3|^12.41.1", + "illuminate/support": "^11.45.3|^12.41.1", "laravel/mcp": "^0.5.1", - "laravel/prompts": "0.1.25|^0.3.6", + "laravel/prompts": "^0.3.10", "laravel/roster": "^0.2.9", - "php": "^8.1" + "php": "^8.2" }, "require-dev": { - "laravel/pint": "^1.20.0", + "laravel/pint": "^1.27.0", "mockery/mockery": "^1.6.12", - "orchestra/testbench": "^8.36.0|^9.15.0|^10.6", + "orchestra/testbench": "^9.15.0|^10.6", "pestphp/pest": "^2.36.0|^3.8.4|^4.1.5", "phpstan/phpstan": "^2.1.27", "rector/rector": "^2.1" @@ -9374,7 +9374,7 @@ "issues": "https://github.com/laravel/boost/issues", "source": "https://github.com/laravel/boost" }, - "time": "2026-01-14T14:51:16+00:00" + "time": "2026-02-10T17:40:45+00:00" }, { "name": "laravel/mcp", @@ -12482,5 +12482,5 @@ "php": "^8.2" }, "platform-dev": {}, - "plugin-api-version": "2.9.0" + "plugin-api-version": "2.6.0" }