aa-conversion-funnel-a…
Analyzes a multi-step conversion funnel to find where visitors drop off and which steps have…
Reconcile a converted/built web page against its source prototype with two complementary probes — a PIXEL/layout diff (stretched images, dropped wraps, blank renders, colour flips) and a STRUCTURAL content+typography diff (dropped/mis-slotted headings, eyebrows, CTAs;
$ npx -y skills add adobe/skills --skill diff --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/diffContext preview
The summary Claude sees to decide when to auto-load this skill.
Reconcile a converted/built web page against its source prototype with two complementary probes — a PIXEL/layout diff (stretched images, dropped wraps, blank renders, colour flips) and a STRUCTURAL content+typography diff (dropped/mis-slotted headings, eyebrows, CTAs;
name: diff description: Reconcile a converted/built web page against its source prototype with two complementary probes — a PIXEL/layout diff (stretched images, dropped wraps, blank renders, colour flips) and a STRUCTURAL content+typography diff (dropped/mis-slotted headings, eyebrows, CTAs; rendered-face font forks). Stack-agnostic via profiles (eds | generic). Use after converting a prototype to EDS/AEM (the stardust `deploy` skill Step 10), or for any prototype↔build fidelity check; invocable as the stardust `diff` skill and from workflows. license: Apache-2.0 compatibility: Requires Node 22+, Playwright with Chromium resolvable from the project, playwright-cli on PATH, and the impeccable skill (github.com/pbakaus/impeccable) installed alongside stardust.
Two probes that compare a **source** prototype against a **built** page. They catch **disjoint** failure classes — run BOTH; either alone gives a false "looks fine".
Both are framework-agnostic Playwright probes that compare two rendered URLs by **computed style + DOM** (not pixels). All stack-specific language lives in a **profile** (`--profile eds|generic`); the comparison logic is generic.
Not for: a single static file with no JS decoration (use the build/harness URL so components are decorated — a raw `.plain.html` has no roles to classify).
| Probe | Script | Sees | Blind to | |---|---|---|---| | **Pixel / layout** | `skills/diff/scripts/visual-diff.mjs` | stretched images, dropped max-width wraps, blank renders, surface/ground colour flips, image-count gaps | "right text, wrong slot"; a dropped CTA (full pixels, plausible colours → no flag) | | **Structural content + type** | `skills/diff/scripts/content-diff.mjs` | MISSING / ROLE-SWAPPED headings·eyebrows·CTAs, invented/dropped body copy, rendered-FACE font forks (width probe); dropped `placeholder`/`aria-label`/`title` values, missing/wrong/moved icons — on the main root AND the `header`/`footer` chrome roots by default | geometry / layout regressions |
`content-diff` extracts an ordered, role-classified inventory (`heading` / `eyebrow` / `cta`+href / `body`) from each root — the `--main` root(s) plus, by default, the `header` and `footer` chrome roots — classifying by **computed style + tag** so the prototype's DOM and the built DOM compare symmetrically, then diffs them root by root; a second inventory per root carries the `placeholder` / `aria-label` / `title` values and the icons.
# Prereq 0: playwright importable from the project root — probe
# node -e "import('playwright').then(()=>process.exit(0))"
# and on failure install it AS A devDependency (npm i -D playwright pixelmatch pngjs cheerio
# --legacy-peer-deps — never --no-save: a --no-save install is PRUNED by the next real npm i,
# recorded twice in one run; extract SKILL.md § Setup). Run the copied scripts from the project
# root, not the plugin: ESM resolves `playwright` from the script's own location.
# Copy the WHOLE skills/diff/scripts/ dir: content-diff imports its local diff-profiles.mjs
# AND content-inventory.mjs. (The deploy gates #93/#94 now use their OWN synced copies in
# skills/deploy/scripts/ — A6/A2 are independent of this skill; the two copies must stay in
# sync until the diff-skill abrasion PR consolidates them.)
# Prereq: a RENDERABLE source. Static → serve from its own dir (python3 -m http.server).
# The build URL must be the DECORATED page (live/preview or a local harness), not raw markup.
# ONE server, ONE port — probe before starting one (curl is always present, lsof is not):
curl -sI localhost:8791/ | head -1 # 200/404 = something serves the port; no line = free
curl -sI localhost:8791/<prototype>.html | head -1 # 200 = it serves YOUR dir: reuse it
command -v lsof >/dev/null && lsof -nP -iTCP:8791 -sTCP:LISTEN # optional: names the pid
# Nothing answered → start yours. Answers but not your file → a foreign server: never kill
# a listener you did not start; prefer a per-project port — a stale server from another
# project makes both probes measure a foreign page. `lsof … || echo free` is not a probe —
# without lsof it prints "free" beside a live listener (recorded: a second server on the
# same port died at once and the round chased 404s).
PROTO="http://localhost:8791/<prototype>.html"
BUILD="https://<branch>--<repo>--<owner>.aem.page/<path>" # or http://localhost:3000/<harness>
# 1. PIXEL/layout
node skills/diff/scripts/visual-diff.mjs "$PROTO" "$BUILD" --profile eds --sections ".hero"
# 2. STRUCTURAL content + type
node skills/diff/scripts/content-diff.mjs "$PROTO" "$BUILD" --profile eds # --json dumps both inventoriesFlags (both tools): `--profile eds|generic` (default `eds`), `--width <px>` (default 1280), `--main <selector[,selector…]>` (content root; content-diff defaults from the profile and takes a comma-separated list — every root is inventoried and diffed on its own and each finding line carries its root as `[root]`; visual-diff takes one selector, default `main`), content-diff only: `--chrome` / `--no-chrome` (default on — the `header` and `footer` roots, resolved as the first `<header>`/`[role=banner]` and `<footer>`/`[role=contentinfo]` outside the main root(s), are compared beside it; a side lacking one is measured as empty there and the root line says so), plus the live-target set (shared engine: `scripts/live-session.mjs` — every context sends the real-Chrome UA **and** the standard Chrome request headers; the UA alone still 403s on Akamai-class bot management):
Repo: adobe/skills
Analyzes a multi-step conversion funnel to find where visitors drop off and which steps have…
Generates a concise, executive-ready performance summary covering key metrics, trends, and…
Produces a compact KPI digest showing how key metrics changed over a period and what's…
Compares the performance of two or more audience segments across key metrics side by side.…
Identifies which items (pages, campaigns, products, channels, regions) had the biggest…
Comprehensive dimension analysis and reporting for CJA. Use this skill whenever the user…