# AI coding agents

Partisan notices when an AI coding agent is driving it and switches to output shaped for a model instead of a terminal. This page covers what changes, how to make sure an agent reaches for the generators at all, and what that saves, measured with Claude Code on a real Filament plugin.

## Agent mode

Detection uses [laravel/agent-detector](https://github.com/laravel/agent-detector), which recognises Claude Code, Codex, Cursor, Gemini CLI, Copilot and friends. Set `PARTISAN_AGENT=1` to get the same output in your own terminal, or `PARTISAN_AGENT=0` to opt out. The output follows the [AXI](https://axi.md) principles for agent-ergonomic CLIs:

- **Never prompts, no ANSI.** Every command runs non-interactively; questions take their defaults.
- **Lists every file it wrote.** A generator ends with the files it created and updated, so the agent never spends a turn on `find` to learn what appeared. A generator that wrote nothing says so (`created[0]: no files written`).
- **Compact help.** `make:<name> --help` prints the generator's own arguments and options only, and an input error (unknown option, missing argument) is followed by that same usage, so the retry needs no separate help run.
- **Content first.** `vendor/bin/partisan` with no command shows the package dashboard (name, namespace, paths, providers, the generators available and the commands to run next) instead of the framework's full command list.

```
created[6]:
  - src/Filament/Resources/Invoices/InvoiceResource.php
  - src/Filament/Resources/Invoices/Pages/CreateInvoice.php
  - src/Filament/Resources/Invoices/Pages/EditInvoice.php
  - src/Filament/Resources/Invoices/Pages/ListInvoices.php
  - src/Filament/Resources/Invoices/Schemas/InvoiceForm.php
  - src/Filament/Resources/Invoices/Tables/InvoicesTable.php
help[1]:
  Run `php artisan make:filament-resource --help` for this generator's options
```

Files a generator writes are formatted with the package's own Pint (`vendor/bin/pint` with your `pint.json`) before they are reported, so `declare(strict_types=1)`, import order and docblock names match the package from the start. `PARTISAN_PINT=0` opts out.

## Tell the agent the generators exist

Installing Partisan is not enough for an agent working from a bare prompt: in our benchmark the agent hand-wrote every file in 15 of 15 runs where Partisan was installed but nothing mentioned it. The fix is three lines in the instructions file every agent reads at startup:

```bash
vendor/bin/partisan partisan:install --agents
```

This appends an "Artisan generators" section to your package's `AGENTS.md` (or `CLAUDE.md` when that is the only instructions file). The section is tailored to the package: the exact `make:model`, `make:command --command=<prefix>:…` and `make:filament-resource --generate --panel=<id>` invocations with your namespace, command prefix and first Filament panel, plus which of the generated files are final and which to edit. With the section in place the agent used the generator in every run.

Pair it with [laravel/pao](https://github.com/laravel/pao) for agent-optimized Pest and PHPStan output and the whole package loop stays cheap to read.

## One command to verify the result

After a change, `partisan:check` answers "does the package still boot and is the new thing wired?" in one run, which is exactly the question an agent otherwise answers with five or six improvised commands:

```bash
vendor/bin/partisan partisan:check
```

It boots the package and reports, one pass/fail line each: the providers from `composer.json` are registered; the commands and routes the package contributes; Filament panels with their resource and page counts; the package's migrations applied to an in-memory SQLite; `pint --test` on `src/` and `database/`; and whether every class under the package's autoload paths (plus `database/factories` and `database/seeders`) can be loaded. Exit code 1 when anything fails, with a `help[n]` line naming the fix, so it works as a CI step too.

## What it saves

### Method

Claude Code headless (`claude -p`), Claude Fable 5.1, Partisan 0.4.0 (the model task remeasured on 0.5.0, whose `make:model --fields` writes the columns, casts, fillable and factory definition from one spec), on a Filament v5 plugin fixture that is green at baseline (`composer test`, Pint, `partisan:check`). Three tasks, each a bare prompt that says what to build and nothing about how:

| Task | Prompt asks for |
| --- | --- |
| Resource | A Filament resource for the `Fly` model, with a default sort and an `is_active` filter (6 files) |
| Model | A `Hive` model with migration, factory and policy |
| Command | A `demo-plugin:prune-flies` console command, registered in the provider |

Three conditions, five runs per task and condition:

- **By hand**: Partisan absent; the agent writes every file itself.
- **Partisan installed**: `vendor/bin/partisan` and an `artisan` script present, agent mode off, `AGENTS.md` untouched.
- **Agent mode**: Partisan installed, agent mode on and `partisan:install --agents` run first.

Every run is verified afterwards from its diff: Pint on the files it touched, then a functional check (the panel discovers the resource with the sort and filter asked for; the classes and migration exist; `php artisan list` shows the command). All 45 runs passed both checks, so the numbers compare runs that produced equally working code. Measured 2026-09-16; the agent-mode model cell remeasured 2026-09-17 on 0.5.0.

### Results

Medians per task, cost at API list prices:

| Task | By hand | Partisan installed | Agent mode |
| --- | --- | --- | --- |
| Resource | 18 turns · 6.3k output tokens · $0.85 | 16 · 6.6k · $0.64 | **10 · 2.4k · $0.30** |
| Model | 12 · 5.2k · $0.62 | 8 · 2.9k · $0.47 | 12 · 2.7k · **$0.33** |
| Command | 12 · 2.3k · $0.36 | 10 · 2.1k · $0.26 | **8 · 1.6k** · $0.37 |
| All 15 runs, mean | 14.9 turns · $0.58 | 12.1 · $0.47 | **10.4 · $0.36** |

### What the transcripts show

- **The Filament resource is the headline.** Every agent-mode run had the same shape: look around, `make:filament-resource Fly --generate --panel=demo`, read the generated form and table, three one-line edits (toggle default, default sort, filter), `partisan:check`. No help reads, no file rewritten whole, four of the five runs within three cents of each other. By hand, the agent writes six files from memory and then verifies at length.
- **Small scaffolds save tokens, not turns.** On the model task the agent reads the generated files back, which costs about as many turns as writing them, but half the output tokens. With `--fields` on 0.5.0 the model and migration come out final and were never edited in any run; what remains is one edit to the factory's fake values and one to the policy's return values, and the cell went from $0.39 to $0.33. The command task went from 16 turns to 8 once the `AGENTS.md` section carried the exact `--command=` recipe, so the agent no longer read `--help` first.
- **Installed is not discovered.** With Partisan installed but nothing mentioning it, the agent never ran a generator. The `AGENTS.md` section is what makes the tool reachable; the `--generate` migrations, Pint on generated files and `partisan:check` are what make each turn count.
- **Where the money goes.** Output tokens and cache writes (tool output entering the context) are 80 to 85% of the bill in every condition. That is why agent mode keeps its output short: a help dump or a 200-line command list costs as much as writing a file.

The harness, prompts and per-run tables live with the fixture package we benchmark against; the same tasks are rerun after every Partisan release so the numbers above stay comparable.
