Skip to content

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:

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

php
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

bash
vendor/bin/phui-snapshot ui/dashboard.php --size=80x24

That writes ui/dashboard.ansi — the frame with its colours intact, ready to cat in a terminal. Add --png for an image:

bash
vendor/bin/phui-snapshot ui/dashboard.php --size=80x24 --png=docs/dashboard.png

Drive it first

--keys takes space-separated tokens, played in order, so you can photograph a component after some input rather than at rest:

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

markdown
After changing a component, render it and look at the result:

vendor/bin/phui-snapshot path/to/target.php --trim

Released under the MIT License.