i’ve been super into OpenCode lately.. and something i’ve noticed - when it runs Pint, it gets back colorful human output and has to guess what happened..

so i’ve opened a PR to add --format agent to Pint - no guarantees it gets merged, but here’s the idea..

this format outputs clean JSON - and auto-activates when Pint detects it’s running inside Claude Code or OpenCode..

the output

{"status":"pass"}

or when there are issues:

{"status":"fixed","files":[{"path":"app/Models/User.php","fixers":["binary_operator_spaces","no_unused_imports"]}]}

three status values: pass (clean), fail (issues found in --test mode), fixed (issues auto-corrected)..

why this matters

AI agents burn tokens parsing human-formatted output and guessing what happened.. with structured JSON, your agent knows exactly which files failed and which fixers were applied - it can take targeted action instead of re-running commands or asking clarifying questions..

how it works

Claude Code sets CLAUDECODE, OpenCode sets OPENCODE.. Pint checks for these:

public static function runningInAgent(): bool
{
    return (bool) getenv('OPENCODE') || (bool) getenv('CLAUDECODE');
}

when one of these env vars is detected, Pint automatically switches the output format to agent:

if ($this->runningInAgent() && $this->format === 'txt') {
    $this->format = 'agent';
}

basically, if you’re in an agent environment and haven’t explicitly set a format, it just does the right thing.. no config needed..

for other tools or custom integrations:

./vendor/bin/pint --format agent
./vendor/bin/pint --test --format agent  # report without fixing