@jevitate/cli 0.8.0 → 0.10.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 (192) hide show
  1. package/dist/anchor-baselines.d.ts +26 -0
  2. package/dist/anchor-baselines.js +25 -0
  3. package/dist/anchor-baselines.js.map +1 -0
  4. package/dist/approval-provenance.d.ts +48 -2
  5. package/dist/approval-provenance.js +110 -6
  6. package/dist/approval-provenance.js.map +1 -1
  7. package/dist/bin.js +25111 -17835
  8. package/dist/browser-cli.d.ts +10 -0
  9. package/dist/browser-cli.js +50 -0
  10. package/dist/browser-cli.js.map +1 -0
  11. package/dist/build-info.generated.js +2 -2
  12. package/dist/catalog-analysis.js +14 -0
  13. package/dist/catalog-analysis.js.map +1 -1
  14. package/dist/catalog-api.js +12 -4
  15. package/dist/catalog-api.js.map +1 -1
  16. package/dist/catalog-bundle-api.d.ts +73 -0
  17. package/dist/catalog-bundle-api.js +206 -0
  18. package/dist/catalog-bundle-api.js.map +1 -0
  19. package/dist/catalog-bundle-findings.d.ts +54 -0
  20. package/dist/catalog-bundle-findings.js +252 -0
  21. package/dist/catalog-bundle-findings.js.map +1 -0
  22. package/dist/catalog-bundle.d.ts +192 -0
  23. package/dist/catalog-bundle.js +578 -0
  24. package/dist/catalog-bundle.js.map +1 -0
  25. package/dist/catalog-cli.d.ts +6 -0
  26. package/dist/catalog-cli.js +180 -5
  27. package/dist/catalog-cli.js.map +1 -1
  28. package/dist/catalog-refs.d.ts +42 -0
  29. package/dist/catalog-refs.js +188 -0
  30. package/dist/catalog-refs.js.map +1 -0
  31. package/dist/catalog-review.d.ts +3 -1
  32. package/dist/catalog-review.js +61 -0
  33. package/dist/catalog-review.js.map +1 -1
  34. package/dist/catalog.d.ts +27 -3
  35. package/dist/catalog.js +46 -2
  36. package/dist/catalog.js.map +1 -1
  37. package/dist/change-context.d.ts +44 -0
  38. package/dist/change-context.js +203 -0
  39. package/dist/change-context.js.map +1 -0
  40. package/dist/check-api.d.ts +1 -1
  41. package/dist/check-api.js +206 -16
  42. package/dist/check-api.js.map +1 -1
  43. package/dist/check-cli.d.ts +2 -1
  44. package/dist/check-cli.js +117 -8
  45. package/dist/check-cli.js.map +1 -1
  46. package/dist/check-execute.d.ts +28 -1
  47. package/dist/check-execute.js +110 -27
  48. package/dist/check-execute.js.map +1 -1
  49. package/dist/check-plan.d.ts +14 -0
  50. package/dist/check-plan.js +24 -1
  51. package/dist/check-plan.js.map +1 -1
  52. package/dist/check-types.d.ts +137 -5
  53. package/dist/check-types.js +8 -0
  54. package/dist/check-types.js.map +1 -1
  55. package/dist/cli-output.d.ts +6 -0
  56. package/dist/cli-output.js +26 -1
  57. package/dist/cli-output.js.map +1 -1
  58. package/dist/cli-shared.d.ts +10 -0
  59. package/dist/cli-shared.js +0 -4
  60. package/dist/cli-shared.js.map +1 -1
  61. package/dist/exit-codes.d.ts +6 -3
  62. package/dist/exit-codes.js +24 -3
  63. package/dist/exit-codes.js.map +1 -1
  64. package/dist/explore-adversarial.js +2 -2
  65. package/dist/explore-adversarial.js.map +1 -1
  66. package/dist/explore-cli.js +3 -2
  67. package/dist/explore-cli.js.map +1 -1
  68. package/dist/explore-coverage.js +3 -3
  69. package/dist/explore-coverage.js.map +1 -1
  70. package/dist/explore-feature.js +3 -3
  71. package/dist/explore-feature.js.map +1 -1
  72. package/dist/explore-goal.js +11 -5
  73. package/dist/explore-goal.js.map +1 -1
  74. package/dist/findings-filing.d.ts +6 -0
  75. package/dist/findings-filing.js +15 -1
  76. package/dist/findings-filing.js.map +1 -1
  77. package/dist/forge-verify.d.ts +224 -0
  78. package/dist/forge-verify.js +649 -0
  79. package/dist/forge-verify.js.map +1 -0
  80. package/dist/heal-probe-guard.d.ts +9 -0
  81. package/dist/heal-probe-guard.js +113 -0
  82. package/dist/heal-probe-guard.js.map +1 -0
  83. package/dist/host-health-run.d.ts +32 -1
  84. package/dist/host-health-run.js +38 -1
  85. package/dist/host-health-run.js.map +1 -1
  86. package/dist/init-codeowners.d.ts +19 -0
  87. package/dist/init-codeowners.js +66 -0
  88. package/dist/init-codeowners.js.map +1 -1
  89. package/dist/job-draft-api.d.ts +52 -0
  90. package/dist/job-draft-api.js +110 -0
  91. package/dist/job-draft-api.js.map +1 -0
  92. package/dist/journeeze-api.d.ts +71 -0
  93. package/dist/journeeze-api.js +285 -0
  94. package/dist/journeeze-api.js.map +1 -0
  95. package/dist/journeeze-connect.d.ts +156 -0
  96. package/dist/journeeze-connect.js +357 -0
  97. package/dist/journeeze-connect.js.map +1 -0
  98. package/dist/journey-anchor-gate.d.ts +52 -0
  99. package/dist/journey-anchor-gate.js +101 -0
  100. package/dist/journey-anchor-gate.js.map +1 -0
  101. package/dist/journey-api.d.ts +43 -3
  102. package/dist/journey-api.js +226 -21
  103. package/dist/journey-api.js.map +1 -1
  104. package/dist/journey-cli.js +162 -20
  105. package/dist/journey-cli.js.map +1 -1
  106. package/dist/journey-heal.d.ts +74 -0
  107. package/dist/journey-heal.js +180 -0
  108. package/dist/journey-heal.js.map +1 -0
  109. package/dist/journey-lint-sarif.d.ts +3 -2
  110. package/dist/journey-lint-sarif.js +9 -2
  111. package/dist/journey-lint-sarif.js.map +1 -1
  112. package/dist/journey-migrate-api.d.ts +54 -0
  113. package/dist/journey-migrate-api.js +64 -0
  114. package/dist/journey-migrate-api.js.map +1 -0
  115. package/dist/journey-network-checks.d.ts +5 -1
  116. package/dist/journey-network-checks.js +15 -4
  117. package/dist/journey-network-checks.js.map +1 -1
  118. package/dist/journey-prefix.js +2 -2
  119. package/dist/journey-prefix.js.map +1 -1
  120. package/dist/journey-proposal-store.d.ts +109 -0
  121. package/dist/journey-proposal-store.js +365 -0
  122. package/dist/journey-proposal-store.js.map +1 -0
  123. package/dist/journey-result-record.d.ts +42 -0
  124. package/dist/journey-result-record.js +33 -0
  125. package/dist/journey-result-record.js.map +1 -0
  126. package/dist/journey-review-api.js +16 -1
  127. package/dist/journey-review-api.js.map +1 -1
  128. package/dist/journey-review.d.ts +18 -1
  129. package/dist/journey-review.js +116 -5
  130. package/dist/journey-review.js.map +1 -1
  131. package/dist/journey-stale-api.d.ts +40 -0
  132. package/dist/journey-stale-api.js +57 -0
  133. package/dist/journey-stale-api.js.map +1 -0
  134. package/dist/launch-armed.js +5 -1
  135. package/dist/launch-armed.js.map +1 -1
  136. package/dist/locator-health-api.d.ts +101 -0
  137. package/dist/locator-health-api.js +203 -0
  138. package/dist/locator-health-api.js.map +1 -0
  139. package/dist/locator-health.d.ts +195 -0
  140. package/dist/locator-health.js +419 -0
  141. package/dist/locator-health.js.map +1 -0
  142. package/dist/login-cli.d.ts +2 -0
  143. package/dist/login-cli.js +56 -11
  144. package/dist/login-cli.js.map +1 -1
  145. package/dist/mcp-api.d.ts +5 -1
  146. package/dist/mcp-api.js +53 -8
  147. package/dist/mcp-api.js.map +1 -1
  148. package/dist/mcp-cli-tools.d.ts +3 -1
  149. package/dist/mcp-cli-tools.js +80 -10
  150. package/dist/mcp-cli-tools.js.map +1 -1
  151. package/dist/multi-run.d.ts +7 -6
  152. package/dist/multi-run.js +5 -4
  153. package/dist/multi-run.js.map +1 -1
  154. package/dist/persona-login.d.ts +60 -3
  155. package/dist/persona-login.js +341 -31
  156. package/dist/persona-login.js.map +1 -1
  157. package/dist/program.js +2 -0
  158. package/dist/program.js.map +1 -1
  159. package/dist/project-config.d.ts +29 -0
  160. package/dist/project-config.js +76 -0
  161. package/dist/project-config.js.map +1 -0
  162. package/dist/report-api.d.ts +1 -0
  163. package/dist/report-api.js +1 -0
  164. package/dist/report-api.js.map +1 -1
  165. package/dist/resource-preflight.js +5 -3
  166. package/dist/resource-preflight.js.map +1 -1
  167. package/dist/run-metadata.d.ts +5 -2
  168. package/dist/run-metadata.js +10 -3
  169. package/dist/run-metadata.js.map +1 -1
  170. package/dist/run-tags-cli.d.ts +2 -0
  171. package/dist/run-tags-cli.js +8 -2
  172. package/dist/run-tags-cli.js.map +1 -1
  173. package/dist/self-heal-adapter.d.ts +43 -27
  174. package/dist/self-heal-adapter.js +196 -62
  175. package/dist/self-heal-adapter.js.map +1 -1
  176. package/dist/source-cli.js +5 -3
  177. package/dist/source-cli.js.map +1 -1
  178. package/dist/suite-explore-options.js +1 -0
  179. package/dist/suite-explore-options.js.map +1 -1
  180. package/dist/sweep-api.d.ts +23 -0
  181. package/dist/sweep-api.js +39 -8
  182. package/dist/sweep-api.js.map +1 -1
  183. package/dist/sweep-cli.js +3 -1
  184. package/dist/sweep-cli.js.map +1 -1
  185. package/dist/ux-usability.js +3 -2
  186. package/dist/ux-usability.js.map +1 -1
  187. package/package.json +17 -15
  188. package/skills/jevitate-ci-check/SKILL.md +25 -1
  189. package/skills/jevitate-getting-started/SKILL.md +9 -3
  190. package/skills/jevitate-mission-scope/SKILL.md +2 -2
  191. package/skills/jevitate-run-journey/SKILL.md +36 -5
  192. package/skills/jevitate-test-campaign/SKILL.md +13 -0
@@ -0,0 +1,419 @@
1
+ import { looksGenerated } from "@jevitate/recorder";
2
+ // === Classification ===
3
+ const LEVEL_RANK = { low: 0, medium: 1, high: 2 };
4
+ /** One notch down: a rung that only resolves with an ordinal (the recorder's `CAPPED_STABILITY`). */
5
+ const CAPPED = { high: "medium", medium: "low", low: "low" };
6
+ const REASON_TEXT = {
7
+ "no-test-id": "no test id",
8
+ "test-id-not-in-convention": "test id attribute is not in the convention",
9
+ "tflow-id-not-a-test-id": "data-tflow-id is tracking metadata, not a test id",
10
+ "generated-value": "generated-looking id or name",
11
+ "no-accessible-name": "no accessible name",
12
+ "duplicate-name": "duplicate name needs disambiguation (nth)",
13
+ "positional-css": "deep or positional css path",
14
+ "text-copy": "text locator on copy likely to change",
15
+ };
16
+ /** The target a step acts on, or null (navigate, press, assert, a forEach's items are its own). */
17
+ export function stepTarget(step) {
18
+ switch (step.kind) {
19
+ case "click":
20
+ case "fill":
21
+ case "waitFor":
22
+ case "extract":
23
+ case "select":
24
+ case "upload":
25
+ case "editText":
26
+ return step.target;
27
+ default:
28
+ return null;
29
+ }
30
+ }
31
+ /** The recorded rung replay tries (an anchor first, as `resolveTarget` does). */
32
+ function recordedRung(d) {
33
+ if (d.anchor !== undefined && d.testId === undefined && (d.anchor.id !== undefined || d.anchor.name !== undefined))
34
+ return "anchor";
35
+ return ownRung(d);
36
+ }
37
+ function ownRung(d) {
38
+ if (d.testId)
39
+ return "testId";
40
+ if (d.role && d.name)
41
+ return "role+name";
42
+ if (d.label)
43
+ return "label";
44
+ if (d.text)
45
+ return "text";
46
+ if (d.css)
47
+ return "css";
48
+ return d.role ? "role" : "css";
49
+ }
50
+ function asRung(r) {
51
+ return ["testId", "anchor", "role+name", "role", "label", "text", "css"].find((x) => x === r) ?? "css";
52
+ }
53
+ /** How deep a css path is, and whether it is positional. */
54
+ function cssShape(css) {
55
+ return { depth: css.split(">").length, positional: /:nth-(of-type|child)\(|:first-|:last-/.test(css) };
56
+ }
57
+ function describeLocator(d, rung) {
58
+ const nth = d.ordinal === undefined ? "" : ` nth=${d.ordinal}`;
59
+ switch (rung) {
60
+ case "testId":
61
+ return `testId[${d.testIdAttr ?? "data-testid"}]=${d.testId ?? "?"}`;
62
+ case "anchor":
63
+ return d.anchor?.id !== undefined ? `[id=${JSON.stringify(d.anchor.id)}]` : `[name=${JSON.stringify(d.anchor?.name ?? "")}]`;
64
+ case "role+name":
65
+ return `role=${d.role ?? "?"} name=${JSON.stringify(d.name ?? "")}${nth}`;
66
+ case "label":
67
+ return `label=${JSON.stringify(d.label ?? "")}${nth}`;
68
+ case "text":
69
+ return `text=${JSON.stringify(d.text ?? "")}${nth}`;
70
+ default:
71
+ return `css=${d.css ?? "?"}`;
72
+ }
73
+ }
74
+ /**
75
+ * One target's verdict against the convention. `via` (a run's resolution) replaces the recorded rung
76
+ * when present; everything else is read from the descriptor.
77
+ */
78
+ export function classifyTarget(d, testIdAttributes, via) {
79
+ const rung = via === undefined ? recordedRung(d) : asRung(via.rung);
80
+ const ordinal = via === undefined ? d.ordinal : via.ordinal;
81
+ const codes = [];
82
+ let level;
83
+ switch (rung) {
84
+ case "testId": {
85
+ const attr = (via?.testIdAttr ?? d.testIdAttr ?? "data-testid").toLowerCase();
86
+ const generated = looksGenerated(d.testId ?? "");
87
+ level = generated ? "low" : "high";
88
+ if (attr === "data-tflow-id")
89
+ codes.push("tflow-id-not-a-test-id");
90
+ else if (!testIdAttributes.includes(attr))
91
+ codes.push("test-id-not-in-convention");
92
+ if (generated)
93
+ codes.push("generated-value");
94
+ break;
95
+ }
96
+ case "anchor":
97
+ // A non-generated id/name attribute (the recorder refuses generated ones): sturdy, but not the convention.
98
+ level = "medium";
99
+ codes.push("no-test-id");
100
+ break;
101
+ case "role+name":
102
+ level = looksGenerated(d.name ?? "") ? "low" : "high";
103
+ codes.push("no-test-id");
104
+ if (level === "low")
105
+ codes.push("generated-value");
106
+ break;
107
+ case "label":
108
+ level = "medium";
109
+ codes.push("no-test-id");
110
+ break;
111
+ case "text":
112
+ level = "medium";
113
+ codes.push("no-test-id", "text-copy");
114
+ break;
115
+ default: {
116
+ level = "low";
117
+ codes.push("no-test-id");
118
+ const shape = cssShape(d.css ?? "");
119
+ if (shape.positional || shape.depth > 3)
120
+ codes.push("positional-css");
121
+ if (/#[A-Za-z0-9_-]*\d{4}|[0-9a-fA-F]{8}/.test(d.css ?? ""))
122
+ codes.push("generated-value");
123
+ }
124
+ }
125
+ if (ordinal !== undefined && rung !== "testId" && rung !== "anchor" && rung !== "css") {
126
+ level = CAPPED[level];
127
+ codes.push("duplicate-name");
128
+ }
129
+ if (rung !== "testId" && !(d.name || d.label))
130
+ codes.push("no-accessible-name");
131
+ if (d.tflowId !== undefined && rung !== "testId" && !codes.includes("tflow-id-not-a-test-id"))
132
+ codes.push("tflow-id-not-a-test-id");
133
+ return { rung, level, codes };
134
+ }
135
+ // === Suggestions ===
136
+ /** `"Save contact"` → `save-contact` (ASCII letters and digits, at most 40 chars). */
137
+ export function kebabCase(s) {
138
+ return s
139
+ .normalize("NFKD")
140
+ .replace(/[̀-ͯ]/g, "")
141
+ .replace(/([a-z0-9])([A-Z])/g, "$1-$2")
142
+ .toLowerCase()
143
+ .replace(/[^a-z0-9]+/g, "-")
144
+ .replace(/^-+|-+$/g, "")
145
+ .slice(0, 40)
146
+ .replace(/-+$/g, "");
147
+ }
148
+ /** The path of a page URL (`https://x/contacts/new?a=1` → `/contacts/new`); a path is kept as is. */
149
+ export function routeOf(url) {
150
+ if (url === undefined || url === "")
151
+ return undefined;
152
+ try {
153
+ return new URL(url).pathname;
154
+ }
155
+ catch {
156
+ const path = url.split(/[?#]/)[0] ?? url;
157
+ return path.startsWith("/") ? path : `/${path}`;
158
+ }
159
+ }
160
+ function singular(word) {
161
+ if (/ies$/.test(word))
162
+ return word.replace(/ies$/, "y");
163
+ if (/(ss|us)$/.test(word))
164
+ return word;
165
+ return word.replace(/s$/, "");
166
+ }
167
+ /** The route's first meaningful segment (not an id or a verb like `new`/`edit`), singular. */
168
+ function routeWords(route) {
169
+ return (route ?? "").split("/").filter((s) => s !== "" && !/^\d+$/.test(s) && !looksGenerated(s) && !/^(new|edit|create|index|view)$/i.test(s));
170
+ }
171
+ function routeNoun(route) {
172
+ const first = routeWords(route)[0];
173
+ return first === undefined ? undefined : singular(kebabCase(first));
174
+ }
175
+ /**
176
+ * The suggested test id: the element's name in kebab-case, with the route's noun when the name is a
177
+ * single word (`Save` on /contacts/new → `save-contact`); an unnamed element is named by its route
178
+ * and tag (`contacts-div`).
179
+ */
180
+ export function suggestTestId(name, route, fallbackTag) {
181
+ const base = name === undefined ? "" : kebabCase(name);
182
+ const noun = routeNoun(route);
183
+ if (base !== "")
184
+ return !base.includes("-") && noun !== undefined && !base.includes(noun) ? `${base}-${noun}` : base;
185
+ const where = kebabCase(routeWords(route).join("-"));
186
+ return `${where === "" ? "page" : where}-${fallbackTag}`;
187
+ }
188
+ function lastCssTag(css) {
189
+ const last = (css ?? "").split(">").pop()?.trim() ?? "";
190
+ return /^([a-z][a-z0-9-]*)/i.exec(last)?.[1]?.toLowerCase() ?? "element";
191
+ }
192
+ function describeElement(d) {
193
+ const name = d.name ?? d.label;
194
+ if (d.role && name)
195
+ return `the ${JSON.stringify(name)} ${d.role}`;
196
+ if (d.label)
197
+ return `the ${JSON.stringify(d.label)} field`;
198
+ if (d.role)
199
+ return `the ${d.role}`;
200
+ if (d.text)
201
+ return `the element with text ${JSON.stringify(d.text.length > 40 ? `${d.text.slice(0, 40)}…` : d.text)}`;
202
+ if (d.testId)
203
+ return `the element with ${d.testIdAttr ?? "data-testid"}=${JSON.stringify(d.testId)}`;
204
+ return `the element at css ${JSON.stringify(d.css ?? "?")}`;
205
+ }
206
+ /** The element's identity across steps and runs: route + role + name (else its css). */
207
+ export function suggestionKey(d, route) {
208
+ const name = d.name ?? d.label ?? d.text;
209
+ if (name !== undefined)
210
+ return `${route ?? ""}|${d.role ?? ""}|${name}`;
211
+ if (d.testId !== undefined)
212
+ return `${route ?? ""}|testid|${d.testId}`;
213
+ return `${route ?? ""}|css|${d.css ?? ""}`;
214
+ }
215
+ function fixFor(d, codes, attribute, testId, element, route) {
216
+ const on = route === undefined ? "" : ` on ${route}`;
217
+ const named = codes.includes("no-accessible-name") ? " and give it an accessible name (visible text or aria-label)" : "";
218
+ if (codes.includes("test-id-not-in-convention") && d.testId !== undefined && !looksGenerated(d.testId)) {
219
+ return `use ${attribute}=${JSON.stringify(d.testId)} instead of ${d.testIdAttr ?? "?"} on ${element}${on} (or add ${d.testIdAttr ?? "?"} to testIdAttributes in .jevitate/project.json)`;
220
+ }
221
+ if (d.testId !== undefined && looksGenerated(d.testId)) {
222
+ return `replace the generated ${d.testIdAttr ?? attribute}=${JSON.stringify(d.testId)} on ${element}${on} with a stable ${attribute}=${JSON.stringify(testId)}`;
223
+ }
224
+ return `add ${attribute}=${JSON.stringify(testId)} to ${element}${on}${named}`;
225
+ }
226
+ function buildSuggestion(d, codes, route, attribute, html, occurrence) {
227
+ const name = d.name ?? d.label ?? d.text;
228
+ const testId = suggestTestId(d.testId !== undefined && !looksGenerated(d.testId) ? d.testId : name, route, lastCssTag(d.css));
229
+ const element = describeElement(d);
230
+ return {
231
+ key: suggestionKey(d, route),
232
+ ...(route === undefined ? {} : { route }),
233
+ ...(d.role === undefined ? {} : { role: d.role }),
234
+ ...(name === undefined ? {} : { name }),
235
+ element,
236
+ ...(html === undefined ? {} : { html: html.length > 160 ? `${html.slice(0, 160)}…` : html }),
237
+ attribute,
238
+ testId,
239
+ fix: fixFor(d, codes, attribute, testId, element, route),
240
+ reasons: codes.map((c) => REASON_TEXT[c]),
241
+ occurrences: [occurrence],
242
+ };
243
+ }
244
+ /** Merges suggestions for the same element (route + role + name): occurrences and reasons combined. */
245
+ export function dedupeSuggestions(lists) {
246
+ const byKey = new Map();
247
+ for (const s of lists.flat()) {
248
+ const prev = byKey.get(s.key);
249
+ if (prev === undefined) {
250
+ byKey.set(s.key, s);
251
+ continue;
252
+ }
253
+ const occ = [...prev.occurrences];
254
+ for (const o of s.occurrences) {
255
+ if (!occ.some((p) => p.journeyId === o.journeyId && p.index === o.index && p.stepId === o.stepId))
256
+ occ.push(o);
257
+ }
258
+ byKey.set(s.key, {
259
+ ...prev,
260
+ ...(prev.html === undefined && s.html !== undefined ? { html: s.html } : {}),
261
+ reasons: [...new Set([...prev.reasons, ...s.reasons])],
262
+ occurrences: occ,
263
+ });
264
+ }
265
+ // The elements most steps depend on first: the highest-value fixes lead the work list.
266
+ return [...byKey.values()].sort((a, b) => b.occurrences.length - a.occurrences.length || a.key.localeCompare(b.key));
267
+ }
268
+ // === Analysis ===
269
+ function flatWithRoute(rec) {
270
+ return rec.pages.flatMap((p) => p.steps.map((recorded) => ({ recorded, route: routeOf(p.url) })));
271
+ }
272
+ export function emptyLevels() {
273
+ return { high: 0, medium: 0, low: 0 };
274
+ }
275
+ /** `7/9 steps on stable locators; 2 brittle (high 7 · medium 1 · low 1)`. */
276
+ export function healthLine(h) {
277
+ const total = h.stable + h.brittle;
278
+ if (total === 0)
279
+ return "no steps act on a target";
280
+ return `${h.stable}/${total} steps on stable locators; ${h.brittle} brittle (high ${h.levels.high} · medium ${h.levels.medium} · low ${h.levels.low})`;
281
+ }
282
+ /**
283
+ * A recording's locator health: every step with a target (flat index, as the interpreter numbers
284
+ * them), against the convention; with `resolved`, the rung each step actually matched at replay.
285
+ */
286
+ export function analyzeRecording(rec, opts) {
287
+ const attribute = opts.testIdAttributes[0] ?? "data-testid";
288
+ const resolvedBy = new Map((opts.resolved ?? []).map((r) => [r.index, r]));
289
+ const steps = [];
290
+ const suggestions = [];
291
+ const levels = { high: 0, medium: 0, low: 0 };
292
+ flatWithRoute(rec).forEach(({ recorded, route }, index) => {
293
+ const d = stepTarget(recorded.step);
294
+ if (d === null)
295
+ return;
296
+ const via = resolvedBy.get(index);
297
+ const v = classifyTarget(d, opts.testIdAttributes, via);
298
+ const brittle = v.codes.length > 0;
299
+ levels[v.level] += 1;
300
+ const stepId = recorded.stepId ?? via?.stepId;
301
+ let key;
302
+ if (brittle) {
303
+ const occurrence = { ...(opts.journeyId === undefined ? {} : { journeyId: opts.journeyId }), index, ...(stepId === undefined ? {} : { stepId }) };
304
+ const s = buildSuggestion(d, v.codes, route, attribute, opts.html?.get(index), occurrence);
305
+ suggestions.push(s);
306
+ key = s.key;
307
+ }
308
+ steps.push({
309
+ ...(stepId === undefined ? {} : { stepId }),
310
+ index,
311
+ kind: recorded.step.kind,
312
+ rung: v.rung,
313
+ level: v.level,
314
+ stability: brittle ? "brittle" : "stable",
315
+ source: via === undefined ? "recorded" : "resolved",
316
+ ...(route === undefined ? {} : { route }),
317
+ locator: describeLocator(d, v.rung),
318
+ reasons: v.codes.map((c) => REASON_TEXT[c]),
319
+ reasonCodes: v.codes,
320
+ ...(key === undefined ? {} : { suggestion: key }),
321
+ });
322
+ });
323
+ const stable = steps.filter((s) => s.stability === "stable").length;
324
+ const brittle = steps.length - stable;
325
+ return { stable, brittle, steps, levels, line: healthLine({ stable, brittle, levels }), suggestions: dedupeSuggestions([suggestions]) };
326
+ }
327
+ /** Totals over several healths (a report, a check): counts, levels and the de-duplicated work list. */
328
+ export function combineHealth(healths) {
329
+ const levels = { high: 0, medium: 0, low: 0 };
330
+ let stable = 0;
331
+ let brittle = 0;
332
+ for (const h of healths) {
333
+ stable += h.stable;
334
+ brittle += h.brittle;
335
+ levels.high += h.levels.high;
336
+ levels.medium += h.levels.medium;
337
+ levels.low += h.levels.low;
338
+ }
339
+ return { stable, brittle, levels, line: healthLine({ stable, brittle, levels }), suggestions: dedupeSuggestions(healths.map((h) => h.suggestions)) };
340
+ }
341
+ // === Gate ===
342
+ /** `check --max-brittle-steps <n>`: true when a Journey item's brittle steps exceed the opt-in threshold. */
343
+ export function exceedsBrittleSteps(health, maxBrittleSteps) {
344
+ return maxBrittleSteps !== undefined && health.brittle > maxBrittleSteps;
345
+ }
346
+ function stepKey(s) {
347
+ return s.stepId ?? `#${s.index}`;
348
+ }
349
+ function score(s) {
350
+ return (s.stability === "stable" ? 10 : 0) + LEVEL_RANK[s.level ?? (s.stability === "stable" ? "high" : "low")];
351
+ }
352
+ /**
353
+ * The trend of `current` against `baseline` (a previous report or run of the same Journey), keyed by
354
+ * step id (else index): a Journey re-recorded or healed after the app added test ids shows its
355
+ * improvement; a step that fell back to a brittle rung shows as a regression.
356
+ */
357
+ export function compareLocatorHealth(current, baseline) {
358
+ const before = new Map(baseline.steps.map((s) => [stepKey(s), s]));
359
+ const seen = new Set();
360
+ const changes = [];
361
+ let unchanged = 0;
362
+ let added = 0;
363
+ const shape = (s) => ({ rung: s.rung, level: s.level ?? (s.stability === "stable" ? "high" : "low"), stability: s.stability });
364
+ for (const s of current.steps) {
365
+ const key = stepKey(s);
366
+ seen.add(key);
367
+ const b = before.get(key);
368
+ if (b === undefined) {
369
+ added++;
370
+ continue;
371
+ }
372
+ const delta = score(s) - score(b);
373
+ if (delta === 0)
374
+ unchanged++;
375
+ else
376
+ changes.push({ key, from: shape(b), to: shape(s), direction: delta > 0 ? "improved" : "regressed" });
377
+ }
378
+ const removed = [...before.keys()].filter((k) => !seen.has(k)).length;
379
+ return {
380
+ improved: changes.filter((c) => c.direction === "improved").length,
381
+ regressed: changes.filter((c) => c.direction === "regressed").length,
382
+ unchanged,
383
+ added,
384
+ removed,
385
+ brittleDelta: current.brittle - baseline.brittle,
386
+ changes,
387
+ };
388
+ }
389
+ /** `trend vs baseline: 2 improved, 1 regressed (brittle -1)`. */
390
+ export function trendLine(t) {
391
+ const sign = t.brittleDelta > 0 ? `+${t.brittleDelta}` : String(t.brittleDelta);
392
+ return `trend vs baseline: ${t.improved} improved, ${t.regressed} regressed (brittle ${sign})`;
393
+ }
394
+ /** The compact form of a detail: per-step rung/stability/reasons, and the top `top` fixes. */
395
+ export function compactHealth(h, top = 5) {
396
+ return {
397
+ stable: h.stable,
398
+ brittle: h.brittle,
399
+ levels: h.levels,
400
+ line: h.line,
401
+ steps: h.steps.map((s) => ({
402
+ ...(s.stepId === undefined ? {} : { stepId: s.stepId }),
403
+ index: s.index,
404
+ rung: s.rung,
405
+ stability: s.stability,
406
+ reasons: s.reasons,
407
+ ...("level" in s ? { level: s.level } : {}),
408
+ })),
409
+ suggestions: h.suggestions.slice(0, top).map((s) => ({
410
+ key: s.key,
411
+ element: s.element,
412
+ fix: s.fix,
413
+ reasons: s.reasons,
414
+ ...(s.route === undefined ? {} : { route: s.route }),
415
+ steps: s.occurrences.length,
416
+ })),
417
+ };
418
+ }
419
+ //# sourceMappingURL=locator-health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locator-health.js","sourceRoot":"","sources":["../src/locator-health.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,8 @@ export interface LoginResult {
6
6
  /** Absolute path of the saved storage state (mode 0600). */
7
7
  readonly saved: string;
8
8
  readonly loginUrl: string;
9
+ /** #449: `form` (a sign-in page driven) or `api` (an HTTP endpoint POSTed to). */
10
+ readonly method: "form" | "api";
9
11
  /** Where the sign-in ended (token-like query values redacted). */
10
12
  readonly landedUrl: string;
11
13
  readonly userEnv: string;
package/dist/login-cli.js CHANGED
@@ -5,12 +5,12 @@ import { fail, ok } from "./envelope.js";
5
5
  import { emitCommandResult } from "./cli-shared.js";
6
6
  import { positiveIntArg } from "./cli-args.js";
7
7
  import { loadPersonasFile, MultiRunArgsError, projectPersonas } from "./multi-run.js";
8
- import { checkSaveTarget, LoginArgsError, LoginFailedError, loginFromFlags, mintStorageState } from "./persona-login.js";
8
+ import { apiVerifyUrl, checkSaveTarget, LoginArgsError, LoginFailedError, loginFromFlags, mintStorageState, parseAuthCheck } from "./persona-login.js";
9
9
  const DEFAULT_TIMEOUT_S = 30;
10
10
  const PERSONA_NAME = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$/;
11
11
  function formatLoginHuman(data) {
12
12
  const r = data;
13
- return `signed in${r.persona === undefined ? "" : ` as persona ${r.persona}`} (${r.userEnv}/${r.passwordEnv}) — storage state saved to ${r.saved} (mode 0600)\n`;
13
+ return `signed in${r.persona === undefined ? "" : ` as persona ${r.persona}`}${r.method === "api" ? " through the API" : ""} (${r.userEnv}/${r.passwordEnv}) — storage state saved to ${r.saved} (mode 0600)\n`;
14
14
  }
15
15
  /** The persona's declared login parameters and session, from `--personas` or the project's `.jevitate/personas.json`. */
16
16
  function declaredPersona(name, personasFile) {
@@ -25,6 +25,14 @@ export function registerLoginCommand(program, deps) {
25
25
  .option("--persona <name>", "the persona being signed in (names it in the result); with a declared persona (--personas or .jevitate/personas.json) its login parameters and storage state path are the defaults")
26
26
  .option("--personas <file>", "personas JSON to read --persona's login parameters from (default: the project's .jevitate/personas.json)")
27
27
  .option("--url <loginUrl>", "the sign-in page (must be an authorized origin: its own, or --allow)")
28
+ .option("--api <url>", "#449: sign in through this HTTP endpoint instead of a form: the credentials are POSTed as JSON (must be an authorized origin; redirects are never followed)")
29
+ .option("--api-user-key <key>", "with --api: the JSON body key the username is sent under (default username)")
30
+ .option("--api-password-key <key>", "with --api: the JSON body key the password is sent under (default password)")
31
+ .option("--token-path <path>", "with --api: a dotted path into the JSON response whose value is the session token (e.g. token, data.accessToken); without it the response's cookies are the session")
32
+ .option("--storage-key <key>", "with --token-path: the localStorage key the token is written under (default: the path's last segment)")
33
+ .option("--storage <where>", "with --token-path: local (the only choice — a Playwright storage state has no sessionStorage)")
34
+ .option("--verify-url <url>", "with --api: the app page the new session is proven on, and whose origin receives the token (default: the endpoint's origin root)")
35
+ .option("--auth-check <check>", "with --api: how --verify-url proves the session: off | auto | urlExcludes:<text> | selector:<css> (default auto)")
28
36
  .option("--user-env <VAR>", "environment variable holding the username (its NAME — the value is read from the environment)")
29
37
  .option("--password-env <VAR>", "environment variable holding the password (its NAME — the value is read from the environment)")
30
38
  .option("--user-field <field>", "the username field: its label, else a CSS selector (default: found by autocomplete/type/name)")
@@ -41,6 +49,7 @@ export function registerLoginCommand(program, deps) {
41
49
  let login;
42
50
  let save;
43
51
  let warnings;
52
+ let authCheck;
44
53
  try {
45
54
  if (o.persona !== undefined && !PERSONA_NAME.test(o.persona)) {
46
55
  throw new LoginArgsError(`--persona ${JSON.stringify(o.persona)} must be 1-64 of [A-Za-z0-9_.-], starting alphanumeric`);
@@ -51,22 +60,55 @@ export function registerLoginCommand(program, deps) {
51
60
  if (o.personas !== undefined && declared === undefined)
52
61
  throw new LoginArgsError(`persona ${o.persona} is not declared in ${o.personas}`);
53
62
  const base = declared?.login;
54
- const url = o.url ?? base?.url;
63
+ const apiFlags = [
64
+ ["--api-user-key", o.apiUserKey],
65
+ ["--api-password-key", o.apiPasswordKey],
66
+ ["--token-path", o.tokenPath],
67
+ ["--storage-key", o.storageKey],
68
+ ["--storage", o.storage],
69
+ ["--verify-url", o.verifyUrl],
70
+ ["--auth-check", o.authCheck],
71
+ ]
72
+ .filter(([, v]) => v !== undefined)
73
+ .map(([k]) => k);
74
+ if (o.api !== undefined && o.url !== undefined)
75
+ throw new LoginArgsError("--api and --url are two ways to sign in: pass one");
76
+ const viaApi = o.api !== undefined || (o.url === undefined && base?.api !== undefined);
77
+ if (!viaApi && apiFlags.length > 0)
78
+ throw new LoginArgsError(`${apiFlags.join(", ")} ${apiFlags.length === 1 ? "applies" : "apply"} to a sign-in through an HTTP endpoint: pass --api <url> too`);
79
+ authCheck = parseAuthCheck(o.authCheck);
80
+ const url = viaApi ? undefined : (o.url ?? base?.url);
81
+ const apiUrl = viaApi ? (o.api ?? base?.api?.url) : undefined;
55
82
  const userEnv = o.userEnv ?? base?.userEnv;
56
83
  const passwordEnv = o.passwordEnv ?? base?.passwordEnv;
57
84
  const target = o.save ?? declared?.storageState;
58
- const missing = [url === undefined ? "--url" : null, userEnv === undefined ? "--user-env" : null, passwordEnv === undefined ? "--password-env" : null, target === undefined ? "--save" : null].filter((m) => m !== null);
85
+ const missing = [url === undefined && apiUrl === undefined ? "--url (or --api)" : null, userEnv === undefined ? "--user-env" : null, passwordEnv === undefined ? "--password-env" : null, target === undefined ? "--save" : null].filter((m) => m !== null);
59
86
  if (missing.length > 0) {
60
87
  throw new LoginArgsError(`missing ${missing.join(", ")}${o.persona === undefined ? "" : ` (persona ${o.persona} declares no login parameters for ${missing.length === 1 ? "it" : "them"})`}`);
61
88
  }
89
+ const b = base?.api;
62
90
  login = loginFromFlags({
63
- url: url,
91
+ ...(url === undefined ? {} : { url }),
92
+ ...(apiUrl === undefined
93
+ ? {}
94
+ : {
95
+ api: {
96
+ url: apiUrl,
97
+ userKey: o.apiUserKey ?? b?.userKey,
98
+ passwordKey: o.apiPasswordKey ?? b?.passwordKey,
99
+ tokenPath: o.tokenPath ?? b?.tokenPath,
100
+ // A declared storage key belongs to the declared token path: a --token-path flag takes its own default.
101
+ storageKey: o.storageKey ?? (o.tokenPath === undefined ? b?.storageKey : undefined),
102
+ storage: o.storage,
103
+ verifyUrl: o.verifyUrl ?? b?.verifyUrl,
104
+ },
105
+ }),
64
106
  userEnv: userEnv,
65
107
  passwordEnv: passwordEnv,
66
- ...pick("userField", o.userField ?? base?.userField),
67
- ...pick("passwordField", o.passwordField ?? base?.passwordField),
68
- ...pick("submit", o.submit ?? base?.submit),
69
- ...pick("success", o.success ?? base?.success),
108
+ ...pick("userField", o.userField ?? (viaApi ? undefined : base?.userField)),
109
+ ...pick("passwordField", o.passwordField ?? (viaApi ? undefined : base?.passwordField)),
110
+ ...pick("submit", o.submit ?? (viaApi ? undefined : base?.submit)),
111
+ ...pick("success", o.success ?? (viaApi ? undefined : base?.success)),
70
112
  });
71
113
  ({ path: save, warnings } = checkSaveTarget(target, "--save"));
72
114
  }
@@ -77,7 +119,8 @@ export function registerLoginCommand(program, deps) {
77
119
  }
78
120
  throw err;
79
121
  }
80
- const allowlist = o.allow.length > 0 ? normalizeAllowlist(o.allow) : normalizeAllowlist([login.url]);
122
+ const loginUrl = login.api?.url ?? login.url;
123
+ const allowlist = o.allow.length > 0 ? normalizeAllowlist(o.allow) : normalizeAllowlist([loginUrl]);
81
124
  for (const w of warnings)
82
125
  program.configureOutput().writeErr?.(`warning: ${w}\n`);
83
126
  try {
@@ -88,11 +131,13 @@ export function registerLoginCommand(program, deps) {
88
131
  env: deps.explore?.env ?? process.env,
89
132
  port: (deps.explore?.browserPortFactory ?? (() => new PlaywrightBrowserPort()))(),
90
133
  timeoutMs: (o.timeout ?? DEFAULT_TIMEOUT_S) * 1000,
134
+ ...(login.api === undefined ? {} : { verify: { url: apiVerifyUrl(login.api), check: authCheck } }),
91
135
  });
92
136
  const result = {
93
137
  ...(o.persona === undefined ? {} : { persona: o.persona }),
94
138
  saved: minted.saved,
95
- loginUrl: redactUrl(login.url),
139
+ loginUrl: redactUrl(loginUrl),
140
+ method: login.api === undefined ? "form" : "api",
96
141
  landedUrl: minted.landedUrl,
97
142
  userEnv: login.userEnv,
98
143
  passwordEnv: login.passwordEnv,
@@ -1 +1 @@
1
- {"version":3,"file":"login-cli.js","sourceRoot":"","sources":["../src/login-cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"login-cli.js","sourceRoot":"","sources":["../src/login-cli.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAgB,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAAgB,MAAM,gBAAgB,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB,EAAE,cAAc,EAAqC,MAAM,oBAAoB,CAAC;AAoD1L,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC7B,MAAM,YAAY,GAAG,mCAAmC,CAAC;AAEzD,SAAS,gBAAgB,CAAC,IAAa;IACrC,MAAM,CAAC,GAAG,IAAmB,CAAC;IAC9B,OAAO,YAAY,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,WAAW,8BAA8B,CAAC,CAAC,KAAK,gBAAgB,CAAC;AAClN,CAAC;AAED,yHAAyH;AACzH,SAAS,eAAe,CAAC,IAAY,EAAE,YAAgC;IACrE,MAAM,GAAG,GAAG,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC5F,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAgB,EAAE,IAAa;IAClE,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CACV,6HAA6H;QAC3H,kIAAkI,CACrI;SACA,MAAM,CAAC,kBAAkB,EAAE,oLAAoL,CAAC;SAChN,MAAM,CAAC,mBAAmB,EAAE,0GAA0G,CAAC;SACvI,MAAM,CAAC,kBAAkB,EAAE,sEAAsE,CAAC;SAClG,MAAM,CAAC,aAAa,EAAE,6JAA6J,CAAC;SACpL,MAAM,CAAC,sBAAsB,EAAE,6EAA6E,CAAC;SAC7G,MAAM,CAAC,0BAA0B,EAAE,6EAA6E,CAAC;SACjH,MAAM,CAAC,qBAAqB,EAAE,qKAAqK,CAAC;SACpM,MAAM,CAAC,qBAAqB,EAAE,uGAAuG,CAAC;SACtI,MAAM,CAAC,mBAAmB,EAAE,+FAA+F,CAAC;SAC5H,MAAM,CAAC,oBAAoB,EAAE,kIAAkI,CAAC;SAChK,MAAM,CAAC,sBAAsB,EAAE,kHAAkH,CAAC;SAClJ,MAAM,CAAC,kBAAkB,EAAE,+FAA+F,CAAC;SAC3H,MAAM,CAAC,sBAAsB,EAAE,+FAA+F,CAAC;SAC/H,MAAM,CAAC,sBAAsB,EAAE,+FAA+F,CAAC;SAC/H,MAAM,CAAC,0BAA0B,EAAE,0FAA0F,CAAC;SAC9H,MAAM,CAAC,iBAAiB,EAAE,qFAAqF,CAAC;SAChH,MAAM,CAAC,mBAAmB,EAAE,8KAA8K,CAAC;SAC3M,MAAM,CAAC,eAAe,EAAE,0GAA0G,CAAC;SACnI,MAAM,CAAC,kBAAkB,EAAE,8GAA8G,EAAE,CAAC,CAAS,EAAE,IAAc,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,EAAc,CAAC;SACvM,MAAM,CAAC,qBAAqB,EAAE,uDAAuD,iBAAiB,GAAG,EAAE,cAAc,CAAC;SAC1H,MAAM,CAAC,QAAQ,EAAE,sBAAsB,CAAC;SACxC,MAAM,CAAC,KAAK;QACX,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAc,CAAC;QAClC,MAAM,IAAI,GAAG,CAAC,QAAiD,EAAQ,EAAE,CACvE,iBAAiB,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAC7G,IAAI,KAAmB,CAAC;QACxB,IAAI,IAAY,CAAC;QACjB,IAAI,QAAkB,CAAC;QACvB,IAAI,SAAoB,CAAC;QACzB,IAAI,CAAC;YACH,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC7D,MAAM,IAAI,cAAc,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,wDAAwD,CAAC,CAAC;YAC3H,CAAC;YACD,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC9F,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;gBAAE,MAAM,IAAI,cAAc,CAAC,mFAAmF,CAAC,CAAC;YACvK,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS;gBAAE,MAAM,IAAI,cAAc,CAAC,WAAW,CAAC,CAAC,OAAO,uBAAuB,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC1I,MAAM,IAAI,GAAG,QAAQ,EAAE,KAAK,CAAC;YAC7B,MAAM,QAAQ,GACZ;gBACE,CAAC,gBAAgB,EAAE,CAAC,CAAC,UAAU,CAAC;gBAChC,CAAC,oBAAoB,EAAE,CAAC,CAAC,cAAc,CAAC;gBACxC,CAAC,cAAc,EAAE,CAAC,CAAC,SAAS,CAAC;gBAC7B,CAAC,eAAe,EAAE,CAAC,CAAC,UAAU,CAAC;gBAC/B,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC;gBACxB,CAAC,cAAc,EAAE,CAAC,CAAC,SAAS,CAAC;gBAC7B,CAAC,cAAc,EAAE,CAAC,CAAC,SAAS,CAAC;aAEhC;iBACE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;iBAClC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;YACnB,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS;gBAAE,MAAM,IAAI,cAAc,CAAC,mDAAmD,CAAC,CAAC;YAC9H,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,IAAI,EAAE,GAAG,KAAK,SAAS,CAAC,CAAC;YACvF,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;gBAAE,MAAM,IAAI,cAAc,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,8DAA8D,CAAC,CAAC;YAClM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACxC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,GAAG,CAAC,CAAC;YACtD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC9D,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,IAAI,EAAE,OAAO,CAAC;YAC3C,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,IAAI,IAAI,EAAE,WAAW,CAAC;YACvD,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,QAAQ,EAAE,YAAY,CAAC;YAChD,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CACtO,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,IAAI,CAC/B,CAAC;YACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,IAAI,cAAc,CAAC,WAAW,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,OAAO,qCAAqC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;YAChM,CAAC;YACD,MAAM,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC;YACpB,KAAK,GAAG,cAAc,CAAC;gBACrB,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;gBACrC,GAAG,CAAC,MAAM,KAAK,SAAS;oBACtB,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC;wBACE,GAAG,EAAE;4BACH,GAAG,EAAE,MAAM;4BACX,OAAO,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC,EAAE,OAAO;4BACnC,WAAW,EAAE,CAAC,CAAC,cAAc,IAAI,CAAC,EAAE,WAAW;4BAC/C,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC,EAAE,SAAS;4BACtC,wGAAwG;4BACxG,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;4BACnF,OAAO,EAAE,CAAC,CAAC,OAAO;4BAClB,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC,EAAE,SAAS;yBACvC;qBACF,CAAC;gBACN,OAAO,EAAE,OAAQ;gBACjB,WAAW,EAAE,WAAY;gBACzB,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;gBAC3E,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,aAAa,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;gBACvF,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAClE,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;aACtE,CAAC,CAAC;YACH,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAC,MAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,cAAc,IAAI,GAAG,YAAY,iBAAiB,EAAE,CAAC;gBACtE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBACxC,OAAO;YACT,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,EAAE,GAAG,IAAI,KAAK,CAAC,GAAI,CAAC;QAC9C,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACpG,KAAK,MAAM,CAAC,IAAI,QAAQ;YAAE,OAAO,CAAC,eAAe,EAAE,CAAC,QAAQ,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAClF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC;gBACpC,KAAK;gBACL,IAAI;gBACJ,SAAS;gBACT,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG;gBACrC,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,qBAAqB,EAAE,CAAC,CAAC,EAAE;gBACjF,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,iBAAiB,CAAC,GAAG,IAAI;gBAClD,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC;aACnG,CAAC,CAAC;YACH,MAAM,MAAM,GAAgB;gBAC1B,GAAG,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC1D,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,QAAQ,EAAE,SAAS,CAAC,QAAQ,CAAC;gBAC7B,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;gBAChD,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,QAAQ;aACT,CAAC;YACF,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QACnB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,cAAc;gBAAE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;iBACtE,IAAI,GAAG,YAAY,gBAAgB;gBAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;;gBAC/E,MAAM,GAAG,CAAC;QACjB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,IAAI,CAAmB,CAAI,EAAE,CAAqB;IACzD,OAAO,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAA0B,CAAC;AACtE,CAAC"}
package/dist/mcp-api.d.ts CHANGED
@@ -2,7 +2,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
2
  import { type AiGenerateTextArgs, type AiGenerateTextResult } from "@jevitate/mcp-facade";
3
3
  import { type CredentialStore, type GenerationPort, type SetupRequiredResult } from "@jevitate/ai-core";
4
4
  import type { JudgmentPort, UsageTracker } from "@jevitate/ai-core";
5
- import type { SelfHealer } from "@jevitate/runtime";
5
+ import type { ChangeScope, SelfHealer } from "@jevitate/runtime";
6
6
  import type { EmulationSpec } from "@jevitate/playwright";
7
7
  import { type RunPolicy } from "@jevitate/domain";
8
8
  import { type RunVerifyFixOptions, type VerifyFixReport } from "./verify-fix-api.js";
@@ -46,6 +46,10 @@ export interface McpTool {
46
46
  export interface McpJourneyRunOptions {
47
47
  readonly policy?: RunPolicy;
48
48
  readonly selfHealer?: SelfHealer;
49
+ /** #453: the change context a hybrid/full self-heal is explained by (`changes`/`changeNote`). */
50
+ readonly heal?: {
51
+ readonly scope: ChangeScope;
52
+ };
49
53
  readonly environment?: ResolvedJourneyEnvironment;
50
54
  readonly browser?: BrowserRunOptions;
51
55
  readonly emulation?: EmulationSpec;