agentleFS
jocarrdjocarrd/crux-agents/skills/visual-diff/SKILL.md

visual-diff

Skill4 starsChanged 17 days agoMITView on GitHub

Objectively measure how far a rendered output (PDF, page, image) deviates from a visual reference, with a cell grid, mean error per cell, pre-blur against antialiasing, zones with semantic names and overlays that reveal misalignment. Use when an official design exists to compare against, when you want a ranking of which zones are worst, or as a safety net after a batch of layout changes that eyeball review doesn't cover.

2 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

1 rule. About 0 are common, 1 is distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Fix the data before comparing: If the current render carries different data from the reference, you are measuring content and not design, …

    line 68

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

visual-diff

It answers one specific question: how far am I from the reference, and where. It is the measurable half of visual work; the other half, when there is no reference and the criterion is a person's, is /render-loop.

When to use each

SituationTool
There is an official design to compare againstthis one
Before accepting a batch of changesthis one
Subjective notes: "bigger", "more air"/render-loop
Confirming a change is noticeable/render-loop

Usage

python3 <this-skill-directory>/scripts/imgdiff.py <current> <reference> \
  --out diff-out --grid 12x18 --blocks blocks.json

It accepts PDFs (rasterized with pdftoppm) or images. It produces report.md sorted by descending deviation, scores.json and one overlay per page. It exits with code 1 if any cell exceeds the threshold, so it works directly as a gate in a hook or in CI.

It requires python3 with numpy and Pillow, and poppler for PDFs.

How it works, and why

  1. Rasterize both outputs at the same resolution and fit the current one to the reference's size.
  2. Apply a pre-blur. This is what makes comparison between different renderers usable: without it, antialiasing dominates the signal and everything looks different. With it, the real defects of position, size and colour survive.
  3. Split into a grid and compute the mean absolute error per cell. One number per page says nothing actionable; per cell, it does.
  4. Ignore cells that are almost white in both. They are the margins: without this filter they inflate the average and hide the real defects.
  5. Label each cell with its semantic block. A report saying "the header is shifted" is actionable; one saying "cell 3,7" forces you to go look at the PNG to understand what is happening.
  6. Generate the overlay. What matches comes out grey; misalignment shows up as a coloured ghost, blue where there is content only in the current one and warm where there is only in the reference.

The semantic blocks

A JSON with the zones in normalized 0 to 1 coordinates, optionally per page:

[{"name": "header",  "page": 1, "box": [0, 0, 1, 0.2]},
 {"name": "left-card", "page": 1, "box": [0, 0.28, 0.55, 0.52]}]

It is worth writing once: it turns the report from a list of coordinates into a list of names where you already know where to make the change.

The rule that decides whether the measurement is worth anything

Fix the data before comparing. If the current render carries different data from the reference, you are measuring content and not design, and any real difference gets buried under the noise.

The normal thing is to expose a mode in the application itself that fills the output with the same data as the reference. Without that, the diff is inconclusive and shouldn't be interpreted.

Systematic coverage

A comparison against a reference measures the case you have rendered. If the output has fixed-size canvases (typical in reports and documents), content that doesn't fit is clipped silently, and eyeball review only detects what one thinks to look at.

That is why it is worth accompanying it with a battery of scenarios that renders the edge cases: the longest possible text, extreme values, empty fields, all the variants of a label. It is the part that must be run without fail after touching typography or spacing.

Documented false positive

If artifacts appear (black headers, badly composed blocks) in some viewers and not in others, suspect the renderer before the design. The usual cause is launching the headless browser without the same flags the production pipeline uses.

Any comparison script must replicate exactly those flags. This cost one team a whole working day before it was documented.

Related

  • /render-loop: iterate when there is no reference and the criterion is subjective
  • /visual-test: inspect web pages across viewports

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.