# Upgrade Filament and Composer Dependencies

Yes. Each week an agent runs composer update in groups on a Filament panel, keeps what passes Pest and PHPStan, and opens one pull request.

[Run this on Rush](https://cloud.getrush.ai/run/upgrade-composer-dependencies/filament/), in a Project that has your repository.

## What the agent does

The agent reads the manifest and the lock to see what moves together. In filamentphp/demo, `composer.json` requires `filament/filament` `^5.0` with three plugins at the same range, the media library, settings and tags plugins, and `composer.lock` has all four at `v5.10.1`. Around them sit `laravel/framework` `^12.0` at `v12.69.2`, `livewire/livewire` at `v4.4.7`, `laravel/octane`, `laravel/sanctum`, `flowframe/laravel-trend` `^0.4.0`, `spatie/laravel-medialibrary` at `11.23.8` and the two `squirephp` data packages. The dev side has `pestphp/pest` `^3.0` at `v3.8.7`, `phpunit/phpunit` at `11.5.56`, `larastan/larastan` at `v3.11.0`, `laravel/pint`, `rector/rector` `^2.1` and `laravel/boost`. The `post-autoload-dump` script runs `php artisan filament:upgrade` after every install, which is what a Filament bump needs anyway.

Then it reads what passes for green. `composer test` runs `test:pest`, which is `pest --parallel`, and `test:phpstan`, which is `phpstan analyse` at level 8 with the Larastan and deprecation-rules extensions from `phpstan.neon`. `phpunit.xml` runs the `tests/Filament` suite only, with the SQLite lines commented out, so the database comes from `.env`, where `.env.example` sets `DB_CONNECTION=sqlite`; `tests/Pest.php` applies `RefreshDatabase` and signs in a factory user before each test. The suite covers the three dashboards, fourteen widgets and the resource pages across Blog, HR and Shop with `Livewire::test`, `callAction` and `TestAction`. `.github/workflows/tests.yml` runs on PHP 8.4 with `pdo_sqlite`, builds assets with `npm ci` and `npm run build` on Node 20, touches `database/database.sqlite`, and runs `composer test:pest`; `phpstan.yml` runs the analysis separately and `format.yml` runs Pint on push to `5.x`.

The repository has turned version bumps from bots off: `.github/dependabot.yml` lists `composer` and `npm` with `open-pull-requests-limit: 0`, leaving only GitHub Actions updates. So the agent's groups are the policy. Filament and its three plugins move together as one group, since the plugins pin the core version and `filament:upgrade` runs after. Laravel, Livewire, Octane and Sanctum move as the framework group. The Spatie packages move together. The dev tools move last and separately, because a Pest, PHPStan or Rector bump changes what counts as passing rather than what runs, and a new PHPStan rule at level 8 can fail the analysis on code that did not change. Majors go one at a time with `composer why-not` consulted first.

Every group runs `composer update` for its packages with `--with-all-dependencies`, then `composer test:pest`, `composer test:phpstan` and `vendor/bin/pint --test`. Before the first group the agent copies `.env.example` to `.env`, generates a key, touches the SQLite file and runs `npm ci && npm run build` once so the Vite manifest the Livewire tests render against exists. A group that passes is a commit; a group that fails is reverted and its error kept. The pull request lists each bump with old and new versions from the lock, the skips with their reason, and the three check results.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "Upgrade this Filament app's Composer dependencies in groups: filament/filament and its plugins together, then laravel/framework with livewire, octane and sanctum, then the spatie packages, then the remaining runtime packages, then the dev tools one at a time, and any major on its own. Before the first group copy .env.example to .env, run php artisan key:generate, create the SQLite database file and build assets with npm ci and npm run build. After each group run composer update for that group with --with-all-dependencies, then composer test:pest, composer test:phpstan and vendor/bin/pint --test. Keep a group only if all three pass; otherwise revert it and record the error. Open one pull request with one commit per group, one line per bump with old and new versions from composer.lock, and every upgrade left out with the reason.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

What comes back is a pull request that changes `composer.lock`, and `composer.json` only where a constraint had to move for a major, in one commit per group that passed. Published Filament assets under `public/` change when the Filament group moved, because `filament:upgrade` runs on install. No application code changes unless a major required it, and then the description names the file and the line.

The description is one line per bump with the locked versions before and after, a list of upgrades left out with the failing Pest test, PHPStan error or Pint diff that excluded them, and the result lines of `composer test:pest`, `composer test:phpstan` and `pint --test`. The trajectory keeps the full output for every group, including the reverted ones.

Before merging, a reviewer checks that the four Filament packages carry the same version, that a PHPStan failure was fixed by reverting the tool bump rather than by lowering the level, and that a skipped major is not a security release that deserves a code change in its own pull request.

## Run it on every Monday morning

Create an automation in the Project with this prompt and a `schedule` trigger (`cron` `0 9 * * 1` in your `timezone`). Each week the run opens one pull request with that week's bumps, or none when nothing moved. Because each group is its own commit, dropping a bump before merge is a revert of one commit.

To have the link reach your server, start the weekly run from your own scheduler instead, with `POST /o/{org}/sessions` and an API key that has a webhook URL: Rush then POSTs `run.completed` with the `session_url` when the turn ends, and a handler on your side can post the pull request link to the channel that watches the panel. A run that ends with no safe group opens no pull request and says why in its result.

## Why run it on Rush?

A Filament panel has more moving parts than a plain Laravel app: the core, three plugins and Livewire have to agree, an upgrade publishes assets, and the Pest suite drives every page through Livewire. The repository turned bot pull requests off because a red one is noise. On Rush the agent runs the suite and the static analysis after each group in its own sandbox, reverts what fails, and keeps the output, so the pull request that reaches you is already green and the failures are written down.

Running `pest --parallel` and PHPStan at level 8 on every group is work a person does once a quarter at best. The record shows each run, and the same request runs on every Filament panel you maintain at once.

## Frequently asked questions

### Why do the Filament plugins move with the core?

Because each plugin pins the core version it was built against, and `composer.lock` already shows all four at the same version. Moving one without the others fails `composer update` or `filament:upgrade`, so the agent treats them as one group.

### Does it need Node?

Once, to build the assets the Livewire tests render against. `tests.yml` does the same with `npm ci` and `npm run build`. The agent does not upgrade npm packages in this run; that is a separate job.

### What if PHPStan fails after a Larastan bump?

The dev-tool group is reverted and the new errors are listed in the description, with the files they point at, so you can decide whether to fix the code or raise the tool later. The agent does not lower the level or add a baseline to make the analysis pass.

### Will it touch application code?

Only for a major that requires it, in the same commit as the bump, with the change named in the description. Minor and patch groups that need code changes are reverted and reported instead.

### Can I pin a package?

Yes. Name it in the prompt and it stays at its locked version with a note in the pull request. A tightened constraint in `composer.json` works too and is respected.
