@ia-qa/self-healing 1.7.7 → 1.7.10

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.
package/README.md CHANGED
@@ -123,6 +123,7 @@ env/SSM — see **Configuration**) or capture-during-run, where your own suite l
123
123
  | Your question | Verb |
124
124
  |---|---|
125
125
  | my tests broke — fix them | `run` (capture → diff → confirm → fix → re-run to verify) |
126
+ | **here is the failure — is it drift?** | **`explain`** — paste the runner's output, get the verdict for the locator it names |
126
127
  | did anything drift? | `diff` → PASS/FIX/BLOCK, the CI gate |
127
128
  | **my suite already ran with `IAQA_CAPTURE=1`** | **`diff`, on its own** — merges the capture, no browser, no second run |
128
129
  | day one, no baseline — is my suite still valid? | `audit` (advisory; never gate on it) |
@@ -137,6 +138,41 @@ env/SSM — see **Configuration**) or capture-during-run, where your own suite l
137
138
  to capture, once to verify the fix): `run --no-verify` keeps only the first, and
138
139
  `IAQA_CAPTURE=1` on the run you already do in CI plus `ia-qa-heal diff` costs nothing extra.
139
140
 
141
+ ### Start from the failure — `ia-qa-heal explain`
142
+
143
+ Every other verb starts from a contract. You start from a red build.
144
+
145
+ ```bash
146
+ ia-qa-heal explain --junit results.xml # the report your runner already writes
147
+ ia-qa-heal explain --message "Expected to find element: '.btn-primary'"
148
+ npx cypress run 2>&1 | ia-qa-heal explain # or just pipe the log
149
+ ```
150
+
151
+ ```
152
+ 🔧 FIX ia-qa-heal explain — is this failure selector drift?
153
+ 1 failure read · 1 locator identified · 1 page compared
154
+
155
+ 🔧 FIX selector ".btn-primary"
156
+ page: checkout
157
+ used at: tests/checkout.spec.js:1
158
+ proposed: .btn-primary → #pay-now
159
+ The string reaches nothing, but its element survived. `ia-qa-heal fix` can rewrite it.
160
+ ```
161
+
162
+ **`PASS` is the answer worth the most.** It means the locators in that failure still reach
163
+ their elements — the build is red for another reason, so stop reading selectors and go look
164
+ at timing, test data, or the app. It re-runs nothing, so it never claims your test is flaky;
165
+ it only rules drift out.
166
+
167
+ It works the same for every runner in every language because **it does not parse your
168
+ runner's error messages**. It intersects the failure text with the locator literals
169
+ `ingest` read from your own sources — so pytest, Cypress, Playwright, Selenium, WebdriverIO
170
+ and JUnit all work, and the answer comes back with the `file:line` the error never carried.
171
+
172
+ Read-only, offline, opens no browser, applies nothing. Needs a baseline (it is about drift —
173
+ a locator that *worked* and stopped); with no baseline the day-one verb is `audit`. Exits 0
174
+ on PASS, 1 on BLOCK, and on FIX only with `--strict`.
175
+
140
176
  ## The verdict
141
177
 
142
178
  ```
package/TUTORIAL.md CHANGED
@@ -12,7 +12,7 @@
12
12
  3. [Before you start](#3-before-you-start)
13
13
  4. [Path A — I use an AI agent (easiest)](#4-path-a--i-use-an-ai-agent-easiest)
14
14
  5. [Path B — I use a terminal](#5-path-b--i-use-a-terminal)
15
- 6. [Your first real workflow](#6-your-first-real-workflow-the-whole-point) — including [the console, if you don't want a terminal](#step-68--no-terminal-open-the-console)
15
+ 6. [Your first real workflow](#6-your-first-real-workflow-the-whole-point) — including [a test just failed, is it drift?](#step-64b--you-didnt-run-diff-you-got-a-red-build--explain) · [the console, if you don't want a terminal](#step-68--no-terminal-open-the-console)
16
16
  7. [Reading the verdict](#7-reading-the-verdict)
17
17
  8. [Putting it in CI](#8-putting-it-in-ci) — [JUnit trends](#82-trend-charts-for-free--junit) · [the run history](#83-the-trend--ia-qa-heal-history)
18
18
  9. [Optional: AI suggestions (BYOK)](#9-optional-ai-suggestions-for-the-lost-ones-byok)
@@ -422,6 +422,48 @@ Now there are two moments, so there is a verdict. Any page you did **not** re-ma
422
422
  carries the baseline's own timestamp; it is listed and left out of the verdict rather than
423
423
  counted as `ok`, because it was never compared either.
424
424
 
425
+ ### Step 6.4b — You didn't run `diff`. You got a red build. — `explain`
426
+
427
+ Everything above assumes you came here *asking* about drift. Most of the time you don't:
428
+ your CI goes red at 2am and you're staring at an error message. That's what `explain` is for.
429
+
430
+ Agent: **"This test failed — is it selector drift?"**
431
+ Terminal:
432
+ ```bash
433
+ npx ia-qa-heal explain --junit results.xml # the report your runner already writes
434
+ npx ia-qa-heal explain --message "Expected to find element: '.btn-primary'"
435
+ npx cypress run 2>&1 | npx ia-qa-heal explain # or just pipe the log
436
+ ```
437
+
438
+ ```
439
+ 🔧 FIX ia-qa-heal explain — is this failure selector drift?
440
+ 1 failure read · 1 locator identified · 1 page compared
441
+
442
+ 🔧 FIX selector ".btn-primary"
443
+ page: checkout
444
+ used at: tests/checkout.spec.js:1
445
+ proposed: .btn-primary → #pay-now
446
+ The string reaches nothing, but its element survived. `ia-qa-heal fix` can rewrite it.
447
+ ```
448
+
449
+ It finds the locator by **intersecting the failure text with the literals your own tests
450
+ write** (that's what `ingest` collected) — it never learns your runner's error format, so
451
+ pytest, Cypress, Playwright, Selenium and WebdriverIO all work the same. As a bonus you get
452
+ the `file:line` the error message never carried.
453
+
454
+ > ✅ **`PASS` is the answer worth the most.** It means the locators in that failure still
455
+ > reach their elements — so the build is red for another reason. Stop reading selectors and
456
+ > go look at timing, test data, or the app itself. It re-runs nothing, so it never claims
457
+ > your test is "flaky"; it only rules drift **out**. That alone can save an afternoon.
458
+
459
+ > ⚠️ It needs a baseline, because drift means *a locator that worked and stopped working*.
460
+ > On day one, `audit` (Step 5.4) is the verb that answers without one. And if it says it
461
+ > **cannot tell which locator the failure is about**, that's not a pass — usually the failing
462
+ > file was never `ingest`ed, or the locator is built at runtime from a variable.
463
+
464
+ Read-only: it opens no browser, re-runs nothing, and edits nothing. Repairs still go through
465
+ `fix`, below.
466
+
425
467
  ### Step 6.5 — Apply the safe fixes
426
468
  Agent: **"Fix my tests in the tests/ folder using that diff"**
427
469
  Terminal:
@@ -824,6 +866,7 @@ npx ia-qa-heal fix .ia-qa/baseline/checkout.json .ia-qa/mapping/checkout.json te
824
866
  npx ia-qa-heal fix .ia-qa/baseline/checkout.json .ia-qa/mapping/checkout.json tests/ # apply (never commits)
825
867
 
826
868
  npx ia-qa-heal ingest tests/ # inventory the selectors your suite uses → .ia-qa/usage.json
869
+ npx ia-qa-heal explain --junit results.xml # a test just failed — is it drift? (also --message "…", or pipe a log)
827
870
  npx ia-qa-heal audit # day one, no baseline: do my locators still name anything? (advisory)
828
871
  npx ia-qa-heal check # is the app sound? dead links · unnamed elements · name collisions · orphan pages
829
872
  npx ia-qa-heal graph --format markdown # the navigation graph, one card per page (RAG chunk / Confluence)
@@ -841,4 +884,5 @@ npx ia-qa-heal skill --install # teach your AI agent the rules (→ .
841
884
  Talking to an agent instead:
842
885
  > "Map my app at http://localhost:3000 to .ia-qa/mapping"
843
886
  > "Diff the baseline against the new contract"
887
+ > "This test failed — is it selector drift?"
844
888
  > "Fix my tests in tests/ — show me the diff, don't commit"
package/dist/cli/args.js CHANGED
@@ -24,6 +24,7 @@ exports.KNOWN_FLAGS = {
24
24
  fix: ['--dry-run', '--locators', '--dir'],
25
25
  ingest: ['--json'],
26
26
  audit: ['--strict', '--json'],
27
+ explain: ['--junit', '--message', '--strict', '--json'],
27
28
  check: ['--strict', '--json', '--offline', '--concurrency'],
28
29
  graph: ['--format', '--kind', '--out', '--open'],
29
30
  run: ['--yes', '--no-verify', '--locators', '--report', '--junit', '--json', '--open'],
@@ -1 +1 @@
1
- {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":";;;AA8BA,gDAeC;AA7CD;;;;;;;;;;;GAWG;AACU,QAAA,WAAW,GAAsC;IAC5D,IAAI,EAAE,EAAE;IACR,QAAQ,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC;IAC9G,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC;IAC7B,GAAG,EAAE,CAAC,eAAe,EAAE,WAAW,CAAC;IACnC,QAAQ,EAAE,EAAE;IACZ,IAAI,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC;IACtE,GAAG,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE,OAAO,CAAC;IACzC,MAAM,EAAE,CAAC,QAAQ,CAAC;IAClB,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC;IAC7B,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,CAAC;IAC3D,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC;IAChD,GAAG,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC;IACtF,KAAK,EAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC;IAC7D,OAAO,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC9B,EAAE,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,CAAC;CACnF,CAAC;AAEF,SAAgB,kBAAkB,CAAC,OAAe,EAAE,IAAc;IAChE,MAAM,KAAK,GAAG,mBAAW,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO;IAChC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACjC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,SAAS;QAChC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACb,eAAe,OAAO,0FAA0F;gBAC9G,4GAA4G;gBAC5G,8FAA8F,CACjG,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,qBAAqB,OAAO,8CAA8C,CAAC,CAAC;IAChH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":";;;AA+BA,gDAeC;AA9CD;;;;;;;;;;;GAWG;AACU,QAAA,WAAW,GAAsC;IAC5D,IAAI,EAAE,EAAE;IACR,QAAQ,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC;IAC9G,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC;IAC7B,GAAG,EAAE,CAAC,eAAe,EAAE,WAAW,CAAC;IACnC,QAAQ,EAAE,EAAE;IACZ,IAAI,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC;IACtE,GAAG,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE,OAAO,CAAC;IACzC,MAAM,EAAE,CAAC,QAAQ,CAAC;IAClB,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC;IAC7B,OAAO,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC;IACvD,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,CAAC;IAC3D,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC;IAChD,GAAG,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC;IACtF,KAAK,EAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC;IAC7D,OAAO,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC9B,EAAE,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,CAAC;CACnF,CAAC;AAEF,SAAgB,kBAAkB,CAAC,OAAe,EAAE,IAAc;IAChE,MAAM,KAAK,GAAG,mBAAW,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO;IAChC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACjC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,SAAS;QAChC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACb,eAAe,OAAO,0FAA0F;gBAC9G,4GAA4G;gBAC5G,8FAA8F,CACjG,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,qBAAqB,OAAO,8CAA8C,CAAC,CAAC;IAChH,CAAC;AACH,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { ExplainReport, FailureInput } from '../explain';
2
+ /**
3
+ * `ia-qa-heal explain` — start from a FAILURE instead of from a contract.
4
+ *
5
+ * The adoption gap `audit` closes is "no baseline on day one". This closes the other
6
+ * one: every verb here expects you to already be thinking about contracts, and nobody
7
+ * is. People arrive at a red build. `explain` takes the runner's own output, works out
8
+ * which locator it is about, and routes that locator through the machinery that already
9
+ * exists — it computes no verdict of its own.
10
+ *
11
+ * That last point is the design. This file runs `collectDirDiff`, the same function
12
+ * `diff --dir` and `run` come through, and then *selects* the rows that touch the
13
+ * failure. A second implementation of PASS/FIX/BLOCK is the CLI/MCP dispatch split in
14
+ * another costume, and it would quietly lose every refusal `fix` depends on
15
+ * (`unattributable`, masked names, conflicting rewrite targets).
16
+ *
17
+ * Read-only, offline, and it opens no browser: the two moments it compares were
18
+ * captured before it ran. Nothing here applies a repair — `fix` stays the only door.
19
+ *
20
+ * It deliberately does NOT append to `.ia-qa/history.jsonl`. History is the drift
21
+ * trend, one entry per measurement; this verb measures nothing new, it re-reads a diff
22
+ * that already happened. Writing an entry would count the same drift twice and put a
23
+ * bend in a chart that nothing in the app produced.
24
+ */
25
+ export type ExplainRefusalReason = 'no-input' | 'no-inventory' | 'no-baseline' | 'no-mapping' | 'no-failure' | 'no-locator';
26
+ export interface ExplainRefusal {
27
+ ok: false;
28
+ reason: ExplainRefusalReason;
29
+ message: string;
30
+ }
31
+ export interface ExplainSuccess {
32
+ ok: true;
33
+ report: ExplainReport;
34
+ }
35
+ export type ExplainOutcome = ExplainSuccess | ExplainRefusal;
36
+ /**
37
+ * The whole diagnosis, with no console and no exit code.
38
+ *
39
+ * Extracted from `runExplain` so the terminal and the MCP tool `explain_failure` share
40
+ * one computation *and* one wording — the same reason `auditProject` exists. The
41
+ * refusals are the half most worth sharing: they are what a second implementation would
42
+ * turn into a pass.
43
+ */
44
+ export declare function explainProject(failures: FailureInput[]): ExplainOutcome;
45
+ export declare function runExplain(args: string[]): Promise<void>;
@@ -0,0 +1,302 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.explainProject = explainProject;
37
+ exports.runExplain = runExplain;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const config_1 = require("../config");
41
+ const explain_1 = require("../explain");
42
+ const ingest_1 = require("../ingest");
43
+ const resolution_1 = require("../resolution");
44
+ const diff_1 = require("./diff");
45
+ const summary_1 = require("./summary");
46
+ function buildResolutionIndex(dir) {
47
+ const index = new Map();
48
+ for (const res of (0, resolution_1.loadAllResolutions)(dir)) {
49
+ for (const [selector, binding] of Object.entries(res.bindings ?? {})) {
50
+ const list = index.get(selector) ?? [];
51
+ list.push({ page: res.page, status: binding.status });
52
+ index.set(selector, list);
53
+ }
54
+ }
55
+ return index;
56
+ }
57
+ /**
58
+ * The whole diagnosis, with no console and no exit code.
59
+ *
60
+ * Extracted from `runExplain` so the terminal and the MCP tool `explain_failure` share
61
+ * one computation *and* one wording — the same reason `auditProject` exists. The
62
+ * refusals are the half most worth sharing: they are what a second implementation would
63
+ * turn into a pass.
64
+ */
65
+ function explainProject(failures) {
66
+ if (failures.length === 0) {
67
+ return {
68
+ ok: false,
69
+ reason: 'no-failure',
70
+ message: `❌ No test failure found in the input.\n\n` +
71
+ ` A JUnit file with no <failure>/<error> element describes a green run, and a\n` +
72
+ ` green run has nothing to explain. Pass the report from the build that failed.`,
73
+ };
74
+ }
75
+ // Order of checks, before the inventory one below. Pointed at a directory that is
76
+ // not a project at all — the ordinary `--config` typo — "usage.json does not exist"
77
+ // sends the reader to `ingest`, which will not help: there is nothing here to
78
+ // ingest *into*. Name the missing project, not the first artifact we happened to
79
+ // look for.
80
+ if (!fs.existsSync(path.join((0, config_1.baseDir)(), config_1.CONFIG_DIR))) {
81
+ return {
82
+ ok: false,
83
+ reason: 'no-inventory',
84
+ message: `❌ No ${config_1.CONFIG_DIR}/ directory in ${(0, config_1.baseDir)()}.\n\n` +
85
+ ` That path is not an ia-qa-heal project. Run \`ia-qa-heal init\` there, or point\n` +
86
+ ` \`--config\` at the directory that holds ${config_1.CONFIG_DIR}/.`,
87
+ };
88
+ }
89
+ const usage = (0, ingest_1.loadUsage)();
90
+ if (!usage) {
91
+ return {
92
+ ok: false,
93
+ reason: 'no-inventory',
94
+ message: `❌ No locator inventory — ${config_1.CONFIG_DIR}/usage.json does not exist.\n\n` +
95
+ ` This verb finds the locator inside your failure by intersecting the message\n` +
96
+ ` with the literals your suite actually writes. Without that inventory there is\n` +
97
+ ` nothing to intersect, and guessing at the message instead is exactly what this\n` +
98
+ ` tool must not do.\n\n` +
99
+ ` ia-qa-heal ingest <test-dir> (or set "testPaths" in .ia-qa/config.json)`,
100
+ };
101
+ }
102
+ const { candidates, unmatched } = (0, explain_1.extractLocators)(failures, usage);
103
+ if (candidates.length === 0) {
104
+ const seen = unmatched.length > 0 ? `\n\n Strings the failure quotes that look like locators but are in no inventory:\n ${unmatched.slice(0, 8).map((u) => `"${u}"`).join('\n ')}` : '';
105
+ return {
106
+ ok: false,
107
+ reason: 'no-locator',
108
+ message: `❌ Cannot tell which locator this failure is about.\n\n` +
109
+ ` This is NOT a pass — it is an unanswered question. Nothing in the failure text\n` +
110
+ ` matched a locator your suite is known to write, so the two most likely causes:\n` +
111
+ ` · the failing file was never ingested — re-run \`ia-qa-heal ingest\` over the WHOLE suite\n` +
112
+ ` · the locator is built dynamically (a variable, a template) — invisible to any\n` +
113
+ ` static scan, and to \`fix\` too\n` +
114
+ ` You can also name it yourself: ia-qa-heal explain --message "<the selector>"` +
115
+ seen,
116
+ };
117
+ }
118
+ const baseline = (0, config_1.baselineDir)();
119
+ const current = (0, config_1.mappingDir)();
120
+ if (!fs.existsSync(baseline)) {
121
+ return {
122
+ ok: false,
123
+ reason: 'no-baseline',
124
+ message: `❌ No baseline to compare against — ${path.resolve(baseline)} does not exist.\n\n` +
125
+ ` Drift needs two moments, and this verb is about drift specifically: a selector\n` +
126
+ ` that WORKED and stopped working. With one capture there is no such thing.\n\n` +
127
+ ` The day-one question — does my suite still name things that exist? — has its own\n` +
128
+ ` verb, and it needs no baseline:\n` +
129
+ ` ia-qa-heal audit\n\n` +
130
+ ` To gate on drift from now on: ia-qa-heal map && ia-qa-heal baseline`,
131
+ };
132
+ }
133
+ if (!fs.existsSync(current)) {
134
+ return {
135
+ ok: false,
136
+ reason: 'no-mapping',
137
+ message: `❌ No current capture — ${path.resolve(current)} does not exist.\n\n` +
138
+ ` Capture the app as it is now, then ask again:\n` +
139
+ ` ia-qa-heal map (or run your suite with IAQA_CAPTURE=1)`,
140
+ };
141
+ }
142
+ const collection = (0, diff_1.collectDirDiff)(baseline, current);
143
+ const pages = collection.reports.map((r) => ({
144
+ name: r.name,
145
+ rows: r.report.rows,
146
+ nameDrift: r.report.nameDrift,
147
+ bindingDrift: r.report.bindingDrift,
148
+ }));
149
+ const findings = (0, explain_1.judgeLocators)(candidates, pages, buildResolutionIndex((0, config_1.resolvedDir)()));
150
+ return {
151
+ ok: true,
152
+ report: {
153
+ verdict: (0, explain_1.explainVerdict)(findings),
154
+ failuresRead: failures.length,
155
+ findings,
156
+ unmatched,
157
+ pagesCompared: pages.length,
158
+ stalePages: collection.stale,
159
+ },
160
+ };
161
+ }
162
+ /* ------------------------------------------------------------------ *
163
+ * Input
164
+ * ------------------------------------------------------------------ */
165
+ function flagValue(args, flag) {
166
+ const i = args.indexOf(flag);
167
+ if (i === -1)
168
+ return undefined;
169
+ const next = args[i + 1];
170
+ if (!next || next.startsWith('-'))
171
+ throw new Error(`${flag} needs a value.`);
172
+ return next;
173
+ }
174
+ function readStdin() {
175
+ return new Promise((resolve) => {
176
+ let buf = '';
177
+ process.stdin.setEncoding('utf8');
178
+ process.stdin.on('data', (c) => {
179
+ buf += c;
180
+ });
181
+ process.stdin.on('end', () => resolve(buf));
182
+ process.stdin.on('error', () => resolve(''));
183
+ });
184
+ }
185
+ /**
186
+ * Where the failure comes from, in order: an explicit message, a JUnit file, a pipe.
187
+ *
188
+ * A raw `--message` is not parsed as XML even if it looks like it: someone pasting a
189
+ * message is answering the "which locator" question by hand, and second-guessing that
190
+ * would be the tool overriding the human on the one input it asked for.
191
+ */
192
+ async function readFailures(args) {
193
+ const message = flagValue(args, '--message');
194
+ if (message !== undefined)
195
+ return [{ text: message }];
196
+ const junit = flagValue(args, '--junit');
197
+ if (junit !== undefined) {
198
+ if (!fs.existsSync(junit))
199
+ throw new Error(`No such file: ${path.resolve(junit)}`);
200
+ return (0, explain_1.parseJUnitFailures)((0, config_1.stripBom)(fs.readFileSync(junit, 'utf8')));
201
+ }
202
+ if (!process.stdin.isTTY) {
203
+ const piped = await readStdin();
204
+ if (piped.trim()) {
205
+ // A pipe carries either a JUnit document or a log. Sniffing for the element we
206
+ // parse is enough to tell them apart, and cheaper than asking the user to say so.
207
+ return /<testcase\b/.test(piped)
208
+ ? (0, explain_1.parseJUnitFailures)((0, config_1.stripBom)(piped))
209
+ : [{ text: piped }];
210
+ }
211
+ }
212
+ return null;
213
+ }
214
+ /* ------------------------------------------------------------------ *
215
+ * Rendering
216
+ * ------------------------------------------------------------------ */
217
+ const ICON = { PASS: '✅', FIX: '🔧', BLOCK: '⛔' };
218
+ function renderFinding(f) {
219
+ const kind = f.kind === 'selector' ? 'selector' : 'name';
220
+ const how = f.source === 'quoted' ? '' : ' (matched by containment — check it is the right one)';
221
+ console.log(`\n ${ICON[f.verdict]} ${f.verdict} ${kind} "${f.literal}"${how}`);
222
+ if (f.page)
223
+ console.log(` page: ${f.page}`);
224
+ if (f.sites.length > 0) {
225
+ const where = f.sites.slice(0, 3).map((s) => `${s.file}:${s.line}`).join(', ');
226
+ const more = f.sites.length > 3 ? ` +${f.sites.length - 3} more` : '';
227
+ console.log(` used at: ${where}${more}`);
228
+ }
229
+ if (f.repair)
230
+ console.log(` proposed: ${f.repair.from} → ${f.repair.to}`);
231
+ if (f.now)
232
+ console.log(` now reaches: ${f.now}`);
233
+ console.log(` ${explain_1.REASON_ADVICE[f.reason]}`);
234
+ }
235
+ async function runExplain(args) {
236
+ const json = args.includes('--json');
237
+ const strict = args.includes('--strict');
238
+ const failures = await readFailures(args);
239
+ if (failures === null) {
240
+ console.error(`❌ Nothing to explain — give this verb a failure.\n\n` +
241
+ ` ia-qa-heal explain --junit results.xml a JUnit report from the failed build\n` +
242
+ ` ia-qa-heal explain --message "<error text>" paste the runner's message\n` +
243
+ ` <your test command> | ia-qa-heal explain pipe the output straight in\n\n` +
244
+ ` JUnit is the portable door: every major runner in every language emits it, so\n` +
245
+ ` this verb needs to know nothing about yours.`);
246
+ process.exitCode = 2;
247
+ return;
248
+ }
249
+ const outcome = explainProject(failures);
250
+ if (!outcome.ok) {
251
+ console.error(outcome.message);
252
+ // A refusal must never arrive as `verdict: null` next to a zero exit — that reads as
253
+ // a pass to anything scripting this. Exit 2 says "could not answer", distinct from
254
+ // the 0/1 a real verdict uses.
255
+ if (json)
256
+ console.log(JSON.stringify({ verdict: null, reason: outcome.reason }, null, 2));
257
+ process.exitCode = 2;
258
+ return;
259
+ }
260
+ const r = outcome.report;
261
+ if (json) {
262
+ console.log(JSON.stringify(r, null, 2));
263
+ process.exitCode = r.verdict === 'BLOCK' || (strict && r.verdict === 'FIX') ? 1 : 0;
264
+ return;
265
+ }
266
+ const icon = r.verdict === 'PASS' ? '✅' : r.verdict === 'FIX' ? '🔧' : '⛔';
267
+ console.log(`\n${icon} ${r.verdict} ia-qa-heal explain — is this failure selector drift?`);
268
+ const against = (0, summary_1.againstLine)((0, config_1.configuredBaseUrl)());
269
+ if (against)
270
+ console.log(against);
271
+ console.log(` ${r.failuresRead} failure${r.failuresRead === 1 ? '' : 's'} read · ` +
272
+ `${r.findings.length} locator${r.findings.length === 1 ? '' : 's'} identified · ` +
273
+ `${r.pagesCompared} page${r.pagesCompared === 1 ? '' : 's'} compared`);
274
+ for (const f of r.findings)
275
+ renderFinding(f);
276
+ if (r.verdict === 'PASS') {
277
+ console.log(`\n Every locator in this failure still resolves against the current capture.` +
278
+ `\n That rules OUT drift; it does not name the real cause, and nothing here re-ran` +
279
+ `\n your test. Look at timing, test data, or an application error.`);
280
+ }
281
+ if (r.unmatched.length > 0) {
282
+ console.log(`\n ℹ️ ${r.unmatched.length} quoted string${r.unmatched.length === 1 ? '' : 's'} in the failure look${r.unmatched.length === 1 ? 's' : ''} like a locator but ${r.unmatched.length === 1 ? 'is' : 'are'} in no inventory:` +
283
+ `\n ${r.unmatched.slice(0, 6).map((u) => `"${u}"`).join(', ')}` +
284
+ `\n Usually an un-ingested file, or a locator built at runtime. Re-run \`ia-qa-heal ingest\`.`);
285
+ }
286
+ if (r.stalePages.length > 0) {
287
+ // Coverage honesty, same rule as everywhere else here: a page left out of the
288
+ // comparison is `stale`, never a pass, and the verdict above does not cover it.
289
+ console.log(`\n ⚠️ ${r.stalePages.length} page${r.stalePages.length === 1 ? '' : 's'} could not be compared (both sides from the same capture):` +
290
+ `\n ${r.stalePages.slice(0, 6).join(', ')}` +
291
+ `\n If the failing locator lives there, this verdict does not cover it.`);
292
+ }
293
+ if (r.findings.some((f) => f.verdict === 'FIX')) {
294
+ console.log(`\n Nothing was written. \`explain\` only reports — review the proposals, then:` +
295
+ `\n ia-qa-heal fix --dry-run see the exact edits` +
296
+ `\n ia-qa-heal fix apply them`);
297
+ }
298
+ console.log('');
299
+ (0, summary_1.summaryLine)('explain', r.verdict === 'PASS' ? 'ok' : r.verdict === 'FIX' ? 'fix' : 'block', (0, explain_1.explainHeadline)(r), (0, explain_1.explainCounts)(r));
300
+ process.exitCode = r.verdict === 'BLOCK' || (strict && r.verdict === 'FIX') ? 1 : 0;
301
+ }
302
+ //# sourceMappingURL=explain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explain.js","sourceRoot":"","sources":["../../src/cli/explain.ts"],"names":[],"mappings":"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"}
package/dist/cli/index.js CHANGED
@@ -11,6 +11,7 @@ const diff_1 = require("./diff");
11
11
  const fix_1 = require("./fix");
12
12
  const ingest_1 = require("./ingest");
13
13
  const audit_1 = require("./audit");
14
+ const explain_1 = require("./explain");
14
15
  const check_1 = require("./check");
15
16
  const run_1 = require("./run");
16
17
  const discover_1 = require("./discover");
@@ -129,6 +130,20 @@ Usage:
129
130
  Read-only — never edits, never guesses silently.
130
131
  --strict exit 1 on a finding (default: advisory, exit 0)
131
132
  --json machine-readable output
133
+ ia-qa-heal explain Start from a FAILURE, not from a contract: paste what your
134
+ runner printed and get PASS/FIX/BLOCK for the locator it is
135
+ about. PASS is the point — it rules drift OUT, so you stop
136
+ hunting selectors and look at timing or data instead.
137
+ Framework- and language-agnostic: it never parses a runner's
138
+ error grammar, it intersects the text with the literals
139
+ \`ingest\` read from your own sources. Read-only, offline,
140
+ opens no browser, re-runs nothing, applies nothing.
141
+ --junit <file> a JUnit report from the failed build (every
142
+ major runner in every language emits one)
143
+ --message "<txt>" paste the error text yourself
144
+ (no flag) reads a piped log on stdin
145
+ --strict exit 1 on FIX too (BLOCK always exits 1)
146
+ --json machine-readable output
132
147
  ia-qa-heal check Is the app you mapped sound? Asks what a diff structurally
133
148
  cannot — a green diff over a page whose links all 404 is
134
149
  still green. Dead links · elements with no accessible name ·
@@ -334,6 +349,9 @@ async function main() {
334
349
  case 'audit':
335
350
  await (0, audit_1.runAudit)(rest);
336
351
  break;
352
+ case 'explain':
353
+ await (0, explain_1.runExplain)(rest);
354
+ break;
337
355
  case 'check':
338
356
  await (0, check_1.runCheck)(rest);
339
357
  break;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}