Skip to content

plumb_verify

Diff what you built against the design. Structured deltas, deterministic, no pixel diff. The closer.

How it works

After the agent renders a screen in code, it walks the DOM and for every element tagged data-plumb-id="<el>" (where el comes from a prior plumb_node call), it collects:

  • boxgetBoundingClientRect(){ x, y, w, h }
  • styles — a subset of getComputedStyle: background colour, text colour, font family / size / weight / line-height, padding (4 sides), gap, flex direction, justify / align, border radius / colour / width, opacity
  • texttextContent for text nodes

It assembles a rendered payload and calls plumb_verify. The tool re-fetches the live PDS, joins by el, runs every comparison with tolerances, returns a sorted list of structured deltas.

Inputs

FieldTypeNotes
idstring · optionalScreen id (preferred).
namestring · optionalScreen name (plugin path).
fileKeystring · optionalFile key (REST path).
renderedRenderedElement[] · requiredWhat the agent built.
tolerancesobject · optionalOverride default thresholds for px / colour.
depthnumber · optionalPDS depth to fetch. Default 12.

Each RenderedElement:

ts
{
  el: string;                            // matches the PDS handle
  box: { x: number; y: number; w: number; h: number };
  text?: string;                         // for TEXT nodes
  styles?: Record<string, string>;       // the getComputedStyle subset
}

Returns

jsonc
{
  "source": "plugin",
  "screen": "Settings → Profile",
  "matched": 42,
  "rendered": 43,
  "unmatched": 1,
  "ok": false,
  "deltas": [
    { "el": "cta",    "name": "Save", "kind": "fill",
      "expected": "$cBrand", "actual": "#0a6dc2",
      "diff": 11, "severity": "error" },
    { "el": "title",  "name": "Profile", "kind": "size.w",
      "expected": 528, "actual": 530, "diff": 2, "severity": "warn" },
    { "el": "ghost",  "name": "ghost", "kind": "missing-in-pds",
      "expected": null, "actual": "ghost", "severity": "warn" }
  ]
}

ok: true means no errors. Warns are differences within tolerance you might have meant.

Delta kinds

KindWhat it compares
size.w, size.hBox width/height
layout.flowFlex direction
layout.gapAuto-layout gap → CSS gap
pad.{top,right,bottom,left}Auto-layout padding → CSS padding
layout.justify, layout.alignjustifyContent / alignItems
fillNon-text background colour
text.colorText node colour
text.charsText content
text.size, text.weight, text.lh, text.familyType style
radiusBorder radius
stroke, stroke.widthBorder colour and width
opacityElement opacity
missing-in-pdsElement you rendered that doesn't exist in the design

Default tolerances

  • Pixels: ok ≤ 1px, warn ≤ 3px, error > 3px
  • Colour: ok ≤ ΔE 6, warn ≤ ΔE 24, error > 24
  • Text size: ok ≤ 0.5px, warn ≤ 1.5px
  • Text weight: warn if off by ≤ 100, error otherwise
  • Line height ratio: warn if off by > 0.05, error if > 0.15
  • Opacity: warn if off by > 0.05, error if > 0.15

Override per call with tolerances.

When the agent should use it

  • After implementing a screen — confirm pixel-accuracy before reporting back.
  • Iteratively while debugging a layout that doesn't quite match.
  • In code-review / CI — generate a verify report from a Playwright snapshot.

Notes

Both paths supported (plugin and REST).

Verification is structural, not visual — no pixel diff, no machine-vision. The agent only has to expose data-plumb-id on rendered elements; the rest is deterministic.

Up to 150 deltas per call (MAX_DELTAS). Truncation is flagged via truncated: true.

Released under the MIT License.