@decocms/parity 0.11.17 → 0.13.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/AGENTS.md +7 -2
  2. package/CHANGELOG.md +47 -0
  3. package/dist/cli.js +45435 -41764
  4. package/package.json +2 -2
package/AGENTS.md CHANGED
@@ -38,7 +38,9 @@ Do **not** run parity for:
38
38
  - Have ONE URL and want to validate it works end-to-end? → `parity e2e` (functional validation)
39
39
  - Have ONE URL and only need absolute checks (vitals/console/SEO)? → `parity audit` (lighter, no flows)
40
40
 
41
- `parity e2e` reuses the same flows + checks as `parity run`, just in single-site mode (checks adapt with absolute criteria when one side is empty).
41
+ `parity e2e` reuses the same flows + checks as `parity run`, just in single-site mode (checks adapt with absolute criteria when one side is empty). It also does the same **selector automation** as `run` — platform detection, grounded LLM discovery + live-validation, and learning from each run — so you rarely need to hand-write `.parityrc.json` selectors (`--no-auto-selectors`/`--refresh-selectors`/`--no-learn` mirror `run`).
42
+
43
+ Do **not** fake single-site with `parity run --prod X --cand X` — it runs everything twice and reports a degenerate self-diff. `run` now rejects a missing `--prod` and points you at `parity e2e` (issue #141).
42
44
 
43
45
  ## Reading the JSON output
44
46
 
@@ -46,7 +48,10 @@ Do **not** run parity for:
46
48
 
47
49
  ```ts
48
50
  {
49
- verdict: { status: "pass"|"warn"|"fail", score: 0..100, critical, high, medium, low },
51
+ verdict: { status: "pass"|"warn"|"fail", score: 0..100, scoreVersion: 2, pagesAnalyzed, critical, high, medium, low },
52
+ // score v2 = 100·e^(-penaltyDensity/35), penaltyDensity = Σ severity weights ÷ pagesAnalyzed.
53
+ // Any FAIL verdict (critical issue or failed check) caps it at 79. It's a progress meter: it RISES as issues get fixed.
54
+ previousRun?: { id, timestamp, score, scoreDelta }, // trend vs last comparable run (same hosts + scoreVersion)
50
55
  topIssues: Issue[], // LLM-ranked, deduplicated; usually 5-10 items
51
56
  issues: Issue[], // all raw issues from every check
52
57
  checks: CheckResult[], // one per check; .data has structured details
package/CHANGELOG.md CHANGED
@@ -5,6 +5,53 @@ 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
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ * **`parity e2e` now automates selectors like `parity run` (issue #141).** Single-site runs previously saw only `DEFAULT_SELECTORS` + hand-written `.parityrc.json` — `e2e` never detected the platform, never ran LLM selector discovery, and never learned from its flow runs (so `learned-selectors.json`, keyed by platform, never applied). It now detects the platform, runs the same grounded LLM discovery + live-validation pass, threads the platform into every flow, and promotes selectors learned from real successful interactions. New flags mirror `run`: `--no-auto-selectors`, `--refresh-selectors`, `--no-learn`. The discovery pass is now shared code (`src/engine/selector-discovery-pass.ts`) used by both commands.
13
+ * **Discovery covers the journey variant/quantity keys.** LLM selector discovery now infers `variantRow`, `quantityIncrement`, `quantityInput`, `sizeSwatch`, and `colorSwatch` (grounded on the real PDP and live-validated) — exactly the keys single-site users kept hand-writing in `.parityrc.json`.
14
+
15
+ ### Fixed
16
+
17
+ * **`purchase-journey-flow` now works in single-site mode.** The check was comparison-only: with no prod baseline it emitted a spurious "prod não produziu captura" issue per viewport instead of evaluating the journey. It now has a single-site branch (prod slot empty) that fails on a failed step or a skipped *critical* step, evaluating the checkout journey on its own terms — while still keeping the "cand crashed" critical signal for real prod↔cand comparisons.
18
+
19
+ ### Changed
20
+
21
+ * **`parity run` without `--prod` now points you at `parity e2e`.** `--prod` is no longer a hard `requiredOption`; omitting it exits with code 2 and a hint to use `parity e2e --url <cand>` for single-site validation, instead of forcing a wasteful `--prod X --cand X` self-comparison (issue #141).
22
+
23
+ ## [0.12.0](https://github.com/decocms/parity/compare/v0.11.17...v0.12.0) (2026-07-27)
24
+
25
+ ### Known issues
26
+
27
+ * **A full `parity run` (multiple viewports/sides concurrently) has been observed to hang indefinitely in at least one resource-constrained sandboxed environment**, after selector discovery's own throwaway browser launch+close already succeeded. Isolated components (`launchBrowser`, `capturePage`, `parity journey`, sequential/concurrent browser launches) all completed correctly in the same environment, so this reads as environment resource contention rather than a confirmed code defect — but it was not fully root-caused. If a run seems stuck at "Launching browser…", try `--max-viewport-concurrency 1` or a narrower `--only`/`--viewports` scope, and please report reproduction steps.
28
+
29
+ ### Fixed
30
+
31
+ * **The health score was stuck at 0 on every real run — now it actually rises as you fix issues.** The old formula (`100 - crit·20 - high·8 - med·3 - low·1`) had no dynamic range for real workloads: 13 high issues alone zeroed it, and checks emit one issue per occurrence (per page × viewport, per robots.txt user-agent, per broken link), so mid-migration runs carry 40–120 issues. Empirical evidence: across 15 real runs of the granadobr migration, issues fell 122 → 39 (criticals 18 → 0) and the score sat at **0 the entire time**. The new formula (score v2) normalizes the severity-weighted penalty by the number of analyzed page-pairs and applies exponential decay — `round(100·e^(-density/35))` — so the same 15 runs now read **20 → 7 (regression caught) → 35**, moving with every fix. Any FAIL verdict (critical issue or failed check) caps the score at 79 so "FAIL · score 91" can't happen. Status logic (pass/warn/fail), `--fail-on`, and exit codes are unchanged. Verdicts now carry `scoreVersion: 2` and `pagesAnalyzed`.
32
+
33
+ ### Added
34
+
35
+ * **Score trend vs previous run.** `parity run` now records `previousRun: { id, timestamp, score, scoreDelta }` in `report.json` (most recent non-partial run against the same prod/cand host pair and same scoreVersion) and surfaces the delta in the CLI summary (`score 64/100 (+23 vs run anterior)`), the HTML dashboard (chip under the health ring), and the `parity pr` Markdown comment (header + score-trend line).
36
+ * **Root-cause grouping in issue displays.** New display-only grouper (`src/report/group-issues.ts`) collapses issues that share check + severity + normalized summary (paths/URLs/viewports/digits stripped), so "description ausente" on 10 pages reads as one row with an affected-pages note instead of 10 near-identical rows. Applied to the HTML Top issues card, the CLI Top issues list, and the PR comment. Issue IDs and baselines are untouched.
37
+ * **Module selection: `--only`/`--skip`/`--why`.** `parity run` now groups its ~30 checks into 8 named modules (`e2e`, `seo`, `visual`, `vitals`, `cache`, `console`, `html`, `network`). Scope a run with `--only e2e,seo` (or single-check granularity via `check:<name>`), subtract with `--skip`; unselected flows/sitemap-crawl/visual-diff passes are skipped entirely rather than run-and-discarded, making scoped runs genuinely lighter and faster. `--why <text>` records the scoping rationale in `report.json`. No selection at all = full back-compat (every check runs, exactly like before). `parity list modules [--json]` discovers the taxonomy programmatically. A TTY with no explicit selection shows an interactive prompt; non-TTY just gets a one-line heads-up and proceeds with everything.
38
+ * **Adaptive, per-module scoring.** The verdict score now reflects only the modules that ran: `--only e2e` scores purely on e2e; `--only e2e,seo` blends both, weighted by pages actually analyzed per module. `report.json` carries the full breakdown (`moduleVerdicts`), `verdict.modulesRun` lists contributing modules, and score-trend comparisons only match runs that scored the *same* module set.
39
+ * **Cart interactions overhauled.** Multi-item add + validation (`add-second-item`/`validate-multi-item`), cart persistence across reload (`verify-cart-persistence`), direct quantity input (`set-qty-input`), configurable coupon codes (`rc.coupon`) with an opt-in valid-coupon assertion (`apply-valid-coupon`), and a VTEX-only informational probe (`seller-code-null`, issue: typing the literal string `"null"` into a seller-code field is accepted by VTEX and resolves the seller itself) — always `ok`/`skipped`, never fails the run.
40
+ * **Interactive PLP pagination.** The `plp` flow now drives pagination like a user would — clicking a next-page link, clicking "load more", or scrolling — instead of only fetch-probing `?page=N`. Catches load-more/infinite-scroll sites the old fetch-only check couldn't, while keeping the fetch probe as a fallback for classic paginated PLPs.
41
+ * **New checks:** `pdp-breadcrumbs` (breadcrumb trail or JSON-LD `BreadcrumbList` still renders), `plp-sorting` (a sort query param actually reorders products), `spa-navigation-flow` (F5 vs client-side `<Link>` navigation — catches CMS sections/site-globals silently dropping on SPA nav, a real bug class from a production Fresh→TanStack migration post-mortem), `serverfn-hover-flood` (hovering product cards shouldn't flood the worker with more than a configurable budget of server-fn/preload requests).
42
+ * **Selector discovery v2.** Discovery now sees up to 3 labeled HTML sources (home + PLP + PDP) instead of home alone, so PDP-only and PLP-only selector keys are grounded in the page they actually live on. The model also flags low-confidence guesses (`low_confidence_keys`). A live-validation pass (`page.locator(sel).count() > 0`) runs before a selector is trusted or promoted to the learned-selectors library — a selector that validates AND wasn't flagged low-confidence is promoted directly as `origin: "verified"`; one that fails validation is dropped from the run entirely rather than silently misfiring later. `parity learned validate --url <url>` exposes this as a standalone diagnostic. Selector cache gained TTL + structural-fingerprint invalidation (previously cached forever until manually refreshed).
43
+ * **`parity extract`** — a new single-site command (no prod×cand comparison) that captures AI-ready structured data about a site's UI components (header, footer, nav, shelves, hero, minicart, …) for migrations where there's no source code to read: HTML, computed styles, cropped screenshots, asset/link inventories. Heuristic component auto-detection (semantic markup + Deco `data-section` convention + geometry, with an optional LLM relabeling pass) plus pluggable exporters (Markdown for pasting into an agent's context, JSON manifest).
44
+
45
+ ### Changed
46
+
47
+ * **`computeVerdict` is now a single shared module** (`src/engine/verdict.ts`) — `run.ts`, `vitals.ts`, and `cache.ts` previously carried three drifting copies.
48
+ * **`src/engine/flows.ts` (3.9k lines) split into `src/engine/flows/`** (one file per flow + shared helpers) — no behavior change, just a maintainability split ahead of the M2 feature work above.
49
+ * Learned-selectors gained a lifecycle: entries now carry `origin: "verified" | "llm-guess"`, staleness decay based on `lastValidated` (previously stored but never read), and verified-first ranking.
50
+
51
+ ### Fixed
52
+
53
+ * **`lazy-section-presence` false positive for Fresh→TanStack/Vite chunk naming** (issue #118) — Fresh names a lazy-loaded section chunk `render`, Vite names the same chunk `render.ts`; the check now strips bundler extensions before comparing, so it stops reporting a false "missing section" on every page with lazy sections.
54
+
8
55
  ## [0.11.16](https://github.com/decocms/parity/compare/v0.11.15...v0.11.16) (2026-06-17)
9
56
 
10
57
  ### Changed