A FIELD GUIDE TO LARAVEL · VOLUME II · THE ECOSYSTEM
ENTRY II.46 · AGENT TOOLING
Laravel PAO
Laravel\Pao · Package · first recorded 7 April 2026, v0.1.0 on Packagist; announced 14 May 2026, a default dev dependency of new apps
Agent-optimised output. When a coding agent, not a person, runs PHPUnit, Pest, PHPStan, Rector or artisan, PAO swaps the decorated terminal output for compact JSON or stripped text. Your terminal is unchanged; new apps ship it.
Specification
Kind Dev dependency loaded by Composer's file autoload; no command of its own
Driver One per tool: PHPUnit, Pest, Paratest, PHPStan, Rector; Artisan via a provider
Consumer Claude Code, Cursor, Devin, Gemini CLI and others, detected by env var
Installed by composer require laravel/pao --dev (already in new apps)
Voice none. PAO_FORCE=true switches it on without an agent
Scales by Output stays one size at 10 or 1,000 tests; PHPStan list capped, -v for all
Range Cloud: not deployed: the default build runs composer install --no-dev
Forge, VPS: not deployed: Forge's composer install uses --no-dev
Vapor: not deployed: build steps use composer install --no-dev
Neighbours
Boost gives an agent context about the app: an MCP server, guidelines and skills. Pint has an agent output format of its own, a switch for one tool. PAO's distinction is that the command does not change: it detects the agent from the environment and reshapes the output of each tool it runs.
Field marks
laravel/pao in require-dev
PAO_FORCE=true
AI_AGENT · CLAUDECODE · CURSOR_AGENT
one JSON object on stdout
Fig. II.46.1 · One test run, two outputs
Parts
1 Agent. Claude Code, Cursor or another; it sets CLAUDECODE, CURSOR_AGENT or AI_AGENT in the environment it runs in.
2 Autoload hook. A Composer file autoload, run by every PHP process that loads Composer; it returns unless an agent is found.
3 Driver. Picked from the command: PHPUnit gets --no-output injected, Pest is silenced, PHPStan and Rector use JSON mode.
4 Test runner. Runs unchanged. At shutdown PAO reads the result from PHPUnit's own result facade, not by scraping the text.
5 JSON. One object: counts, duration, failures with file, line and message. Coverage and profiling land in a raw array.
6 Artisan. A different path: the console OutputStyle is rebound and decoration disabled, so about loses its boxes.
Hidden joinery
In Docker, Sail or DDEV the agent's variables stop at the container wall; forward them in compose.yaml or with docker compose exec -e, or PAO never wakes. Paratest results are merged by a wrapper runner before the one JSON object is written. PHPStan's per-file list is capped, with a hint to pass -v.
Every line checked on 2026-10-08 against docs, source, Packagist and The Monitor; see the ledger.
TITLE
Laravel PAO · output for agents
SOURCES
github.com/laravel/pao · packagist.org/packages/laravel/pao · github.com/laravel/agent-detector · github.com/laravel/laravel/blob/13.x/composer.json · laravel.com/blog/introducing-laravel-pao-cleaner-output-for-ai-agents · github.com/laravel/pint · pestphp.com/docs/cli-api-reference · laravel.com/cloud/docs/deploy-guides/laravel · laravel.com/forge/docs/sites/the-basics · docs.vapor.build/projects/deployments · laravel.com/docs/13.x/boost · Monitor 572
STATUS
Verified · 2026-10-08
SHEET
II.46 of 48
REV
A · 2026-10-08
DRAWN
BS
FINISH
All faces, including the back