Visual reference CLI for curated put.io screenshots.
Build and serve static galleries from repo-local manifests so agents can inspect UI evidence before they edit.
Install in an app repo that owns visual references:
pnpm add -D @putdotio/vrefCreate a repo-local manifest and screenshots:
.vref/
manifest.json
screenshots/Build the gallery:
vref buildValidate without writing index.html:
vref validate --output json
vref build --check --output jsonAdd a capture to the gallery. vref encodes it to lossless webp, writes it under
.vref/screenshots/, and appends the manifest entry:
vref screenshot add ./dist/tmp/home.png --json '{"id":"home","title":"Home","group":"Main pages","platform":"Web","device":"Chrome 1440","tags":["home"],"notes":["Home grid."]}'Open the gallery locally:
vref serveAgents should inspect the command schema before automating:
vref describe --output jsonWhen vref output is piped or captured in a non-interactive process, JSON is
the default. Use --fields to keep automation responses small:
vref validate --fields screenshotCount,groupCount
vref describe --fields commands,automationvref writes webp only, from .png, .jpg, .jpeg, or .webp sources. Encoding is
lossless unless --quality 1-100 asks for lossy. A webp source is copied
verbatim, keeping the fidelity it already had, unless its bytes are not really
webp or it carries an EXIF orientation a verbatim copy could not apply.
It fills in the derived half of the manifest entry: sizeBytes from the encoded
byte length, viewport from the encoded pixel dimensions, capturedAt from the
source file's modification time, and file from the screenshot id. sizeBytes
is always measured, so it cannot drift from the file; the other three are
defaults your --json may override.
Preview an add without writing anything:
vref screenshot add ./capture.png --json '{"id":"home",...}' --dry-run --output json
vref manifest update home --json '{"title":"Home"}' --dry-run --output json
vref screenshot remove home --dry-run --output jsonMigrate an existing png or jpeg reference set. Legacy entries keep validating, so upgrading does not force this:
vref convert --dry-run --output json
vref convertThe Visual Reference Guide covers the format
choice, retina viewports, and what convert does to your originals.
vref reads .vref/manifest.json by default and writes .vref/index.html. It
stamps updatedAt whenever it rewrites the manifest.
Screenshot file paths are relative to the manifest's directory and must stay
inside it.
{
"version": 1,
"title": "put.io Roku visual reference",
"description": "Curated Roku screenshots for review and design comparison.",
"updatedAt": "2026-05-19T13:35:00.000Z",
"screenshots": [
{
"id": "home",
"title": "Home",
"group": "Main pages",
"platform": "Roku",
"device": "Roku 720p",
"viewport": { "width": 1280, "height": 720 },
"file": "screenshots/roku-720p/home.webp",
"capturedAt": "2026-05-19T13:34:00.000Z",
"sizeBytes": 22788,
"tags": ["home", "navigation"],
"notes": ["Home menu with Files, Search, and Settings visible."]
}
]
}Append a metadata-only entry for a screenshot file you are placing yourself.
When you have the captured image, prefer vref screenshot add above:
vref manifest add --json '{"id":"settings","title":"Settings","group":"Main pages","platform":"Roku","device":"Roku 720p","viewport":{"width":1280,"height":720},"file":"screenshots/roku-720p/settings.webp","capturedAt":"2026-05-19T13:35:00.000Z","sizeBytes":39716,"tags":["settings"],"notes":["Settings page."]}' --dry-run --output jsonRemove --dry-run after the preview looks correct. This command only edits
manifest metadata; it never encodes or copies the image.
See Contributing for setup, validation, and pull request expectations.
MIT, see License
