Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Pao Laravel Package

nunomaduro/pao

Laravel PAO detects when PHPUnit, Pest, Paratest, PHPStan, Rector, or Artisan run inside an AI agent and swaps verbose human output for compact structured JSON. Zero config, installs as a dev dependency, and leaves normal terminal output untouched.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Build vs. buy for the AI developer loop. PAO is a one-line dev dependency that converts PHPUnit, Pest, Paratest, PHPStan, Rector, and Artisan output into compact structured JSON when it detects an agent (Claude Code, Cursor, Devin, Gemini CLI). The alternative is building our own output formatter or maintaining per-tool prompt conventions. Buying costs a line in composer.json; building costs a permanent compatibility treadmill against PHPUnit/Pest printer internals. This package lets us defer that build decision until we know the payoff is real.
  • Whether to invest in agent-assisted development as a roadmap bet. PAO is a cheap, measurable proxy for a bigger strategic question: how much of engineering throughput should we shift toward agent-driven workflows? Adoption gives us a controlled pilot with a concrete metric — token spend per test run and per Artisan command — instead of an opinion.
  • Context budget as a product constraint. The headline claims (up to ~99.8% fewer tokens on a 1,000-test suite; ~70–75% reduction on about, db:show, migrate:status) reframe CI output as an input to a cost model, not just a log. If we accept that agents waste context on dots, progress bars, and box-drawing characters, PAO is the cheapest available lever on inference cost and on agent task success rate for large suites.
  • Where to spend tooling budget across repos. PAO is scoped to a subset of our stack — PHP 8.3+, PHPUnit 12–13, Pest 4–5, Laravel 12+. That constraint is itself a portfolio decision: it tells us which repos are eligible for the agent pilot and which need upgrading before they can participate.
  • Standardizing agent-facing tool output across languages. PHP is the first domain where a vendor-backed, zero-config option exists. Adopting it sets a precedent and a pattern (structured JSON, constant-size results, human output untouched) that we can then demand from equivalent tooling in our Node, Python, or Go repos — or build if no equivalent exists.
  • Reversibility as a decision input. Because it is --dev-only, touches no application code, no HTTP path, no queue, and no database, and only activates when it detects an agent, the decision is a one-line install and a one-line removal. That asymmetry — tiny downside, potentially meaningful upside — is exactly the shape of decision we should be making quickly rather than researching to death.

When to Consider This Package

Adopt when all of the following hold:

  • A meaningful share of our PHP engineers already use an agent daily (Claude Code, Cursor, Devin, Gemini CLI) and drive test/analysis commands from it, not just autocomplete in an editor.
  • Our target repos are on PHP 8.3+, PHPUnit 12–13, Pest 4–5, and Laravel 12+. Anything on PHP 8.2 or PHPUnit 11 is out of scope and should not be forced in.
  • The candidate repos have suites large enough for context crowding to actually bite — a few hundred tests or more. Below that, the token savings are real but immaterial, and the pilot will not produce a defensible result.
  • We can isolate the change to a pilot set of repos first. A dev dependency still participates in lockfile resolution and can create transitive constraint conflicts in older projects.
  • We have explicit, automated verification that PAO's exit code matches the native tool's exit code on failure, error, timeout, and partial runs. The changelog shows repeated fixes here (exit code 1 on phpunit, test results being displayed on runtime exits). If it ever returns success on a failing suite, we have silently disabled our quality gate. Test this; do not assume it.

Look elsewhere, or delay, when:

  • Agent usage is low or concentrated in a few enthusiasts. The value is entirely a function of agent adoption; with none, the payoff is approximately zero.
  • Repo constraints block it. Pre-8.3 PHP or PHPUnit ≤11 makes this a non-starter without an upgrade project that should be justified on its own merits.
  • We need a stable contract. There is no published output schema, docs are README plus changelog, and there are zero dependents outside the author's own usage. If our internal tooling or dashboards are going to parse PAO's JSON, we would be building on an undocumented interface that is likely to churn.
  • Our CI/log pipeline assumes human-readable text. PAO's activation heuristic keys off environment signals from fast-moving third-party tools. False negatives degrade gracefully (normal output); false positives are the hazard — JSON surfacing to a human or a log parser that expects text, including in containers that happen to set similar env vars. If we cannot control or audit those signals in CI, hold off.
  • We need complete static-analysis output. PHPStan errors are capped at 30 per run and grouped by file. That is a sensible token decision, but on large legacy codebases it means an agent may never see the full error set. If our remediation workflow depends on exhaustive error enumeration, this is the wrong layer to truncate at.
  • We require vendor stability guarantees. The package moved namespaces (nunomaduro/pao → laravel/pao at v1.0.6). Pin the canonical name everywhere and expect to upgrade in lockstep with the test toolchain indefinitely — most releases are compatibility patches for upstream printer/plugin internals.

How to Pitch It (Stakeholders)

To executives — one paragraph. Our engineers' AI coding agents waste a large share of their context and our inference budget reading dots, progress bars, and box-drawing characters. Laravel PAO is a free, MIT-licensed, dev-only package that detects when a tool is being run by an agent and swaps that verbose output for roughly eight lines of structured JSON — up to ~99.8% fewer tokens on a 1,000-test suite and ~70–75% fewer on common Artisan commands. It does not touch production code, does not change anything human developers see in their terminals, and costs one line in a dev dependency list to add or remove. I am recommending a scoped pilot on two or three of our largest eligible PHP repos with a clear success metric — token spend per test run and agent task completion rate — and a defined exit if the numbers do not move.

To engineering — the practical case. Install with composer require laravel/pao --dev. No config file, no CI changes. PAO hooks in through Composer's autoloader and intercepts PHPUnit, Pest, Paratest, PHPStan, Rector, and — on Laravel 12+ via auto-discovered service provider — Artisan output. It only activates inside an agent, so your terminal, your colors, and your muscle memory are untouched. Failures still carry file paths, line numbers, and messages; deprecations, warnings, and notices get their own *_details arrays; Pest plugin output like --coverage and --profile is preserved in a cleaned raw array rather than dropped.

What I need from engineering before we broaden it:

  1. Exit-code parity. Prove PAO's exit code equals the native tool's exit code across pass, fail, error, timeout, and interrupted runs. This is the gating item — everything else is optimization.
  2. Activation audit. Confirm which environment signals our CI containers expose and whether any could trigger PAO where a human or log parser expects text.
  3. Upgrade coupling. Agree that PAO versions track PHPUnit/Pest upgrades, and pin the canonical laravel/pao name in our tooling and docs.
  4. Truncation policy. Accept or override the 30-error PHPStan cap on our largest repos, and know which repos it affects.

The honest counterargument, stated up front. This package has 728 stars and zero dependents, documentation is a README plus a changelog, and there is no published output schema. It is early. That is precisely why the recommendation is a bounded pilot rather than a standard — we are buying an option on a strategic bet for the price of one line in a dev dependency list, and we can unwind it in the same amount of time.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin