@decocms/parity 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +77 -178
  3. package/dist/cli.js +15474 -13525
  4. package/package.json +81 -88
package/CHANGELOG.md CHANGED
@@ -5,6 +5,56 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
 
8
+ ## [0.11.0](https://github.com/decocms/parity/compare/v0.10.1...v0.11.0) (2026-06-17)
9
+
10
+ ### Added
11
+
12
+ * **Claude Agent SDK as a third LLM provider (#66).** Reuses the local `claude` CLI auth via [`@anthropic-ai/claude-agent-sdk`](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk). Auto-detected when no env key is set — devs with `claude` already logged in don't need to configure anything. Goes through the user's Claude plan instead of API billing.
13
+ * **Per-feature model routing.** Selector discovery / step recovery / classification → Haiku 4.5 (cheap), visual diff / aggregation → Sonnet 4.6, explain → Opus 4.7. Overridable via `--llm-model <feat>=<model>,...`, `--llm-tier-default <tier>`, or `--llm-model-default <model>`. Cuts ~70% of the LLM cost on a `--preset full` run.
14
+ * **`parity pr` CI/CD command (#79).** Compares a PR preview URL against prod and emits a Markdown comment ready to paste into a GitHub PR. With `--github`, writes to `$GITHUB_STEP_SUMMARY`. Thin wrapper around `parity run` with CI-tuned defaults (preset=ci, mobile-only, purchase-journey).
15
+ * **`parity report --section <name>` (#74).** Extracts one tab from a saved run as HTML or, with `--json`, as a tailored JSON projection (verdict, top-issues, checks, network, etc.). Lets agents pull the SEO/Network/Vitals slice without parsing the whole report or loading the full Run.
16
+ * **Per-page Network waterfall (#78).** SVG bar chart on the Network tab, positioned by `requestStart`, color-coded by resource type, faded for cached. `NetworkEntry` schema gets optional `startMs`/`endMs` (back-compat).
17
+ * **Clickable dashboard tiles → per-check detail panels (#76).** Tiles route to `#detail/<checkName>` showing status, duration, summary, issues, raw `data` payload, and a copy-pasteable reproduction command.
18
+ * **Side-by-side Home/PLP/PDP/Cart/Checkout buttons (#77).** SBS panel classifies captured paths by role and emits one button per role. URLs captured on one side only get a dashed border + warning chip.
19
+ * **`--pt` flag for LLM output language (#67).** Available on `parity run`, `audit`, `e2e`, `journey`, `fix`, `explain`. Affects only LLM-generated content — static report stays in English.
20
+ * **Tab descriptions / inline help (#73).** Every tab opens with a one-line description so new readers (and agents) immediately know what the tab covers.
21
+ * **Interactive selector prompt foundation (#72).** When parity hits a missing selector AND no LLM provider is available AND running in a TTY, the new prompt module guides the dev through writing a `.parityrc.json` override. Wiring into the runner is a follow-up.
22
+
23
+ ### Changed
24
+
25
+ * **Report HTML now in English by default (#67).** Every user-facing PT-BR string in the report, audit HTML, and visual-diff prompt is translated. New regression test scans the output for PT-BR diacritics and a deny-list of common tokens.
26
+ * **`#diff` tab hidden when no baseline (#68).** The empty-state "Run executed without baseline" message that looked like a bug on every normal run is gone — the tab simply doesn't render unless `--baseline <name>` is loaded.
27
+ * **LLM-only tabs hidden when no LLM ran (#75).** Visual Diff and LLM Prompt tabs are omitted entirely from the nav + DOM when no LLM output exists. Single header banner explains why.
28
+ * **Side-by-side iframe forces mobile viewport via proxy (#70).** When `parity serve` is active, the proxy injects `<meta name="viewport" content="width=375">`, sets a mobile UA, and adds `Sec-CH-UA-Mobile: ?1` so cand renders in real mobile.
29
+ * **Smart `--visual-pages` default (#71).** Auto-zeroes when no LLM provider is available — the capture without analysis was just wasted seconds. Opt in with `--visual-pages N` if you want the raw screenshots anyway.
30
+ * **README rewrites around the agents-in-loop thesis (#80).** Three use cases (assisted migration, CI/CD PR review, continuous smoke) up front. New `docs/cli.md`, `docs/checks.md`, `docs/config.md`.
31
+ * **Report mobile-friendly + a11y focus rings + tabular numerics (#81).** Below 880px the sidebar becomes a horizontal chip strip; numeric values in tiles stay aligned across columns.
32
+
33
+ ### Fixed
34
+
35
+ * **SDK provider image handling.** First implementation embedded base64 data URLs as text in the prompt — vision features (visual-diff, section-understanding) silently produced garbage. Now switches to the async-iterable `SDKUserMessage` form with proper `image` content blocks when `userImages` is set.
36
+ * **Timer leak in SDK provider abort handle.** `setTimeout` was created but never cleared. New `makeAbortHandle` returns a `clear()` callback that callers invoke in `finally`.
37
+ * **JSON repair reuse in SDK provider.** Bare `JSON.parse` was dropping fenced/wrapped output the OpenRouter provider would have salvaged. Now reuses the exported `tryRepairJson`.
38
+ * **`setForcedProvider` validates credentials before activating.** Returns a user-facing error string instead of failing with a 401 mid-run.
39
+ * **`disallowedTools: ["*"]` removed.** Was treated as a literal tool name, not a glob — misleading dead code.
40
+ * **Repo-wide lint sweep.** 9 biome errors carried over from in-flight PRs (template-literal-as-string, optional-chain, assign-in-expression) now fixed. `bun run lint` is clean.
41
+
42
+ ## [0.10.1](https://github.com/decocms/parity/compare/v0.10.0...v0.10.1) (2026-05-30)
43
+
44
+ ### Fixed
45
+
46
+ * **Adaptive `scrollFullPage` — actually reaches the bottom on long pages.** Previous fixed-step loop with a 10s outer race only covered ~15000px before bailing, so 25000-40000px e-commerce homepages were captured with half the content still as skeletons. New loop re-measures `scrollHeight` every tick, waits inline for in-view skeleton placeholders to clear (up to 1.5s per step), and exits once page height has been stable for 3 consecutive checks. On miess home: 15 steps, 8862px reached, **0 skeletons at screenshot time** (was 7+ before). Race timeout bumped 10s → 45s, `capturePage` visual-diff `timeoutMs` 45s → 90s to fit the new scroll budget.
47
+
48
+ * **Silent `ReferenceError: __name is not defined` inside `page.evaluate`.** Took two debug rounds to isolate — `tsx`/esbuild injects a `__name` helper to preserve `.name` on arrow-function declarations (`const foo = () => ...`), but that helper doesn't exist in the page's browser context. The function threw immediately and `.catch(() => undefined)` swallowed it, making it look like a legitimate timeout. Fix: inlined the helper Promises inside `scrollFullPage`'s `page.evaluate`, and replaced silent `.catch` with one that logs the actual error message.
49
+
50
+ * **`SKELETON_DOWNGRADE_PCT_DIFF_CEILING = 0.25`.** The skeleton-vs-loaded downgrade was masking structural failures: any diff where the LLM mentioned "skeleton"/"placeholder" was forced to `low`, even when prod had a half-empty page (34%+ pctDiff). Now the downgrade only fires when pctDiff is under 25% — above that, the imbalance is treated as a real regression, not timing noise.
51
+
52
+ ### Changed
53
+
54
+ * `waitForSkeletonsToResolve` budget reduced 10s → 5s. The new adaptive scroll does inter-step skeleton waits, so the global safety net is a last-resort for off-screen skeletons rather than the primary defense.
55
+
56
+ * New `pre-screenshot skeletons=N` diagnostic log (via `DEBUG_PARITY=1`) so anyone investigating "is the page actually ready when we capture it?" can answer in one run.
57
+
8
58
  ## [0.10.0](https://github.com/decocms/parity/compare/v0.9.0...v0.10.0) (2026-05-29)
9
59
 
10
60
  ### Added
package/README.md CHANGED
@@ -1,39 +1,27 @@
1
1
  # @decocms/parity
2
2
 
3
- E2E parity validator for site migrations. CLI that runs comparative tests between two URLs — `prod` (source of truth) and `cand` (migrated version) — and produces a single HTML report flagging UI, functional, SEO, and Web Vitals regressions.
3
+ > **Infrastructure for agents in loop to close migrations, PRs, and incidents without a dev on the critical path.**
4
4
 
5
- Built originally for Fresh TanStack Start migrations of Deco storefronts, but the checks are generic enough for any side-by-side migration.
5
+ `parity` is a CLI that runs deep comparative tests between two URLs — `prod` (source of truth) and `cand` (migrated version, PR preview, or staging) and produces:
6
+
7
+ - A standalone **HTML report** for humans to scan in 30 seconds
8
+ - A normalized **JSON projection** (`parity report --section <name> --json`) that agents can consume without parsing HTML
9
+ - A **JSONL stream** (`--json`) that streams each check result as it completes
10
+ - A **PR comment** (`parity pr --prod ... --preview ...`) ready to drop into a CI/CD pipeline
11
+
12
+ It checks UI, functional, SEO, performance, console, network, and cache regressions. Built originally for Fresh → TanStack Start migrations of Deco storefronts, but the checks are generic enough for any side-by-side migration.
6
13
 
7
14
  > **Status:** alpha. APIs and report layout may still change.
8
15
 
9
- ## What it checks
10
-
11
- | Check | What it catches |
12
- | ----------------------------- | ---------------------------------------------------------------------- |
13
- | HTTP status parity | Routes that 404 / 500 in cand but worked in prod |
14
- | Console errors | New hydration mismatches, failed fetches, JS exceptions |
15
- | HTML structural diff | Section / element counts drifting beyond tolerance |
16
- | Meta / SEO parity | `<title>`, `<meta description>`, canonical, og:\*, twitter:\*, JSON-LD |
17
- | **Visual diff (LLM Vision)** | Sections missing, wrong hero, broken shelf, layout shifts |
18
- | Purchase journey | Home → PLP → PDP → CEP → cart → checkout completes in both |
19
- | Network summary | Request count / bytes / cache hit rate |
20
- | Web Vitals | LCP, FCP, TTFB, INP, CLS — mobile |
21
- | Image loading health | Missing alt text, no srcset, broken `<img>` |
22
- | Lazy section presence | Deco `/deco/render` and `/_loader/*` routes responding |
23
- | SEO deep audit | robots.txt, sitemap, noindex regressions |
24
- | Cache coverage | Cache hit rate, opportunities to cache |
25
- | **Search presence** | Search input reachable from home in both |
26
- | **Search autocomplete** | Typing reveals suggestions; cand keeps parity with prod |
27
- | **Search results** | Same keyword returns comparable product counts |
28
- | **Search no-results** | Unicode garbage term shows empty state, doesn't match products |
29
- | **Cart interactions** | Increment / decrement / coupon / remove all behave in cand |
30
- | **404 parity** | Invalid URL returns 404 (no catch-all 200 in cand) |
31
- | **Cookie/CEP modal CLS** | Modals don't introduce layout shifts >0.1 in cand |
32
- | **PDP gallery + related** | Image gallery + "Related products" shelf still render |
33
- | **Footer links health** | Institutional links (privacy, contact, etc.) aren't broken in cand |
34
- | **Login flow** _(opt-in)_ | Valid credentials log in; invalid ones show a clear error |
35
-
36
- All results are aggregated (optionally via Claude) and ranked by severity. Each issue includes screenshots, reproduction, and a suggested fix.
16
+ ## Why parity exists
17
+
18
+ Migrations, PR reviews, and incident triage all share the same workflow: take two versions of a site, find what's different, fix it. Doing this by hand is slow and error-prone; spinning up an LLM agent to do it requires a tool the agent can drive. `parity` is that tool.
19
+
20
+ Three use cases drive the design:
21
+
22
+ 1. **Assisted migration** (Fresh → TanStack, Shopify → Hydrogen, etc.) — an agent runs `parity run` on the migrated branch every commit, picks the top issue, fixes it, runs again. The HTML report + visual-diff prompt are both designed to be paste-ready into Claude / ChatGPT.
23
+ 2. **CI/CD PR review** — `parity pr --prod ... --preview ...` outputs a Markdown comment with verdict, top issues, and a link back to the full report. Drop it into a workflow with `gh pr comment -F` or `actions/github-script`.
24
+ 3. **Continuous smoke** `parity run --preset smoke` finishes in ~30s and runs no LLM. Cheap enough to ping after every deploy.
37
25
 
38
26
  ## Quickstart
39
27
 
@@ -44,125 +32,98 @@ npm install -g @decocms/parity
44
32
  npx @decocms/parity run --prod ... --cand ...
45
33
 
46
34
  # First-time smoke run (~30s, no LLM needed)
47
- parity run \
48
- --prod https://oldsite.com \
49
- --cand https://newsite.example.dev \
50
- --preset smoke --open
35
+ parity run --prod https://oldsite.com --cand https://newsite.example.dev --preset smoke --open
51
36
 
52
- # Full audit with visual diff (set ANTHROPIC_API_KEY for the LLM bits)
37
+ # Full audit with visual diff
53
38
  ANTHROPIC_API_KEY=sk-... parity run \
54
39
  --prod https://oldsite.com \
55
40
  --cand https://newsite.example.dev \
56
41
  --preset full --open
42
+
43
+ # CI/CD PR comment
44
+ parity pr --prod https://oldsite.com --preview https://pr-123-preview.example.dev --github
57
45
  ```
58
46
 
59
- ## Presets
47
+ ## Agent contract
48
+
49
+ For agents driving `parity` in a loop, the stable surface is:
60
50
 
61
- `--preset smoke` homepage only, mobile only, no LLM, no extra crawl. Use to validate the pipeline runs at all (~30s).
51
+ | Need | Command | Output |
52
+ | --- | --- | --- |
53
+ | Run a full comparison | `parity run --prod X --cand Y --json runs.jsonl` | JSON-Lines, one line per check |
54
+ | Extract one tab from a saved run | `parity report <runId> --section <name>` | HTML slice |
55
+ | Extract one tab as structured JSON | `parity report <runId> --section <name> --json` | JSON projection |
56
+ | Drive a CI/CD pipeline | `parity pr --prod X --preview Y --github` | Markdown comment + `$GITHUB_STEP_SUMMARY` |
57
+ | Drill into one issue | `parity explain <runId> <issueId>` | LLM deep-dive (needs key) |
58
+ | Build a paste-ready prompt | `parity prompt <runId>` | Markdown ready for Claude/ChatGPT |
59
+ | Generate visual-fix bundle | `parity fix --prod X --cand Y --selector S` | Markdown + screenshots + computed-styles diff |
62
60
 
63
- `--preset full` purchase journey, mobile + desktop, 5 visual diff pages, 10 vitals pages, LLM enabled if API key is set. Use for releases.
61
+ See [`docs/cli.md`](./docs/cli.md) for every command, [`docs/checks.md`](./docs/checks.md) for every check.
64
62
 
65
- `--preset ci` — purchase journey on mobile, smaller crawls (3 visual + 5 vitals). Tuned for CI runtime.
63
+ ## LLM providers
66
64
 
67
- Individual flags always override the preset.
65
+ Three providers, auto-detected in this order — **none required** if you have the `claude` CLI logged in locally:
68
66
 
69
- ## Commands
67
+ 1. `ANTHROPIC_API_KEY` — direct Anthropic API (fastest, billed to your API account)
68
+ 2. `OPENROUTER_API_KEY` — OpenRouter
69
+ 3. **Local `claude` CLI** — uses [`@anthropic-ai/claude-agent-sdk`](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk); goes through your existing Claude plan. No env vars needed
70
70
 
71
- | Command | What it does |
72
- | ------------------ | ----------------------------------------------------------------------------- |
73
- | `parity run` | Full comparison run between two URLs |
74
- | `parity audit` | **Single-site** absolute audit (no prod×cand). Console + Vitals + SEO + Imgs |
75
- | `parity e2e` | **Single-site** functional end-to-end: all flows + all checks. ONE URL. |
76
- | `parity journey` | CI-friendly: only the purchase journey, with JUnit / GitHub annotations |
77
- | `parity vitals` | Crawl N pages, compare Web Vitals prod vs cand |
78
- | `parity cache` | CDN cache analysis, opportunities, request categorization |
79
- | `parity serve` | Local HTTP server with iframe proxy so side-by-side tab works for any site |
80
- | `parity report` | Reopen an existing run's HTML report |
81
- | `parity compare` | Compare a run against a baseline |
82
- | `parity baseline` | Manage baselines (`set`, `list`, `unset`) |
83
- | `parity list` | List saved runs |
84
- | `parity check` | Run a single check (`<name>`) — skips sitemap + LLM aggregation; sub-10s loop |
85
- | `parity console` | Sub-10s capture of console errors/warnings + network failures for one URL |
86
- | `parity html` | Dump page/selector HTML or unified diff prod×cand (prettier + jsdiff) |
87
- | `parity section` | Focused prod×cand diff of a section: HTML + screenshot + computed styles |
88
- | `parity fix` | Pixel-perfect bundle: heatmap + CSS source + LLM-ready Markdown prompt |
89
- | `parity prompt` | Export issues as a Markdown prompt for any LLM |
90
- | `parity explain` | LLM deep-dive on a specific issue (needs `ANTHROPIC_API_KEY`) |
91
- | `parity learned` | Inspect the learned-selectors library |
71
+ Force with `--llm <anthropic|openrouter|claude-code|none|auto>`. Override per-feature with `--llm-model selector-discovery=claude-haiku-4-5,visual-diff=claude-opus-4-7`. Default tiers: Haiku for short tasks (selector discovery, classification), Sonnet for vision/aggregation, Opus for `explain`.
92
72
 
93
- Run any command with `--help` for the full flag list.
73
+ Without any provider, the CLI still runs and outputs raw check results — only the LLM-tagged tabs (Visual Diff, LLM Prompt) hide themselves and a banner explains why.
94
74
 
95
75
  ## Output
96
76
 
97
77
  ```
98
78
  ./parity-output/runs/<runId>/
99
79
  ├── report.html # standalone, open in any browser
100
- ├── report.json # structured output for CI / tooling
80
+ ├── report.json # structured output for agents / CI / tooling
101
81
  ├── screenshots/ # per-page, per-viewport, per-side; includes pixelmatch heatmaps
102
82
  ├── har/ # Playwright HARs (one per viewport/side)
103
83
  ├── traces/ # Playwright traces — drag into trace.playwright.dev
104
84
  └── console/ # console messages captured per page
105
85
  ```
106
86
 
107
- Plus `./parity-baselines/<name>.json` for git-trackable baseline manifests.
108
-
109
- ## Visual Diff tab
110
-
111
- When `--visual-pages > 0` and an LLM key is set, the report's **Visual Diff** tab shows, per page:
112
-
113
- - prod screenshot · cand screenshot · pixelmatch heatmap, side-by-side
114
- - list of Deco sections present in prod but missing in cand (auto-detected from `data-section`)
115
- - semantic differences identified by Claude Vision (region, type, severity, description)
116
- - one-click "Export visual prompt" — Markdown ready to paste into Claude / ChatGPT to generate the fix
87
+ ## Presets
117
88
 
118
- The visual prompt focuses *only* on visual diffs, references the screenshot paths, and includes migration-specific guidance (register section in `setup.ts`, loader shape drift, useDevice hydration, etc).
89
+ - `--preset smoke` homepage only, mobile only, no LLM, no extra crawl. ~30s. Use for "did the pipeline even run?".
90
+ - `--preset full` — purchase journey, mobile + desktop, 5 visual diff pages, 10 vitals pages. Use for releases.
91
+ - `--preset ci` — purchase journey on mobile, smaller crawls (3 visual + 5 vitals). Tuned for CI runtime.
119
92
 
120
- ## Pixel-perfect fix loop
93
+ Individual flags always override the preset. See `parity run --help` for the full default behavior breakdown.
121
94
 
122
- When `parity run` flags a section but you want the LLM to actually patch it, `parity fix` bundles every signal into one Markdown prompt:
95
+ ## CI usage (GitHub Actions)
123
96
 
124
- ```bash
125
- parity fix \
126
- --prod https://www.example.com \
127
- --cand https://example.deco-cx.workers.dev \
128
- --selector 'header'
97
+ ```yaml
98
+ - name: Parity check
99
+ env:
100
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
101
+ run: |
102
+ npx @decocms/parity pr \
103
+ --prod ${{ vars.PROD_URL }} \
104
+ --preview ${{ env.PR_PREVIEW_URL }} \
105
+ --github
129
106
  ```
130
107
 
131
- Writes (under `./parity-output/sections/`):
132
-
133
- - `section-<hash>-{prod,cand}.png` — locator screenshots, carousels stabilized
134
- - `section-<hash>-heatmap.png` — pixelmatch with bounding-box analysis
135
- - `section-<hash>-bundle.json` — machine-readable bundle (deltas + sources + bboxes)
136
- - `section-<hash>-prompt.md` — **paste-ready** Markdown with embedded images, computed-style deltas, CSS source per property, HTML diff, and an opinionated "summarize what you understand first, no code yet" instruction
137
-
138
- If `ANTHROPIC_API_KEY` is set, the LLM is invoked automatically and prints a one-paragraph diagnosis to stdout (uses Claude Vision on the screenshots). Pass `--no-llm` to stay offline.
139
-
140
- The same flags are available individually on `parity section`: `--heatmap`, `--css-source`, `--prompt`, `--llm-summary`. Use those when you only need one signal; `parity fix` is the "do everything" shortcut.
141
-
142
- ## `parity e2e` — single-site functional run
143
-
144
- The `audit` command runs absolute checks (vitals, console, network, images, SEO) — useful but doesn't exercise interactions. `parity e2e` runs **all the functional flows** (homepage, plp, pdp, purchase-journey, search, cart-interactions, optionally login) against a single URL plus all parity checks in single-site mode.
145
-
146
- ```bash
147
- # Quick e2e for a single site (no comparison, ~3-5min)
148
- parity e2e --url https://www.example.com
149
-
150
- # Pick specific flows
151
- parity e2e --url https://www.example.com --flows=search,cart-interactions
108
+ The `--github` flag writes the Markdown to `$GITHUB_STEP_SUMMARY` so it shows up under the workflow summary. To also post as a PR comment:
152
109
 
153
- # Override LLM-discovered search term
154
- parity e2e --url https://www.example.com --search-terms="camisa,promocao"
155
-
156
- # With login (credentials via env or flags)
157
- PARITY_LOGIN_EMAIL=test@example.com PARITY_LOGIN_PASSWORD=*** \
158
- parity e2e --url https://www.example.com --flows=login
110
+ ```yaml
111
+ npx @decocms/parity pr ... --out parity-comment.md
112
+ - uses: actions/github-script@v7
113
+ with:
114
+ script: |
115
+ const fs = require('fs');
116
+ const body = fs.readFileSync('parity-comment.md', 'utf8');
117
+ github.rest.issues.createComment({
118
+ ...context.repo,
119
+ issue_number: context.issue.number,
120
+ body,
121
+ });
159
122
  ```
160
123
 
161
- **Use `parity e2e` when** you want to validate "does this site actually work end-to-end?" — pre-launch, post-deploy, partner sites. **Use `parity run` when** you need to detect *regressions* between two versions (prod vs migration candidate).
162
-
163
124
  ## Configuration (optional)
164
125
 
165
- `.parityrc.json` at the project root — selector overrides and run defaults:
126
+ `.parityrc.json` at the project root — selector overrides and run defaults. See [`docs/config.md`](./docs/config.md) for the full schema.
166
127
 
167
128
  ```json
168
129
  {
@@ -170,77 +131,15 @@ PARITY_LOGIN_EMAIL=test@example.com PARITY_LOGIN_PASSWORD=*** \
170
131
  "selectors": {
171
132
  "categoryLink": "header a[href*='/c/']",
172
133
  "productCard": "[data-product-card] a",
173
- "buyButton": "button:has-text('Comprar')",
174
- "minicartTrigger": "[data-minicart-trigger]",
175
- "cepInputPdp": "input[name='shipping-zipcode']",
176
- "cepInputCart": "input[name='cart-zipcode']",
177
- "checkoutButton": "a:has-text('Finalizar compra')",
178
- "searchInput": "input[type='search']",
179
- "cartCouponInput": "input[name*='coupon']"
180
- },
181
- "search": {
182
- "terms": ["camisa", "promocao"]
134
+ "buyButton": "button:has-text('Comprar')"
183
135
  },
184
- "footer": {
185
- "maxLinks": 20,
186
- "followExternal": false
187
- },
188
- "notFound": {
189
- "testUrl": "/this-page-definitely-does-not-exist"
190
- },
191
- "login": { "enabled": true }
136
+ "search": { "terms": ["camisa", "promocao"] }
192
137
  }
193
138
  ```
194
139
 
195
- > **Credentials are NEVER read from `.parityrc.json`.** Set `PARITY_LOGIN_EMAIL` and `PARITY_LOGIN_PASSWORD` as environment variables (`.parityrc.json` is for non-secret config only).
196
-
197
- `.parityignore` — noise suppression:
198
-
199
- ```json
200
- {
201
- "ignoreSelectorsVisual": [".banner-rotativo", "#trustvox-trustbar"],
202
- "ignoreRequestPatterns": ["*.gif?t=*", "**/pixel*"],
203
- "ignoreConsolePatterns": ["ERR_BLOCKED_BY_CLIENT"]
204
- }
205
- ```
206
-
207
- Both files are gitignored by default — they're per-user, not per-repo.
208
-
209
- ## LLM (optional)
210
-
211
- Set **one** environment variable to unlock LLM-driven features:
212
-
213
- - `ANTHROPIC_API_KEY` — direct Anthropic API (Claude Sonnet 4.6 with prompt caching). Preferred.
214
- - `OPENROUTER_API_KEY` — OpenRouter (default model `anthropic/claude-sonnet-4.5`; override with `PARITY_OPENROUTER_MODEL`).
215
-
216
- What LLM enables:
217
-
218
- - **Issue aggregation** — flat raw issues become ranked, deduplicated top issues
219
- - **Selector discovery** — infers `categoryLink` / `productCard` / `buyButton` etc. from HTML
220
- - **Step recovery** — when a flow step fails, suggest a working selector
221
- - **Visual semantic diff** — Claude Vision interprets pixel diffs as missing sections / wrong layout / etc.
222
- - **PLP picker / PDP matcher** — cross-site disambiguation
223
- - **`parity explain <issue>`** — root-cause analysis on demand
224
-
225
- Without any key, the CLI still runs and outputs raw check results — only the smart bits are skipped. Deterministic fallbacks always apply.
226
-
227
- **Cost** — A `--preset full` run with visual diff uses ~6-12 Claude calls (each with 2 screenshots). Roughly $0.05–$0.20 per run on Sonnet 4.6 with prompt caching.
228
-
229
- ## CI usage
230
-
231
- ```yaml
232
- - name: Parity check
233
- env:
234
- ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
235
- run: |
236
- npx @decocms/parity journey \
237
- --prod ${{ vars.PROD_URL }} \
238
- --cand ${{ env.PR_PREVIEW_URL }} \
239
- --junit parity.junit.xml \
240
- --github
241
- ```
140
+ `.parityignore` noise suppression. See `docs/config.md`.
242
141
 
243
- `parity journey` emits GitHub Actions `::error` and `::warning` annotations for each failed step and writes JUnit XML.
142
+ > **Credentials are NEVER read from `.parityrc.json`.** Set `PARITY_LOGIN_EMAIL` and `PARITY_LOGIN_PASSWORD` as environment variables.
244
143
 
245
144
  ## Development
246
145