{"_id":"@appliqation/visual-regression","_rev":"4-05c199fcf2df7593eec5a6f43ad46c39","name":"@appliqation/visual-regression","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.0":{"name":"@appliqation/visual-regression","version":"0.1.0","license":"MIT","_id":"@appliqation/visual-regression@0.1.0","maintainers":[{"name":"archana6","email":"accounts@appliqation.io"}],"homepage":"https://github.com/appliqation/visual-regression#readme","bugs":{"url":"https://github.com/appliqation/visual-regression/issues"},"bin":{"appliqation-visual-regression":"dist/cli/index.js"},"dist":{"shasum":"a7b30e22d19e2d40ff65a13c3b01ef4c9a45daea","tarball":"https://registry.npmjs.org/@appliqation/visual-regression/-/visual-regression-0.1.0.tgz","fileCount":21,"integrity":"sha512-YyTZnwACtX6gECC3+AALjAmSuCXB4Wk5R26NOmjzUIqRvU61SVlCVVw+wp6XwfN2PWNCrfL+HBVzhuFmbTJMXQ==","signatures":[{"sig":"MEUCIEKbYbWnCtpGp7KZJBjAcAqbBQbE0mKxtl25Xif2ZhGGAiEAkAksK7A7xkAes3To0UyuHZrvZF31aawsC5JC9vYw6fk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":64631},"type":"module","engines":{"node":">=20"},"gitHead":"d58f877f9e1a2b199d7398365af3776df83806fa","scripts":{"dev":"tsx src/cli/index.ts","lint":"eslint src --ext .ts","test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest"},"_npmUser":{"name":"archana6","email":"accounts@appliqation.io"},"repository":{"url":"git+https://github.com/appliqation/visual-regression.git","type":"git"},"_npmVersion":"11.7.0","description":"Standalone agent that checks a page for real visual regressions by diffing it against its own live production counterpart — no stored baseline files, no manual baseline-approval workflow. Declines rather than compares when no production equivalent exists.","directories":{},"_nodeVersion":"23.10.0","dependencies":{"pngjs":"^7.0.0","dotenv":"^16.4.7","commander":"^13.1.0","pixelmatch":"^7.2.0","playwright":"^1.51.0","@appliqation/agent-core":"^0.1.5"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.3","eslint":"^9.39.5","vitest":"^3.2.7","@eslint/js":"^9.39.5","typescript":"^5.8.2","@types/node":"^22.13.10","@types/pngjs":"^6.0.5","typescript-eslint":"^8.67.0"},"_npmOperationalInternal":{"tmp":"tmp/visual-regression_0.1.0_1788164107501_0.40341428181264516","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@appliqation/visual-regression","version":"0.1.1","license":"MIT","_id":"@appliqation/visual-regression@0.1.1","maintainers":[{"name":"archana6","email":"accounts@appliqation.io"}],"homepage":"https://github.com/appliqation/visual-regression#readme","bugs":{"url":"https://github.com/appliqation/visual-regression/issues"},"bin":{"appliqation-visual-regression":"dist/cli/index.js"},"dist":{"shasum":"3ec66f412b4a43bf20a2485a2b2877e8faf408b2","tarball":"https://registry.npmjs.org/@appliqation/visual-regression/-/visual-regression-0.1.1.tgz","fileCount":21,"integrity":"sha512-H+39Acs69XSQ8MsbZgZ5skjxMcoegQYJobYGMxwFFAg4g2RUXFq+SyYNM1KMQjH3f8simibwy7RSHMn/3ykM5g==","signatures":[{"sig":"MEUCIQD7KP8pboGzI5XgjzT+Ggijmiu2uXRl3XIFtHMuZgKvOAIgCLxiR4Hwd7Mq5v7EBuxGlKJyYo9oTJHK0jDjVYKChTo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":64570},"type":"module","engines":{"node":">=20"},"gitHead":"3721e7cda362b3b9d19f4e4516fe337cf1fe48f4","scripts":{"dev":"tsx src/cli/index.ts","lint":"eslint src --ext .ts","test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest"},"_npmUser":{"name":"archana6","email":"accounts@appliqation.io"},"repository":{"url":"git+https://github.com/appliqation/visual-regression.git","type":"git"},"_npmVersion":"11.7.0","description":"Standalone agent that checks a page for real visual regressions by diffing it against its own live production counterpart: no stored baseline files, no manual baseline-approval workflow. Declines rather than compares when no production equivalent exists.","directories":{},"_nodeVersion":"23.10.0","dependencies":{"pngjs":"^7.0.0","dotenv":"^16.4.7","commander":"^13.1.0","pixelmatch":"^7.2.0","playwright":"^1.51.0","@appliqation/agent-core":"^0.1.5"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.3","eslint":"^9.39.5","vitest":"^3.2.7","@eslint/js":"^9.39.5","typescript":"^5.8.2","@types/node":"^22.13.10","@types/pngjs":"^6.0.5","typescript-eslint":"^8.67.0"},"_npmOperationalInternal":{"tmp":"tmp/visual-regression_0.1.1_1788165410353_0.6925020278103735","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@appliqation/visual-regression","version":"0.1.2","license":"MIT","_id":"@appliqation/visual-regression@0.1.2","maintainers":[{"name":"archana6","email":"accounts@appliqation.io"}],"homepage":"https://github.com/appliqation/visual-regression#readme","bugs":{"url":"https://github.com/appliqation/visual-regression/issues"},"bin":{"appliqation-visual-regression":"dist/cli/index.js"},"dist":{"shasum":"dee8931b2c257abbd40a53d8c1c3fe5759693b8b","tarball":"https://registry.npmjs.org/@appliqation/visual-regression/-/visual-regression-0.1.2.tgz","fileCount":21,"integrity":"sha512-enBVOIUrbG+jnHdpzSX+m7UlW7ohsbNRQPz3yNaYTURmsI7MNYXptjNEz9JRTOsjO72gv2QSSv/acc7h84e6Bg==","signatures":[{"sig":"MEQCIAxiw2UkDTbqnXYGOFcUdNHcN9yxwQxYKYc/7M2IwMObAiBCZqBqmqHIPWUsTSdEGiMyP4smbZXJ41YPE1r2ikBubw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":67346},"type":"module","engines":{"node":">=20"},"gitHead":"57623e68d3ea00eb370eadf4b67707af054a4d2b","scripts":{"dev":"tsx src/cli/index.ts","lint":"eslint src --ext .ts","test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest"},"_npmUser":{"name":"archana6","email":"accounts@appliqation.io"},"repository":{"url":"git+https://github.com/appliqation/visual-regression.git","type":"git"},"_npmVersion":"11.7.0","description":"Standalone agent that checks a page for real visual regressions by diffing it against its own live production counterpart: no stored baseline files, no manual baseline-approval workflow. Declines rather than compares when no production equivalent exists.","directories":{},"_nodeVersion":"23.10.0","dependencies":{"pngjs":"^7.0.0","dotenv":"^16.4.7","commander":"^13.1.0","pixelmatch":"^7.2.0","playwright":"^1.51.0","@appliqation/agent-core":"^0.1.7"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.3","eslint":"^9.39.5","vitest":"^3.2.7","@eslint/js":"^9.39.5","typescript":"^5.8.2","@types/node":"^22.13.10","@types/pngjs":"^6.0.5","typescript-eslint":"^8.67.0"},"_npmOperationalInternal":{"tmp":"tmp/visual-regression_0.1.2_1788433886766_0.4193603132719026","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@appliqation/visual-regression","version":"0.1.3","description":"Standalone agent that checks a page for real visual regressions by diffing it against its own live production counterpart: no stored baseline files, no manual baseline-approval workflow. Declines rather than compares when no production equivalent exists.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/appliqation/visual-regression.git"},"homepage":"https://github.com/appliqation/visual-regression#readme","bugs":{"url":"https://github.com/appliqation/visual-regression/issues"},"type":"module","bin":{"appliqation-visual-regression":"dist/cli/index.js"},"engines":{"node":">=20"},"scripts":{"build":"tsc -p tsconfig.build.json","dev":"tsx src/cli/index.ts","typecheck":"tsc -p tsconfig.json --noEmit","lint":"eslint src --ext .ts","test":"vitest run","test:watch":"vitest"},"dependencies":{"@appliqation/agent-core":"^0.1.7","commander":"^13.1.0","dotenv":"^16.4.7","pixelmatch":"^7.2.0","playwright":"^1.51.0","pngjs":"^7.0.0"},"devDependencies":{"@eslint/js":"^9.39.5","@types/node":"^22.13.10","@types/pngjs":"^6.0.5","eslint":"^9.39.5","tsx":"^4.19.3","typescript":"^5.8.2","typescript-eslint":"^8.67.0","vitest":"^3.2.7"},"gitHead":"0590f7443cde45cb664e463ad06f114be6160208","_id":"@appliqation/visual-regression@0.1.3","_nodeVersion":"23.10.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-s14Y6bTYEL8lMzlDEgnACTmtouR9rXFcWUKSVZW1/8OwD0vFZYqP4QM1stWB5kkLlAYL3AOMvkNKlIHvfBjLGg==","shasum":"447f13e705106619c4fb20c05319b19896b08f4a","tarball":"https://registry.npmjs.org/@appliqation/visual-regression/-/visual-regression-0.1.3.tgz","fileCount":21,"unpackedSize":68426,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCnli0ZCocSCh80HUdLjeAvF78DPvZW+GWDq2Yt09BwbAIhAIIFntUhHEePDfCKwFtKU6p37Ho66K3KIH5x4z0yQhac"}]},"_npmUser":{"name":"archana6","email":"accounts@appliqation.io"},"directories":{},"maintainers":[{"name":"archana6","email":"accounts@appliqation.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/visual-regression_0.1.3_1788494196779_0.8172548454057982"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-31T08:15:07.309Z","modified":"2026-09-04T03:56:37.047Z","0.1.0":"2026-08-31T08:15:07.640Z","0.1.1":"2026-08-31T08:36:50.481Z","0.1.2":"2026-09-03T11:11:26.901Z","0.1.3":"2026-09-04T03:56:36.886Z"},"bugs":{"url":"https://github.com/appliqation/visual-regression/issues"},"license":"MIT","homepage":"https://github.com/appliqation/visual-regression#readme","repository":{"type":"git","url":"git+https://github.com/appliqation/visual-regression.git"},"description":"Standalone agent that checks a page for real visual regressions by diffing it against its own live production counterpart: no stored baseline files, no manual baseline-approval workflow. Declines rather than compares when no production equivalent exists.","maintainers":[{"name":"archana6","email":"accounts@appliqation.io"}],"readme":"# Appliqation Visual-Regression\n\n**Checks one route for a real visual regression by diffing it against its own live production counterpart: no stored baseline files, no manual baseline-approval workflow.**\n\nPoint it at a route and a test case. It navigates to that route on production and a target environment, masks any known dynamic regions, full-page screenshots both, pixel-diffs them for real, and has a model judge the result from the actual evidence: a genuine regression, an expected divergence, or a route that simply doesn't exist on production yet (declines rather than substituting any other baseline).\n\n## Why this exists\n\nA Playwright `getByRole` assertion can pass while the page looks broken: an overlapping modal, a button pushed off-screen by a CSS regression, invisible text from a contrast bug. Nothing else in this agent family checks appearance, only behaviour. Traditional visual-regression tooling solves this with a stored baseline image that a human has to keep re-approving every time a legitimate UI change ships; in practice, that maintenance burden is what kills most setups. This agent sidesteps it entirely by using **production itself as the baseline, fetched live at comparison time**. Production always represents current truth by definition; there's nothing to store or re-approve.\n\n## The one rule that matters more than anything else here\n\n**If the route doesn't exist on production, that's not a failure: it's not applicable.** This agent never falls back to comparing against a design file or mock (a live render vs. a Figma file is a different, unreliable problem: design fidelity, not regression detection). No production equivalent means no comparison, reported plainly, nothing forced.\n\nThe mechanical work (navigating both environments, masking, screenshotting, pixel-diffing) is entirely code-owned, never something the model claims: it happens inside one atomic `capture_and_diff` call, and the real diff statistics it returns are what the model is required to cite, never a number it asserts on its own. The model's only real job is judgment, reported back through a structured `submit_verdict` call rather than free-text prose, the same discipline `appq:autotest-validator` already uses for its own verdicts.\n\n## Quick start\n\n```bash\nnpm install -g @appliqation/visual-regression\nnpx playwright install chromium\n```\n\nCreate a `.env` file (in whatever directory you'll run it from) with:\n\n```\nAPPQ_API_KEY=your-appliqation-api-key   # read-only is enough\nANTHROPIC_API_KEY=your-anthropic-key    # or OPENAI_API_KEY (pick one)\n```\n\n```bash\nappliqation-visual-regression check \\\n  --test-case-uuid 1350-2732cd99-81d6-44ce-a053-1aa2e2efc42c \\\n  --route /subscribe \\\n  --baseline-environment Prod \\\n  --target-environment Stage \\\n  --mask \".reader-count\" \\\n  --mask \"[data-testid=timestamp]\"\n```\n\nAdd `--json`/`--ci` for a structured summary. The exit code is 0 for `expected-divergence`/`not-applicable`, 1 for `regression`/`inconclusive` (fail-closed on ambiguity). The JSON summary's `verdict` field is what actually distinguishes the outcomes, not the exit code alone.\n\n## CLI reference\n\n`appliqation-visual-regression check [options]`\n\n**Required:**\n\n| Option | Description |\n|---|---|\n| `--test-case-uuid <uuid>` | Test case this route belongs to; derives `project_id`, supplies `expected_result` context. |\n| `--route </path>` | The route to check, e.g. `/subscribe`; the same route is checked on both environments. |\n| `--baseline-environment <name>` | Environment name treated as the source of truth (commonly, but not necessarily, \"Prod\"). |\n| `--target-environment <name>` | Environment name being checked against the baseline. |\n\n**Optional:**\n\n| Option | Description |\n|---|---|\n| `--mask <selector>` | CSS selector to mask before capturing (repeatable); reduces noise on known dynamic regions. |\n| `--storage-state <path>` | Playwright storageState file, for auth-gated routes. |\n| `--max-turns <n>` | Override `BUDGET_MAX_TURNS` for this run. |\n| `--json` | Print a single structured JSON summary on stdout instead of a human-readable report. |\n| `--ci` | Shorthand for `--json`; exit code already reflects the real verdict either way. |\n\n## What this agent does not do (on purpose)\n\n- **No route enumeration or inference.** `--route` is always explicit; there's no structured route data on a scenario/test case to derive it from (confirmed: routes only ever exist inside free-text step descriptions). A real caller with a just-completed run derives it from real observed navigation data (`get_execution_evidence`), never by guessing at step text.\n- **No auto-detection of dynamic regions.** `--mask` is caller-supplied CSS selectors only. The model already has to reason about \"is this difference data-driven or a real break\" regardless, so masking is an optimization, not a prerequisite.\n- **No write capability.** This agent never calls an Appliqation write tool and never files a defect; it reports a verdict, nothing else. What happens to a confirmed regression (or a secondary observation) is entirely the caller's decision.\n- **No ID/slug-based dynamic-content routes.** `/blog/123` on staging has no reliable way to be matched to its \"equivalent\" content on production (`/blog/345`) without this agent guessing at content equivalence: a single `--route` assumes path identity means content identity. Static, stable routes only.\n- **No multi-step workflow replay.** This agent navigates directly to a URL; it doesn't replay a login flow or rebuild cart state. Auth-gated pages are covered via `--storage-state`; deeper application state built up through a workflow is not.\n\n## Primary finding vs. secondary observations\n\nA full-page diff can surface something real that's unrelated to what the check was actually for. The verdict carries one **primary finding** (what drove the classification) and a separate list of **secondary observations**: other real differences noticed elsewhere on the page. Secondary observations are always reported, never silently dropped, and never affect the verdict or exit code.\n\n## Configuration\n\nCopy `.env.example` to `.env`. Requires `APPQ_API_KEY` (read-only access is sufficient; this agent never calls an appq write tool) and one of `ANTHROPIC_API_KEY`/`OPENAI_API_KEY`.\n\n## Running this safely\n\nThis agent has a real browser and navigates to whatever URLs `--baseline-environment`/`--target-environment` resolve to. It has no filesystem write access and no shell surface at all (unlike `heal-selector`/`scriptgen`, it never patches anything).\n\n**Run this inside a container with an egress allowlist**, same as every agent in this family. This process only ever legitimately needs to reach:\n\n- your LLM provider (`api.anthropic.com` or `api.openai.com`)\n- your configured `APPQ_ORIGIN` (`appq.appliqation.io` by default)\n- the two sites under test (whatever `--baseline-environment`/`--target-environment` resolve to)\n\nAnything else this process tries to reach is unexpected and worth investigating.\n\n## Development\n\n```bash\ngit clone https://github.com/appliqation/visual-regression.git\ncd visual-regression\nnpm install\ncp .env.example .env   # fill in APPQ_API_KEY (read-only) and an LLM key\nnpm run dev -- check --test-case-uuid <uuid> --route </path> --baseline-environment <name> --target-environment <name>\nnpm run typecheck\nnpm test\n```\n\nSee `CLAUDE.md` for a map of this repo if you're working in it with an AI coding assistant.\n\n## License\n\nMIT. See [LICENSE](./LICENSE).\n","readmeFilename":"README.md"}