cairn-engine 1.2.0 → 2.0.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 (44) hide show
  1. package/README.md +5 -3
  2. package/dist/adapters/critics/assertion.d.ts +8 -3
  3. package/dist/adapters/critics/assertion.js +19 -9
  4. package/dist/adapters/critics/assertion.js.map +1 -1
  5. package/dist/adapters/critics/llm.d.ts +1 -1
  6. package/dist/adapters/critics/llm.js +2 -2
  7. package/dist/adapters/critics/llm.js.map +1 -1
  8. package/dist/adapters/drivers/chrome.d.ts +5 -4
  9. package/dist/adapters/drivers/chrome.js +8 -4
  10. package/dist/adapters/drivers/chrome.js.map +1 -1
  11. package/dist/adapters/drivers/self-heal.d.ts +3 -2
  12. package/dist/adapters/drivers/self-heal.js +10 -7
  13. package/dist/adapters/drivers/self-heal.js.map +1 -1
  14. package/dist/adapters/llm/anthropic.js +4 -1
  15. package/dist/adapters/llm/anthropic.js.map +1 -1
  16. package/dist/adapters/skills/file-store.d.ts +7 -4
  17. package/dist/adapters/skills/file-store.js +27 -10
  18. package/dist/adapters/skills/file-store.js.map +1 -1
  19. package/dist/browser.d.ts +1 -0
  20. package/dist/browser.js +1 -0
  21. package/dist/browser.js.map +1 -1
  22. package/dist/cli.js +22 -12
  23. package/dist/cli.js.map +1 -1
  24. package/dist/core/discover.d.ts +18 -2
  25. package/dist/core/discover.js +191 -18
  26. package/dist/core/discover.js.map +1 -1
  27. package/dist/core/pipeline.d.ts +3 -1
  28. package/dist/core/pipeline.js +30 -2
  29. package/dist/core/pipeline.js.map +1 -1
  30. package/dist/core/ports.d.ts +10 -4
  31. package/dist/core/step-heal.d.ts +14 -0
  32. package/dist/core/step-heal.js +55 -0
  33. package/dist/core/step-heal.js.map +1 -0
  34. package/dist/core/steps.d.ts +11 -1
  35. package/dist/core/steps.js +4 -2
  36. package/dist/core/steps.js.map +1 -1
  37. package/dist/core/types.d.ts +14 -3
  38. package/dist/index.d.ts +2 -1
  39. package/dist/index.js +2 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist/run.d.ts +18 -5
  42. package/dist/run.js +62 -8
  43. package/dist/run.js.map +1 -1
  44. package/package.json +1 -1
@@ -0,0 +1,55 @@
1
+ import { applyDecision, parseDecision, renderElements } from "./discover.js";
2
+ const MAX_STEP_HEALS = 5;
3
+ const STEP_HEAL_SYSTEM = "You repair ONE step of a browser QA scenario that ran but didn't reach its expected outcome. " +
4
+ "Given the step's goal and the current page elements, reply with the SINGLE next action that " +
5
+ 'achieves the goal, as one JSON action object (same format as discovery: {"action":"click","text":"..."}). ' +
6
+ 'If nothing on the page can achieve it, reply {"action":"done"}. JSON only, no prose.';
7
+ export class LlmStepHealer {
8
+ llm;
9
+ maxHeals;
10
+ heals = [];
11
+ constructor(llm, maxHeals = MAX_STEP_HEALS) {
12
+ this.llm = llm;
13
+ this.maxHeals = maxHeals;
14
+ }
15
+ async heal(step, index, driver) {
16
+ if (this.heals.length >= this.maxHeals)
17
+ return null;
18
+ const elements = await driver.snapshot();
19
+ let decision;
20
+ try {
21
+ const reply = await this.llm.complete(stepHealPrompt(step, elements), { system: STEP_HEAL_SYSTEM });
22
+ decision = parseDecision(reply);
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ if (decision.action === "done")
28
+ return null;
29
+ let healed;
30
+ try {
31
+ healed = await applyDecision(driver, decision);
32
+ }
33
+ catch {
34
+ return null;
35
+ }
36
+ // Keep the original intent + expect on the re-frozen step so it stays verifiable next replay.
37
+ healed.intent = step.intent;
38
+ healed.expect = step.expect;
39
+ const heal = { index, step: healed };
40
+ this.heals.push(heal);
41
+ return heal;
42
+ }
43
+ }
44
+ function stepHealPrompt(step, elements) {
45
+ return [
46
+ `Step goal: ${step.intent ?? step.kind}`,
47
+ `Expected outcome: ${step.expect ? JSON.stringify(step.expect) : "(reach the next state)"}`,
48
+ ``,
49
+ `Current page:`,
50
+ renderElements(elements),
51
+ ``,
52
+ `Reply with the single next action that achieves the goal.`,
53
+ ].join("\n");
54
+ }
55
+ //# sourceMappingURL=step-heal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-heal.js","sourceRoot":"","sources":["../../src/core/step-heal.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAiB,MAAM,eAAe,CAAC;AAE5F,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB,MAAM,gBAAgB,GACpB,+FAA+F;IAC/F,8FAA8F;IAC9F,4GAA4G;IAC5G,sFAAsF,CAAC;AAEzF,MAAM,OAAO,aAAa;IAGL;IACA;IAHV,KAAK,GAAe,EAAE,CAAC;IAChC,YACmB,GAAc,EACd,WAAW,cAAc;QADzB,QAAG,GAAH,GAAG,CAAW;QACd,aAAQ,GAAR,QAAQ,CAAiB;IACzC,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAC,IAAU,EAAE,KAAa,EAAE,MAAc;QAClD,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QACpD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QACzC,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;YACpG,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QAC5C,IAAI,MAAY,CAAC;QACjB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;QACD,8FAA8F;QAC9F,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC5B,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC5B,MAAM,IAAI,GAAa,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAC/C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,SAAS,cAAc,CAAC,IAAU,EAAE,QAAuB;IACzD,OAAO;QACL,cAAc,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE;QACxC,qBAAqB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,wBAAwB,EAAE;QAC3F,EAAE;QACF,eAAe;QACf,cAAc,CAAC,QAAQ,CAAC;QACxB,EAAE;QACF,2DAA2D;KAC5D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
@@ -5,7 +5,7 @@
5
5
  * registering a handler, never editing a stage. Depends only on core ports/types.
6
6
  */
7
7
  import type { CustomAction, Driver, StepHandler } from "./ports.js";
8
- import type { Step } from "./types.js";
8
+ import type { Step, WaitUntil } from "./types.js";
9
9
  /** Handles cairn's built-in step vocabulary — every kind except product-defined `custom`. */
10
10
  export declare class BuiltinStepHandler implements StepHandler {
11
11
  supports(step: Step): boolean;
@@ -20,3 +20,13 @@ export declare class CustomStepHandler implements StepHandler {
20
20
  }
21
21
  /** The engine's default Execute-stage chain: built-ins first, then product `custom` actions. */
22
22
  export declare function defaultStepHandlers(actions?: Record<string, CustomAction>): StepHandler[];
23
+ /**
24
+ * Poll the Driver's own observation until every field of `until` holds, or throw on timeout.
25
+ * Uses only `observe()`/`snapshot()`, so any Driver works and replay stays deterministic (no LLM,
26
+ * invariant #4). This is the explicit-wait primitive the heuristic `settle()` can't express —
27
+ * e.g. "wait until /me returns 200" before the next step, instead of racing the app's readiness.
28
+ */
29
+ export declare function waitForCondition(driver: Driver, until: WaitUntil, timeoutMs?: number): Promise<void>;
30
+ /** Whether every field of `until` holds now (Driver observation only, no LLM). Polled by `waitFor`
31
+ * and checked once per step for `expect` verification (spec/core/surgical-heal.md). */
32
+ export declare function conditionMet(driver: Driver, until: WaitUntil): Promise<boolean>;
@@ -65,7 +65,7 @@ export function defaultStepHandlers(actions = {}) {
65
65
  * invariant #4). This is the explicit-wait primitive the heuristic `settle()` can't express —
66
66
  * e.g. "wait until /me returns 200" before the next step, instead of racing the app's readiness.
67
67
  */
68
- async function waitForCondition(driver, until, timeoutMs = WAIT_TIMEOUT_MS) {
68
+ export async function waitForCondition(driver, until, timeoutMs = WAIT_TIMEOUT_MS) {
69
69
  const deadline = Date.now() + timeoutMs;
70
70
  for (;;) {
71
71
  if (await conditionMet(driver, until))
@@ -76,7 +76,9 @@ async function waitForCondition(driver, until, timeoutMs = WAIT_TIMEOUT_MS) {
76
76
  await sleep(WAIT_POLL_MS);
77
77
  }
78
78
  }
79
- async function conditionMet(driver, until) {
79
+ /** Whether every field of `until` holds now (Driver observation only, no LLM). Polled by `waitFor`
80
+ * and checked once per step for `expect` verification (spec/core/surgical-heal.md). */
81
+ export async function conditionMet(driver, until) {
80
82
  if (until.url !== undefined || until.requestStatus !== undefined) {
81
83
  const { execution, logic } = await driver.observe();
82
84
  if (until.url !== undefined && !(execution.finalUrl ?? "").includes(until.url))
@@ -1 +1 @@
1
- {"version":3,"file":"steps.js","sourceRoot":"","sources":["../../src/core/steps.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"steps.js","sourceRoot":"","sources":["../../src/core/steps.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,13 @@
2
2
  export interface Context {
3
3
  intent: string;
4
4
  }
5
- export type Step = {
5
+ /** Per-step surgical-heal metadata: `intent` is what a heal re-decides from; `expect` is a
6
+ * post-condition replay verifies deterministically (same shape as `waitFor`). See spec/core/surgical-heal.md. */
7
+ export interface StepMeta {
8
+ intent?: string;
9
+ expect?: WaitUntil;
10
+ }
11
+ export type Step = StepMeta & ({
6
12
  kind: "goto";
7
13
  url: string;
8
14
  } | {
@@ -41,7 +47,7 @@ export type Step = {
41
47
  kind: "custom";
42
48
  name: string;
43
49
  params?: Record<string, unknown>;
44
- };
50
+ });
45
51
  /**
46
52
  * A condition a `waitFor` step blocks on. All provided fields must hold (AND). Checked against the
47
53
  * Driver's `observe()`/`snapshot()` — so any Driver supports it without a new port method.
@@ -99,6 +105,9 @@ export interface Scenario {
99
105
  name: string;
100
106
  steps: Step[];
101
107
  assertions: Assertion[];
108
+ /** Set by discover when it stopped at the step cap without reaching "done" — the path may be
109
+ * incomplete, so a host can warn before trusting the freeze. Absent on a normal finish. */
110
+ truncated?: boolean;
102
111
  }
103
112
  /** An interactive element the discover loop perceives and acts on. */
104
113
  export interface PageElement {
@@ -125,7 +134,9 @@ export interface NetworkRequest {
125
134
  status: number;
126
135
  resourceType?: string;
127
136
  }
128
- /** Three observable layers the Critic judges on never "the screen looked right". */
137
+ /** Three observable layers. Execution + logic drive the deterministic verdict (never "the screen
138
+ * looked right"); perception (screenshots) feeds the host's visual replay and is available to custom
139
+ * checks — built-in critics don't judge it yet (LLM-vision assertions are future). */
129
140
  export interface Evidence {
130
141
  execution: {
131
142
  actions: ExecutedAction[];
package/dist/index.d.ts CHANGED
@@ -4,8 +4,9 @@ export * from "./core/ports.js";
4
4
  export { runHarness } from "./core/pipeline.js";
5
5
  export type { RunHarnessOptions } from "./core/pipeline.js";
6
6
  export { BuiltinStepHandler, CustomStepHandler, defaultStepHandlers } from "./core/steps.js";
7
- export { runScenario, needsLlmCritic, applyHeals } from "./run.js";
7
+ export { runScenario, needsLlmCritic, applyHeals, applyStepHeals } from "./run.js";
8
8
  export type { RunScenarioOptions, RunScenarioResult } from "./run.js";
9
+ export { LlmStepHealer } from "./core/step-heal.js";
9
10
  export { InlineContextProvider } from "./adapters/context/inline.js";
10
11
  export { StaticPlanner } from "./adapters/planners/static.js";
11
12
  export { AssertionCritic, checkAssertion, resolveAssertion, judgeAssertion, MechanicalAssertionHandler, CustomAssertionHandler, } from "./adapters/critics/assertion.js";
package/dist/index.js CHANGED
@@ -3,7 +3,8 @@ export * from "./core/types.js";
3
3
  export * from "./core/ports.js";
4
4
  export { runHarness } from "./core/pipeline.js";
5
5
  export { BuiltinStepHandler, CustomStepHandler, defaultStepHandlers } from "./core/steps.js";
6
- export { runScenario, needsLlmCritic, applyHeals } from "./run.js";
6
+ export { runScenario, needsLlmCritic, applyHeals, applyStepHeals } from "./run.js";
7
+ export { LlmStepHealer } from "./core/step-heal.js";
7
8
  export { InlineContextProvider } from "./adapters/context/inline.js";
8
9
  export { StaticPlanner } from "./adapters/planners/static.js";
9
10
  export { AssertionCritic, checkAssertion, resolveAssertion, judgeAssertion, MechanicalAssertionHandler, CustomAssertionHandler, } from "./adapters/critics/assertion.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EACL,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACjG,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAGrF,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEhF,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EACL,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACjG,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAGrF,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEhF,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/run.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { CustomAction } from "./core/ports.js";
2
2
  import type { CustomChecks } from "./adapters/critics/assertion.js";
3
- import type { ContextProvider, Critic, Driver, LlmClient, Reporter } from "./core/ports.js";
3
+ import type { ContextProvider, Critic, Driver, LlmClient, Reporter, StepHeal } from "./core/ports.js";
4
4
  import type { Heal } from "./adapters/drivers/self-heal.js";
5
5
  import type { Result, Scenario, StepProgress } from "./core/types.js";
6
6
  export interface RunScenarioOptions {
@@ -10,7 +10,12 @@ export interface RunScenarioOptions {
10
10
  context?: ContextProvider;
11
11
  reporter?: Reporter;
12
12
  llm?: LlmClient;
13
- /** Wrap the driver so broken steps are repaired by the LLM and retried. */
13
+ /**
14
+ * Repair broken replays with the LLM (invariant #4 sanctioned use). Two layers, both only when set:
15
+ * a `SelfHealingDriver` fixes a step whose target no longer resolves, and — if the run still fails
16
+ * its assertions (a "passed-the-steps-but-wrong-outcome" break that locator-heal can't catch) —
17
+ * the scenario is re-discovered from the start. A green replay triggers neither (stays LLM-free).
18
+ */
14
19
  heal?: boolean;
15
20
  /** Fired on each self-heal — a host's signal that the frozen scenario is aging. */
16
21
  onHeal?: (heal: Heal) => void;
@@ -23,17 +28,25 @@ export interface RunScenarioOptions {
23
28
  screenshots?: boolean;
24
29
  /** Product-defined checks for `{ kind: "custom", name }` assertions — the host defines success. */
25
30
  custom?: CustomChecks;
31
+ /** URL substrings whose 4xx/5xx is product noise (e.g. analytics), excluded from `no-failed-requests`. */
32
+ benign?: string[];
26
33
  /** Product-defined handlers for `{ kind: "custom", name }` steps — the host defines interactions. */
27
34
  actions?: Record<string, CustomAction>;
28
35
  }
29
36
  export interface RunScenarioResult {
30
37
  result: Result;
31
- /** Substitutions self-heal made (empty unless `heal` was set and a step broke). */
38
+ /** Locator substitutions self-heal made (empty unless `heal` was set and a target broke). */
32
39
  heals: Heal[];
33
- /** Scenario rewritten with healed targets, ready to re-freeze. Undefined if no heals. */
40
+ /** Surgical step repairs (empty unless `heal` was set and a step's `expect` diverged). */
41
+ stepHeals: StepHeal[];
42
+ /** Scenario rewritten with healed targets/steps, ready to re-freeze. Undefined if no heals. */
34
43
  healedScenario?: Scenario;
35
44
  }
36
45
  export declare function needsLlmCritic(scenario: Scenario): boolean;
37
- /** Rewrite a scenario's targets with the names self-heal substituted, for re-freezing. */
46
+ /** Rewrite a scenario's targets with the (re-located) targets self-heal substituted, for re-freezing.
47
+ * Keyed by the original target's object identity — which flows unchanged from the step through the
48
+ * driver into the Heal — so two steps sharing a label don't rewrite together (#39). */
38
49
  export declare function applyHeals(scenario: Scenario, heals: Heal[]): Scenario;
50
+ /** Replace surgically-healed steps in place (keyed by index, so same-label steps don't collide). */
51
+ export declare function applyStepHeals(scenario: Scenario, heals: StepHeal[]): Scenario;
39
52
  export declare function runScenario(scenario: Scenario, opts?: RunScenarioOptions): Promise<RunScenarioResult>;
package/dist/run.js CHANGED
@@ -4,6 +4,7 @@
4
4
  * `heal` needs one, so a plain mechanical replay stays deterministic (invariant #4).
5
5
  */
6
6
  import { runHarness } from "./core/pipeline.js";
7
+ import { discover } from "./core/discover.js";
7
8
  import { InlineContextProvider } from "./adapters/context/inline.js";
8
9
  import { StaticPlanner } from "./adapters/planners/static.js";
9
10
  import { AssertionCritic } from "./adapters/critics/assertion.js";
@@ -12,45 +13,98 @@ import { ChromeDevToolsDriver } from "./adapters/drivers/chrome.js";
12
13
  import { SelfHealingDriver } from "./adapters/drivers/self-heal.js";
13
14
  import { ConsoleReporter } from "./adapters/reporters/console.js";
14
15
  import { createLlmClient } from "./adapters/llm/factory.js";
16
+ import { LlmStepHealer } from "./core/step-heal.js";
15
17
  export function needsLlmCritic(scenario) {
16
18
  return scenario.assertions.some((a) => a.kind === "expect");
17
19
  }
18
- /** Rewrite a scenario's targets with the names self-heal substituted, for re-freezing. */
20
+ /** The scenario's entry URL (its first `goto`), so an outcome-heal re-discovers from the same start. */
21
+ function firstGotoUrl(scenario) {
22
+ const first = scenario.steps[0];
23
+ return first && first.kind === "goto" ? first.url : undefined;
24
+ }
25
+ /** Rewrite a scenario's targets with the (re-located) targets self-heal substituted, for re-freezing.
26
+ * Keyed by the original target's object identity — which flows unchanged from the step through the
27
+ * driver into the Heal — so two steps sharing a label don't rewrite together (#39). */
19
28
  export function applyHeals(scenario, heals) {
20
29
  if (!heals.length)
21
30
  return scenario;
22
- const byOriginal = new Map(heals.map((h) => [h.original.text, h.healedText]));
31
+ const byOriginal = new Map(heals.map((h) => [h.original, h.healed]));
23
32
  return {
24
33
  ...scenario,
25
34
  steps: scenario.steps.map((step) => {
26
- if ("target" in step && step.target.text) {
27
- const healed = byOriginal.get(step.target.text);
35
+ if ("target" in step) {
36
+ const healed = byOriginal.get(step.target);
28
37
  if (healed)
29
- return { ...step, target: { ...step.target, text: healed } };
38
+ return { ...step, target: healed };
30
39
  }
31
40
  return step;
32
41
  }),
33
42
  };
34
43
  }
44
+ /** Replace surgically-healed steps in place (keyed by index, so same-label steps don't collide). */
45
+ export function applyStepHeals(scenario, heals) {
46
+ if (!heals.length)
47
+ return scenario;
48
+ const byIndex = new Map(heals.map((h) => [h.index, h.step]));
49
+ return { ...scenario, steps: scenario.steps.map((step, i) => byIndex.get(i) ?? step) };
50
+ }
35
51
  export async function runScenario(scenario, opts = {}) {
36
52
  // Build the LLM lazily and once — only if the critic or heal needs it.
37
53
  let llmCache = opts.llm;
38
54
  const getLlm = () => (llmCache ??= createLlmClient(opts.model ? { model: opts.model } : {}));
39
55
  const critic = opts.critic ??
40
- (needsLlmCritic(scenario) ? new LlmCritic(getLlm(), opts.custom) : new AssertionCritic(opts.custom));
56
+ (needsLlmCritic(scenario)
57
+ ? new LlmCritic(getLlm(), opts.custom, opts.benign)
58
+ : new AssertionCritic(opts.custom, opts.benign));
41
59
  const baseDriver = opts.driver ?? new ChromeDevToolsDriver();
42
60
  let healer;
43
61
  const driver = opts.heal
44
62
  ? (healer = new SelfHealingDriver(baseDriver, getLlm(), { onHeal: opts.onHeal }))
45
63
  : baseDriver;
64
+ const stepHealer = opts.heal ? new LlmStepHealer(getLlm()) : undefined;
46
65
  const result = await runHarness({
47
66
  context: opts.context ?? new InlineContextProvider(),
48
67
  planner: new StaticPlanner(scenario),
49
68
  driver,
50
69
  critic,
51
70
  reporter: opts.reporter ?? new ConsoleReporter(),
52
- }, scenario.name, { signal: opts.signal, onStep: opts.onStep, captureScreenshots: opts.screenshots, actions: opts.actions });
71
+ }, scenario.name, {
72
+ signal: opts.signal,
73
+ onStep: opts.onStep,
74
+ captureScreenshots: opts.screenshots,
75
+ actions: opts.actions,
76
+ stepHealer,
77
+ });
53
78
  const heals = healer?.heals ?? [];
54
- return { result, heals, healedScenario: heals.length ? applyHeals(scenario, heals) : undefined };
79
+ const stepHeals = stepHealer?.heals ?? [];
80
+ // Outcome-aware heal: the steps ran (locators/steps may even have healed) but the run still failed
81
+ // its assertions — the frozen path no longer reaches the goal, a break surgical-heal couldn't fix.
82
+ // Re-discover from the start (invariant #4 sanctioned use (b)); only on failure.
83
+ if (opts.heal && !result.verdict.passed) {
84
+ const repaired = await discover(scenario.name, {
85
+ driver: baseDriver,
86
+ llm: getLlm(),
87
+ baseUrl: firstGotoUrl(scenario),
88
+ signal: opts.signal,
89
+ });
90
+ const ctx = await (opts.context ?? new InlineContextProvider()).provide(scenario.name);
91
+ const evidence = await baseDriver.observe();
92
+ // Judge against the ORIGINAL goal assertions, not the ones the re-discovery derived for itself —
93
+ // else a path that reaches a different end-state passes as green (P2 false green).
94
+ const verdict = await critic.judge(evidence, scenario.assertions, ctx);
95
+ return {
96
+ result: { scenario: repaired.name, context: ctx, evidence, verdict },
97
+ heals,
98
+ stepHeals,
99
+ healedScenario: { ...repaired, assertions: scenario.assertions },
100
+ };
101
+ }
102
+ const rewritten = applyStepHeals(applyHeals(scenario, heals), stepHeals);
103
+ return {
104
+ result,
105
+ heals,
106
+ stepHeals,
107
+ healedScenario: heals.length || stepHeals.length ? rewritten : undefined,
108
+ };
55
109
  }
56
110
  //# sourceMappingURL=run.js.map
package/dist/run.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cairn-engine",
3
- "version": "1.2.0",
3
+ "version": "2.0.0",
4
4
  "description": "An engine for self-healing E2E browser tests — discovered once by an AI, replayed deterministically.",
5
5
  "keywords": [
6
6
  "e2e",