Agents & Snapshotting
Render a component to an image or an ANSI frame from the command line, with no TTY and no running app — so you, a reviewer, or a coding agent can see what it looks like.
Overview
vendor/bin/phui-snapshot mounts a component against the same fake terminal TestScreen uses, plays whatever input you give it, and writes the frame out. Nothing touches a real terminal, so it runs in CI, in a hook, or from an agent, and the same input always produces the same bytes.
PNG output shells out to freeze (brew install charmbracelet/tap/freeze); --film and --gif render one frame per input token and additionally need ImageMagick. The ANSI path needs neither.
Write a target file
The tool takes a PHP file that returns a component — an instance, or the name of a class it can construct with no arguments:
use App\Ui\Dashboard;
return new Dashboard(user: 'sam');Built-ins and components that take props need a parent to supply them, so return a small host that mounts the real thing:
use Phui\Component;
use Phui\Components\Select;
use Phui\Nodes\Container;
use Phui\Nodes\Node;
return new class extends Component
{
public function build(): Node
{
return Container::make([
Select::mount()->props(items: ['main', 'develop'], selected: 0),
])->tw('fixed-x-30 p-1');
}
};Take the shot
vendor/bin/phui-snapshot ui/dashboard.php --size=80x24That writes ui/dashboard.ansi — the frame with its colours intact, ready to cat in a terminal. Add --png for an image:
vendor/bin/phui-snapshot ui/dashboard.php --size=80x24 --png=docs/dashboard.pngDrive it first
--keys takes space-separated tokens, played in order, so you can photograph a component after some input rather than at rest:
vendor/bin/phui-snapshot ui/picker.php --keys='enter down down enter'Tokens cover typed characters, named keys, modified presses, mouse input, and the fake clock — the full list, along with every option the command takes, is in the Snapshot CLI reference.
One option is worth calling out here: --trim is what makes a shot of one small component look like that component rather than a mostly-empty terminal, so reach for it whenever the subject is smaller than the screen.
Give your agent eyes
An agent working on a TUI is normally blind. It edits render code, runs the tests, and never sees a frame — so it reports that a layout works while the border is broken and the title overflows. An agent that renders what it just wrote catches this the way you would: by looking at it. As is often the case when working with agents, closing the loop can make a huge difference to the output.
Both formats work as agent input. The .ansi file is plain text — reading it puts the frame straight into the agent's context, colours intact, no image support required. --png gives a vision-capable agent the pixels instead. And because --keys scripts input, the agent can look at the states that matter — the open dropdown, the focused field, the list after a scroll — not just the first frame.
Tell your agent the tool exists in your project instructions and it will use it on its own:
After changing a component, render it and look at the result:
vendor/bin/phui-snapshot path/to/target.php --trim