php artisan boost:add-skill filament/tables
Save this content to: AGENTS.md
# AGENTS.md
Filament is a full-stack UI framework for Laravel built with Livewire. It provides admin panels, forms, tables, notifications, actions, infolists, and widgets as composable packages.
## Task-specific Skills
Load the relevant skill before doing its work. If your agent cannot load skills, read the linked `SKILL.md` directly.
- **Testing**: Load [testing-filament](.agents/skills/testing-filament/SKILL.md) when planning verification, adding or changing tests, running tests, or validating asynchronous JavaScript changes. It covers Pest, browser testing, accessibility, and test databases.
- **Documentation**: Load [writing-filament-docs](.agents/skills/writing-filament-docs/SKILL.md) when adding, editing, or reviewing developer documentation.
- **Documentation screenshots**: Load [capturing-filament-screenshots](.agents/skills/capturing-filament-screenshots/SKILL.md) when adding screenshot examples, changing screenshot definitions, or capturing documentation screenshots.
## Testing and Documentation Requirements
**Introduce new tests only for actual frontend or backend behavior changes.** Styling changes and bug fixes that restore existing intended behavior should not introduce new tests. Verify those fixes using existing tests and, for styling, visual inspection. For frontend behavior changes, add browser tests using Pest Browser. Load `testing-filament` before planning or performing verification.
**Update documentation for developer-facing features and changes to supported usage** in the owning page under `docs/` or `packages/{package}/docs/`. Automatic styling, layout, interaction changes, fixes restoring intended behavior, and implementation details need documentation only when they change how developers configure, use, extend, or integrate Filament, or introduce consequential compatibility or accessibility limitations. A change visible to end users alone does not require documentation.
## Naming Conventions
- **Never use abbreviated variable names.** Use `$exception`, `$component`, `$response`, `$configuration`, `$record`, and `$livewire`, not `$e`, `$comp`, `$res`, `$cfg`, `$rec`, or `$lw`. Universally understood abbreviations like `$id` and `$url` are allowed.
- Use backticks for code references in Pest test names, with `()` for methods: `` it('can use `aspectRatio()` to force image cropping') ``.
- Use backticks for code references in comments: `` // Uses `evaluate()` to resolve the `Closure` ``.
## Development Commands
Run from the repository root:
```bash
composer test # Run all tests (SQLite + commands + PHPStan)
composer test:sqlite # Run tests with SQLite
composer test:phpstan # Run PHPStan static analysis
composer cs # Run all code style fixes (Rector + Pint + Prettier)
npm run build # Build all JS and CSS
npm run build-demo # Build and publish to ../demo if it exists
vendor/bin/pest tests/src/Forms/Components/FileUploadTest.php
```
Database-specific commands and startup instructions are in `testing-filament`. The demo uses SQLite.
## Coding Patterns
### Fluent API
Components use `make()` and fluent chainable methods. Nullable properties have nullable setters so they can be undone. Properties and setters share a name; getters use `get` and `evaluate()` for `Closure` support:
```php
protected string | Closure | null $icon = null;
public function icon(string | Closure | null $icon): static
{
$this->icon = $icon;
return $this;
}
public function getIcon(): ?string
{
return $this->evaluate($this->icon);
}
```
### Boolean Methods
Boolean properties use an `is`/`should`/`can`/`has` prefix, default to `false`, and support `Closure`. Setters use the verb form, default their argument to `true`, and accept `false` to undo. Getters cast to `bool`:
```php
protected bool | Closure $isDisabled = false;
public function disabled(bool | Closure $condition = true): static
{
$this->isDisabled = $condition;
return $this;
}
public function isDisabled(): bool
{
return (bool) $this->evaluate($this->isDisabled);
}
```
### Other PHP Conventions
- Use `static fn` when the closure doesn't use `$this`.
- Use `app()` instead of `new` to allow users to bind custom implementations.
- Do not use `final` or `readonly` classes; users need to extend Filament classes.
- Traits in `Concerns/` use `Can*` for capabilities and `Has*` for properties. Interfaces belong in `Contracts/`.
- Add PHPDoc only when providing type information beyond native PHP types.
- Keep old public methods used in docs and mark them with `` /** @deprecated Use `newMethod()` instead. */ ``.
## JavaScript
### Organization
Use `components/` for eager and lazy Alpine factories, `stores/` for Alpine stores, `utilities/` for shared helpers and composition, and `components/<feature>/` for feature-private internals. Keep registration in `index.js`. Use kebab-case filenames and explicit `.js` extensions on relative JavaScript imports. Follow the owning package's frontend naming convention; check registration and markup usage before renaming existing names.
### Lifecycle Cleanup
- Alpine components and directives must release resources they own in `destroy()` or `cleanup()`, including listeners on surviving ancestors or global objects, observers, animation loops, and third-party instances. Retain the same callback reference when adding and removing listeners. Listeners attached only to removed subtree elements do not need separate cleanup.
- Guard asynchronous initialization and callbacks when they could create surviving resources or cause observable stale behavior after destruction. After asynchronous work, verify the owner and target are still current; saved document positions alone do not establish identity. Verify third-party completion, failure, cancellation, and teardown contracts against their implementation when necessary, and use their real teardown API.
- Balance processing-start/finish signals exactly once per operation, including failure, cancellation, and destruction. For batches, restore busy/editable state only after every task settles; preserve the original state.
- Do not add cleanup solely for short-lived timers; cancel or guard them when their callback could still cause stale behavior after destruction.
## CSS Hook Classes
**Never use Tailwind classes directly in Blade views.** Put them in CSS files using `@apply`:
```css
.fi-fo-field {
@apply grid gap-y-2;
}
```
Use the `fi-` prefix with package codes (`fi-fo-` forms, `fi-ta-` tables, `fi-ac-` actions, etc.). Hook abbreviations include `btn`, `col`, `ctn`, and `wrp`.
## Repository Map
Core dependency direction: **support** → **schemas** → **forms**, **infolists**, **tables**, **actions**, **notifications**, **widgets** → **panels**.
Other packages include query-builder, upgrade, spatie-laravel-media-library-plugin, spatie-laravel-settings-plugin, spatie-laravel-tags-plugin, spatie-laravel-google-fonts-plugin, and spark-billing-provider.
- **Resources**: `packages/panels/src/Resources/` (Eloquent CRUD interfaces)
- **Pages**: `packages/panels/src/Pages/` (Livewire page components)
- **Schema components**: `packages/schemas/src/Components/`
- **Actions**: `packages/actions/src/` (modal-based operations)
- **Panel configuration**: `packages/panels/src/Panel.php`
- **Tests**: `tests/src/{Forms,Tables,Actions,Panels}/`
- **Docs**: `docs/` and `packages/{package}/docs/`
- **Views**: `packages/{package}/resources/views/`
- **CSS**: `packages/{package}/resources/css/`
- **Translations**: `packages/{package}/resources/lang/{locale}/`
Filament is a full-stack UI framework for Laravel built with Livewire. It provides admin panels, forms, tables, notifications, actions, infolists, and widgets as composable packages.
Load the relevant skill before doing its work. If your agent cannot load skills, read the linked SKILL.md directly.
Introduce new tests only for actual frontend or backend behavior changes. Styling changes and bug fixes that restore existing intended behavior should not introduce new tests. Verify those fixes using existing tests and, for styling, visual inspection. For frontend behavior changes, add browser tests using Pest Browser. Load testing-filament before planning or performing verification.
Update documentation for developer-facing features and changes to supported usage in the owning page under docs/ or packages/{package}/docs/. Automatic styling, layout, interaction changes, fixes restoring intended behavior, and implementation details need documentation only when they change how developers configure, use, extend, or integrate Filament, or introduce consequential compatibility or accessibility limitations. A change visible to end users alone does not require documentation.
$exception, $component, $response, $configuration, $record, and $livewire, not $e, $comp, $res, $cfg, $rec, or $lw. Universally understood abbreviations like $id and $url are allowed.() for methods: it('can use `aspectRatio()` to force image cropping').// Uses `evaluate()` to resolve the `Closure`.Run from the repository root:
composer test # Run all tests (SQLite + commands + PHPStan)
composer test:sqlite # Run tests with SQLite
composer test:phpstan # Run PHPStan static analysis
composer cs # Run all code style fixes (Rector + Pint + Prettier)
npm run build # Build all JS and CSS
npm run build-demo # Build and publish to ../demo if it exists
vendor/bin/pest tests/src/Forms/Components/FileUploadTest.php
Database-specific commands and startup instructions are in testing-filament. The demo uses SQLite.
Components use make() and fluent chainable methods. Nullable properties have nullable setters so they can be undone. Properties and setters share a name; getters use get and evaluate() for Closure support:
protected string | Closure | null $icon = null;
public function icon(string | Closure | null $icon): static
{
$this->icon = $icon;
return $this;
}
public function getIcon(): ?string
{
return $this->evaluate($this->icon);
}
Boolean properties use an is/should/can/has prefix, default to false, and support Closure. Setters use the verb form, default their argument to true, and accept false to undo. Getters cast to bool:
protected bool | Closure $isDisabled = false;
public function disabled(bool | Closure $condition = true): static
{
$this->isDisabled = $condition;
return $this;
}
public function isDisabled(): bool
{
return (bool) $this->evaluate($this->isDisabled);
}
static fn when the closure doesn't use $this.app() instead of new to allow users to bind custom implementations.final or readonly classes; users need to extend Filament classes.Concerns/ use Can* for capabilities and Has* for properties. Interfaces belong in Contracts/./** @deprecated Use `newMethod()` instead. */.Use components/ for eager and lazy Alpine factories, stores/ for Alpine stores, utilities/ for shared helpers and composition, and components/<feature>/ for feature-private internals. Keep registration in index.js. Use kebab-case filenames and explicit .js extensions on relative JavaScript imports. Follow the owning package's frontend naming convention; check registration and markup usage before renaming existing names.
destroy() or cleanup(), including listeners on surviving ancestors or global objects, observers, animation loops, and third-party instances. Retain the same callback reference when adding and removing listeners. Listeners attached only to removed subtree elements do not need separate cleanup.Never use Tailwind classes directly in Blade views. Put them in CSS files using @apply:
.fi-fo-field {
@apply grid gap-y-2;
}
Use the fi- prefix with package codes (fi-fo- forms, fi-ta- tables, fi-ac- actions, etc.). Hook abbreviations include btn, col, ctn, and wrp.
Core dependency direction: support → schemas → forms, infolists, tables, actions, notifications, widgets → panels.
Other packages include query-builder, upgrade, spatie-laravel-media-library-plugin, spatie-laravel-settings-plugin, spatie-laravel-tags-plugin, spatie-laravel-google-fonts-plugin, and spark-billing-provider.
packages/panels/src/Resources/ (Eloquent CRUD interfaces)packages/panels/src/Pages/ (Livewire page components)packages/schemas/src/Components/packages/actions/src/ (modal-based operations)packages/panels/src/Panel.phptests/src/{Forms,Tables,Actions,Panels}/docs/ and packages/{package}/docs/packages/{package}/resources/views/packages/{package}/resources/css/packages/{package}/resources/lang/{locale}/How can I help you explore Laravel packages today?