Packstub

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, 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 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:

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 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:

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.