cairn-engine 2.0.0 → 2.2.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.
package/README.md CHANGED
@@ -2,72 +2,179 @@
2
2
 
3
3
  ![cairn banner](https://raw.githubusercontent.com/team-poem/cairn/main/banner.svg)
4
4
 
5
- The engine behind [cairn](https://github.com/team-poem/cairn) — an AI walks an unfamiliar
6
- app **once** to discover a browser test and **freezes it into a marker**; from then on it
7
- replays that path **deterministically, with no LLM in the loop**. When a step breaks or lands
8
- in the wrong state, the LLM returns to **heal** just that step, then re-freezes. **Discovery is
9
- paid once; every replay is free.** Model- and browser-agnostic — embed it, or drive it from the `cairn` CLI.
5
+ [![npm](https://img.shields.io/npm/v/cairn-engine.svg)](https://www.npmjs.com/package/cairn-engine)
6
+ [![CI](https://github.com/team-poem/cairn/actions/workflows/ci.yml/badge.svg)](https://github.com/team-poem/cairn/actions/workflows/ci.yml)
7
+ [![types](https://img.shields.io/npm/types/cairn-engine.svg)](https://www.npmjs.com/package/cairn-engine)
8
+ [![license](https://img.shields.io/npm/l/cairn-engine.svg)](https://github.com/team-poem/cairn/blob/main/LICENSE)
9
+
10
+ **Browser tests you write in plain language — that then run with zero AI in the loop.**
11
+
12
+ An AI walks your app **once** to discover the flow and **freezes** it. From then on it replays
13
+ **deterministically — no LLM, no hand-written selectors.** When the UI changes and a step breaks,
14
+ the AI returns to **heal just that step**, then re-freezes. A third thing, between two tools you
15
+ already reach for:
16
+
17
+ - **Scripted (Playwright/Cypress)** — deterministic, but you hand-write selectors that break every redesign.
18
+ - **LLM agents** — plain language, but a slow, costly, flaky model in _every_ run.
19
+ - **cairn** — plain-language authoring **and** deterministic, free, self-healing replay.
20
+
21
+ ## Use it
10
22
 
11
23
  ```sh
12
24
  npm install cairn-engine
13
25
  ```
14
26
 
15
- ```sh
16
- # discover an LLM walks the app once and writes a scenario
17
- cairn discover "follow the link to learn more" --url https://example.com --freeze t.json
18
- # replay deterministic, no LLM; non-zero exit on failure (CI gate)
19
- cairn replay t.json
20
- # heal repair a broken step via the LLM and re-freeze
21
- cairn replay t.json --heal --freeze t.json
27
+ **Author once** — an AI discovers the flow; you freeze it to a file:
28
+
29
+ ```ts
30
+ import { discover, ChromeDevToolsDriver, createLlmClient } from "cairn-engine";
31
+ import { writeFileSync } from "node:fs";
32
+
33
+ const scenario = await discover(
34
+ "log in, add the first product, open the cart",
35
+ {
36
+ driver: new ChromeDevToolsDriver(),
37
+ llm: createLlmClient(), // Claude Code if installed, else ANTHROPIC_API_KEY
38
+ baseUrl: "https://shop.example",
39
+ },
40
+ );
41
+ writeFileSync("cart.skill.json", JSON.stringify(scenario, null, 2));
22
42
  ```
23
43
 
24
- Embed itevery stage is an injected port:
44
+ **Replay forever**deterministic, no LLM. When the UI drifts, `heal` repairs the step and you
45
+ re-freeze the fixed path:
25
46
 
26
47
  ```ts
27
- import { runScenario } from "cairn-engine";
48
+ import { runScenario, loadSkillFile } from "cairn-engine";
49
+ import { writeFileSync } from "node:fs";
50
+
51
+ const { result, healedScenario } = await runScenario(
52
+ loadSkillFile("cart.skill.json"),
53
+ {
54
+ heal: true, // repair a broken step with the LLM instead of going red
55
+ },
56
+ );
57
+
58
+ if (healedScenario) {
59
+ // the UI changed and cairn adapted — write the repaired path back
60
+ writeFileSync("cart.skill.json", JSON.stringify(healedScenario, null, 2));
61
+ }
62
+ if (!result.verdict.passed) process.exit(1); // a deterministic gate for CI
63
+ ```
64
+
65
+ Prefer a one-off from the terminal? The same steps are CLI commands —
66
+ `cairn discover … --freeze cart.skill.json` · `cairn replay cart.skill.json` · `… --heal`.
67
+
68
+ **Models** — set a key and cairn picks the backend: **Anthropic** (`ANTHROPIC_API_KEY`, or a local
69
+ **Claude Code** install with no key), **OpenAI** (`OPENAI_API_KEY`), or **Gemini**
70
+ (`GEMINI_API_KEY`). Force one with `createLlmClient({ backend: "openai" })`, or implement the
71
+ `LlmClient` port for any other model.
72
+
73
+ ## How the loop works
74
+
75
+ ```
76
+ intent ─► discover (LLM, once) ─► cart.skill.json ─► replay (no LLM, forever)
77
+ │ a step breaks
78
+
79
+ self-heal (LLM, just that step)
80
+ ```
28
81
 
29
- const { result } = await runScenario(scenario, { heal: true });
30
- if (!result.verdict.passed) process.exit(1);
82
+ - **discover** _(LLM · once)_ observes the live page, picks one action, acts, and repeats until your intent is met. Out comes a `Scenario`.
83
+ - **freeze** — that scenario is plain JSON (`*.skill.json`): a flat list of steps + assertions, each target carrying several locators. No model, no LLM — just data.
84
+ - **replay** _(no LLM)_ — runs the steps through a `Driver`, auto-waiting for the page to settle; a `Critic` rules on three layers of evidence — _did it act_ · _what it looked like_ · _the requests & console_. Same input, same verdict.
85
+ - **heal** _(LLM · only on a break)_ — when a target stops resolving or the outcome diverges, the LLM maps your original step `intent` onto the new page, repairs that one step, retries, and returns a scenario to re-freeze. A green replay never calls it.
86
+
87
+ Discovery is paid once; regression is free. A frozen scenario is data you can read, diff, and edit
88
+ by hand:
89
+
90
+ ```json
91
+ {
92
+ "name": "cart",
93
+ "steps": [
94
+ { "kind": "goto", "url": "https://shop.example" },
95
+ {
96
+ "kind": "type",
97
+ "target": { "text": "Email" },
98
+ "text": "you@shop.example"
99
+ },
100
+ {
101
+ "kind": "click",
102
+ "target": { "text": "Log in" },
103
+ "intent": "submit the login form",
104
+ "expect": { "requestStatus": { "urlIncludes": "/auth", "status": 200 } }
105
+ },
106
+ { "kind": "click", "target": { "text": "Add to cart" } },
107
+ { "kind": "click", "target": { "text": "Cart", "role": "link" } },
108
+ { "kind": "waitFor", "until": { "url": "/cart" } }
109
+ ],
110
+ "assertions": [
111
+ { "kind": "navigated", "to": "/cart" },
112
+ { "kind": "no-failed-requests" }
113
+ ]
114
+ }
31
115
  ```
32
116
 
33
- Building a UI on top? The engine exposes the seams; you bring the UI:
117
+ Each `target` keeps several locators `text` (accessible name) first, `role` + `index` as a
118
+ rename-resilient fallback, `selector` as a CSS escape hatch — which is what lets replay survive a
119
+ redesign without falling back to the LLM. The `expect` on a step is its post-condition: replay
120
+ checks it deterministically and only heals if it diverges.
121
+
122
+ **Measured, not claimed** — a real multi-step checkout, via cairn's `bench/` harness:
123
+
124
+ - **4/4 deterministic** replays · **0 LLM calls** on replay
125
+ - discovery **~$0.50 once** → every replay after is **$0** (a full LLM agent runs **~$15–30 _per run_**)
126
+ - a renamed button broke hand-written selectors; cairn **healed it and stayed green**
127
+
128
+ ## Build on it
129
+
130
+ cairn is the machinery — discover · freeze · replay · heal — behind a handful of ports, **general
131
+ in mechanism, specific in meaning.** It's made to be **built on**, not scattered across your
132
+ service as test code. A few things it powers:
133
+
134
+ - **A QA tool** — non-developers write flows in plain language, then watch them replay & self-heal
135
+ - **A CI regression gate** — frozen flows run on every PR; drift heals instead of going red
136
+ - **A synthetic monitor** — replay critical paths against production, alert only when one truly breaks
137
+ - **A visual-replay app** — the engine streams per-step progress + screenshots; you draw the UI
138
+
139
+ You _can_ call `runScenario` straight from a test file — nothing stops you. But that isn't the
140
+ point: cairn is **not a Jest or Playwright you write service tests in** — it's the engine those
141
+ kinds of tools are built _from_. Reach for it to **build** testing tooling, not to author a test
142
+ suite by hand.
143
+
144
+ ## Extend it
145
+
146
+ The core knows no app — **you** supply what "success" means and how to drive the browser. Every
147
+ stage is a replaceable port — your own `Driver` (e.g. Playwright), `Critic`, `Reporter`,
148
+ `ContextProvider` (auth/fixtures), `LlmClient` (any model). Too much for a full port? `custom`
149
+ assertions/actions define success inline:
34
150
 
35
151
  ```ts
36
- const controller = new AbortController();
37
152
  await runScenario(scenario, {
38
- signal: controller.signal, // a Stop button
39
- screenshots: true, // capture a PNG per step
40
- onStep: (e) => render(e.index, e.step, e.ok, e.screenshot), // live timeline
153
+ custom: {
154
+ "cart-has": (p, ev) =>
155
+ ev.logic.requests.some((r) => r.url.includes(p.path) && r.status === 200),
156
+ },
41
157
  });
42
158
  ```
43
159
 
44
- Make it yours the engine ships defaults, your product defines the specifics:
160
+ Building a UI on top? The engine streams exactly what a screen needs — wire it up and draw:
45
161
 
46
162
  ```ts
163
+ const controller = new AbortController();
47
164
  await runScenario(scenario, {
48
- // success is whatever your product says it is
49
- custom: { "cart-has": (p, ev) => ev.logic.requests.some((r) => r.url.includes(p.path) && r.status === 200) },
50
- // product-specific interactions, beyond click/type/hover/select/scroll
51
- actions: { "drag-slider": async (driver, p) => { /* … */ } },
165
+ signal: controller.signal, // a Stop button
166
+ screenshots: true, // a PNG per step
167
+ onStep: (s) => render(s.index, s.step, s.ok, s.screenshot), // a live timeline
52
168
  });
53
169
  ```
54
170
 
55
- Every layer is replaceable: bring your own `Driver` (e.g. Playwright), `Critic`, `Reporter`,
56
- `ContextProvider` (auth / fixtures), or `LlmClient` (any model) and use `custom`
57
- assertions / `actions` for what doesn't fit the built-ins. Nothing forces your product
58
- through only what we decided.
59
-
60
- **Browser or extension (no Node)?** `runScenario` and the default Chrome DevTools MCP driver
61
- need Node. Import the browser-safe core from `cairn-engine/browser` and compose `runHarness`
62
- with your own `Driver` (e.g. one over `chrome.debugger`) plus a fetch-based `LlmClient`:
63
-
64
- ```ts
65
- import { runHarness, StaticPlanner, AssertionCritic, AnthropicLlmClient } from "cairn-engine/browser";
66
- ```
171
+ **Browser / extension (no Node)?** Import the browser-safe core from `cairn-engine/browser` and
172
+ compose `runHarness` with your own `Driver` (e.g. one over `chrome.debugger`) plus a fetch-based
173
+ `LlmClient`.
67
174
 
68
- No API key needed if you have **Claude Code** installed (cairn shells out to it); set
69
- `ANTHROPIC_API_KEY` to use the Anthropic API instead.
175
+ ## Conventions
70
176
 
71
- **Full docs, design, and the loop diagram:** https://github.com/team-poem/cairn
177
+ Name embedded files `*.agentic.ts` + frozen `*.skill.json` — distinct from `*.test.ts` /
178
+ `*.spec.ts`, stable glob `**/*.agentic.ts`.
72
179
 
73
- MIT
180
+ **Full docs · design · the loop:** https://github.com/team-poem/cairn · MIT
@@ -1,10 +1,4 @@
1
- /** Requests whose failure is noise, not a regression — excluded from `no-failed-requests`. Built-in
2
- * universal noise plus any URL-substring a product marks benign (e.g. its own analytics 4xx). */
3
- function isBenignRequest(url, benign = []) {
4
- if (/\/favicon\.ico(\?|$)/i.test(url) || /\/robots\.txt(\?|$)/i.test(url))
5
- return true;
6
- return benign.some((s) => url.includes(s));
7
- }
1
+ import { isBenignRequest } from "../../core/requests.js";
8
2
  /** Evaluate one mechanical assertion. `expect` is not mechanical — returns unsupported (LlmCritic handles it). */
9
3
  export function checkAssertion(assertion, evidence, benign = []) {
10
4
  switch (assertion.kind) {
@@ -1 +1 @@
1
- {"version":3,"file":"assertion.js","sourceRoot":"","sources":["../../../src/adapters/critics/assertion.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"assertion.js","sourceRoot":"","sources":["../../../src/adapters/critics/assertion.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- const delay = (ms) => new Promise((r) => setTimeout(r, ms));
1
+ import { postJsonWithRetry } from "./http.js";
2
2
  export class AnthropicLlmClient {
3
3
  id;
4
4
  apiKey;
@@ -18,58 +18,39 @@ export class AnthropicLlmClient {
18
18
  this.id = `anthropic:${this.model}`;
19
19
  }
20
20
  async complete(prompt, opts = {}) {
21
- const body = JSON.stringify({
22
- model: this.model,
23
- max_tokens: opts.maxTokens ?? 1024,
24
- // #15 — cache the (constant) system prompt so repeated discover steps don't re-bill it.
25
- ...(opts.system
26
- ? { system: [{ type: "text", text: opts.system, cache_control: { type: "ephemeral" } }] }
27
- : {}),
28
- messages: [{ role: "user", content: prompt }],
21
+ const data = await postJsonWithRetry(`${this.baseUrl}/v1/messages`, {
22
+ headers: {
23
+ "content-type": "application/json",
24
+ "x-api-key": this.apiKey,
25
+ "anthropic-version": "2023-06-01",
26
+ },
27
+ body: JSON.stringify({
28
+ model: this.model,
29
+ max_tokens: opts.maxTokens ?? 1024,
30
+ // #15 — cache the (constant) system prompt so repeated discover steps don't re-bill it.
31
+ ...(opts.system
32
+ ? {
33
+ system: [
34
+ {
35
+ type: "text",
36
+ text: opts.system,
37
+ cache_control: { type: "ephemeral" },
38
+ },
39
+ ],
40
+ }
41
+ : {}),
42
+ messages: [{ role: "user", content: prompt }],
43
+ }),
44
+ }, {
45
+ timeoutMs: this.timeoutMs,
46
+ maxRetries: this.maxRetries,
47
+ label: "Anthropic",
29
48
  });
30
- for (let attempt = 0;; attempt++) {
31
- const controller = new AbortController();
32
- const timer = setTimeout(() => controller.abort(), this.timeoutMs);
33
- try {
34
- const res = await fetch(`${this.baseUrl}/v1/messages`, {
35
- method: "POST",
36
- headers: {
37
- "content-type": "application/json",
38
- "x-api-key": this.apiKey,
39
- "anthropic-version": "2023-06-01",
40
- },
41
- body,
42
- signal: controller.signal,
43
- });
44
- if (res.ok) {
45
- const data = (await res.json());
46
- return (data.content ?? [])
47
- .filter((c) => c.type === "text" && typeof c.text === "string")
48
- .map((c) => c.text)
49
- .join("")
50
- .trim();
51
- }
52
- // Back off on transient errors (rate limit / overloaded / server), else fail.
53
- if ((res.status === 429 || res.status >= 500) && attempt < this.maxRetries) {
54
- await delay(500 * 2 ** attempt);
55
- continue;
56
- }
57
- throw new Error(`Anthropic API ${res.status}: ${await res.text()}`);
58
- }
59
- catch (err) {
60
- const aborted = err instanceof Error && err.name === "AbortError";
61
- if (aborted && attempt >= this.maxRetries)
62
- throw new Error(`Anthropic request timed out after ${this.timeoutMs}ms`);
63
- if (aborted) {
64
- await delay(500 * 2 ** attempt);
65
- continue;
66
- }
67
- throw err;
68
- }
69
- finally {
70
- clearTimeout(timer);
71
- }
72
- }
49
+ return (data.content ?? [])
50
+ .filter((c) => c.type === "text" && typeof c.text === "string")
51
+ .map((c) => c.text)
52
+ .join("")
53
+ .trim();
73
54
  }
74
55
  }
75
56
  //# sourceMappingURL=anthropic.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/adapters/llm/anthropic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/adapters/llm/anthropic.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAgB9C,MAAM,OAAO,kBAAkB;IACpB,EAAE,CAAS;IACH,MAAM,CAAS;IACf,KAAK,CAAS;IACd,OAAO,CAAS;IAChB,SAAS,CAAS;IAClB,UAAU,CAAS;IAEpC,YAAY,OAAyB,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC5D,IAAI,CAAC,MAAM;YACT,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,mBAAmB,CAAC;QAC/C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,2BAA2B,CAAC;QAC3D,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC;QAC1C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,EAAE,GAAG,aAAa,IAAI,CAAC,KAAK,EAAE,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,OAAwB,EAAE;QACvD,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAClC,GAAG,IAAI,CAAC,OAAO,cAAc,EAC7B;YACE,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,WAAW,EAAE,IAAI,CAAC,MAAM;gBACxB,mBAAmB,EAAE,YAAY;aAClC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI;gBAClC,wFAAwF;gBACxF,GAAG,CAAC,IAAI,CAAC,MAAM;oBACb,CAAC,CAAC;wBACE,MAAM,EAAE;4BACN;gCACE,IAAI,EAAE,MAAM;gCACZ,IAAI,EAAE,IAAI,CAAC,MAAM;gCACjB,aAAa,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;6BACrC;yBACF;qBACF;oBACH,CAAC,CAAC,EAAE,CAAC;gBACP,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC9C,CAAC;SACH,EACD;YACE,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,WAAW;SACnB,CACF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;aACxB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;aAC9D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aAClB,IAAI,CAAC,EAAE,CAAC;aACR,IAAI,EAAE,CAAC;IACZ,CAAC;CACF"}
@@ -1,8 +1,12 @@
1
- /** Picks the LLM backend (invariant #5): the API if ANTHROPIC_API_KEY is set, else local Claude Code. */
1
+ /**
2
+ * Picks the LLM backend (invariant #5). An explicit `backend` wins; otherwise the first provider
3
+ * whose API key is present, in order Anthropic → OpenAI → Gemini, falling back to local Claude Code.
4
+ */
2
5
  import type { LlmClient } from "../../core/ports.js";
6
+ export type LlmBackend = "anthropic" | "openai" | "gemini" | "claude-code";
3
7
  export interface LlmFactoryOptions {
4
8
  /** Force a backend regardless of environment. */
5
- backend?: "anthropic" | "claude-code";
9
+ backend?: LlmBackend;
6
10
  model?: string;
7
11
  }
8
12
  export declare function createLlmClient(opts?: LlmFactoryOptions): LlmClient;
@@ -1,9 +1,27 @@
1
1
  import { AnthropicLlmClient } from "./anthropic.js";
2
2
  import { ClaudeCodeLlmClient } from "./claude-code.js";
3
+ import { GeminiLlmClient } from "./gemini.js";
4
+ import { OpenAILlmClient } from "./openai.js";
5
+ function detectBackend() {
6
+ if (process.env.ANTHROPIC_API_KEY)
7
+ return "anthropic";
8
+ if (process.env.OPENAI_API_KEY)
9
+ return "openai";
10
+ if (process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY)
11
+ return "gemini";
12
+ return "claude-code";
13
+ }
3
14
  export function createLlmClient(opts = {}) {
4
- const backend = opts.backend ?? (process.env.ANTHROPIC_API_KEY ? "anthropic" : "claude-code");
5
- return backend === "anthropic"
6
- ? new AnthropicLlmClient({ model: opts.model })
7
- : new ClaudeCodeLlmClient({ model: opts.model });
15
+ const backend = opts.backend ?? detectBackend();
16
+ switch (backend) {
17
+ case "openai":
18
+ return new OpenAILlmClient({ model: opts.model });
19
+ case "gemini":
20
+ return new GeminiLlmClient({ model: opts.model });
21
+ case "claude-code":
22
+ return new ClaudeCodeLlmClient({ model: opts.model });
23
+ default:
24
+ return new AnthropicLlmClient({ model: opts.model });
25
+ }
8
26
  }
9
27
  //# sourceMappingURL=factory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/adapters/llm/factory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAQvD,MAAM,UAAU,eAAe,CAAC,OAA0B,EAAE;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAC9F,OAAO,OAAO,KAAK,WAAW;QAC5B,CAAC,CAAC,IAAI,kBAAkB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QAC/C,CAAC,CAAC,IAAI,mBAAmB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/adapters/llm/factory.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAU9C,SAAS,aAAa;IACpB,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAAE,OAAO,WAAW,CAAC;IACtD,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO,QAAQ,CAAC;IAChD,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO,QAAQ,CAAC;IAC9E,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAA0B,EAAE;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,aAAa,EAAE,CAAC;IAChD,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,QAAQ;YACX,OAAO,IAAI,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACpD,KAAK,QAAQ;YACX,OAAO,IAAI,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACpD,KAAK,aAAa;YAChB,OAAO,IAAI,mBAAmB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACxD;YACE,OAAO,IAAI,kBAAkB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IACzD,CAAC;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * LlmClient backed by the Google Gemini API (GEMINI_API_KEY / GOOGLE_API_KEY). Uses fetch — no SDK.
3
+ */
4
+ import type { CompleteOptions, LlmClient } from "../../core/ports.js";
5
+ export interface GeminiOptions {
6
+ apiKey?: string;
7
+ model?: string;
8
+ baseUrl?: string;
9
+ timeoutMs?: number;
10
+ maxRetries?: number;
11
+ }
12
+ export declare class GeminiLlmClient implements LlmClient {
13
+ readonly id: string;
14
+ private readonly apiKey;
15
+ private readonly model;
16
+ private readonly baseUrl;
17
+ private readonly timeoutMs?;
18
+ private readonly maxRetries?;
19
+ constructor(opts?: GeminiOptions);
20
+ complete(prompt: string, opts?: CompleteOptions): Promise<string>;
21
+ }
@@ -0,0 +1,44 @@
1
+ import { postJsonWithRetry } from "./http.js";
2
+ export class GeminiLlmClient {
3
+ id;
4
+ apiKey;
5
+ model;
6
+ baseUrl;
7
+ timeoutMs;
8
+ maxRetries;
9
+ constructor(opts = {}) {
10
+ const apiKey = opts.apiKey ?? process.env.GEMINI_API_KEY ?? process.env.GOOGLE_API_KEY;
11
+ if (!apiKey)
12
+ throw new Error("GeminiLlmClient requires GEMINI_API_KEY");
13
+ this.apiKey = apiKey;
14
+ this.model = opts.model ?? "gemini-2.0-flash";
15
+ this.baseUrl = opts.baseUrl ?? "https://generativelanguage.googleapis.com";
16
+ this.timeoutMs = opts.timeoutMs;
17
+ this.maxRetries = opts.maxRetries;
18
+ this.id = `gemini:${this.model}`;
19
+ }
20
+ async complete(prompt, opts = {}) {
21
+ const data = await postJsonWithRetry(`${this.baseUrl}/v1beta/models/${this.model}:generateContent`, {
22
+ headers: {
23
+ "content-type": "application/json",
24
+ "x-goog-api-key": this.apiKey,
25
+ },
26
+ body: JSON.stringify({
27
+ ...(opts.system
28
+ ? { systemInstruction: { parts: [{ text: opts.system }] } }
29
+ : {}),
30
+ contents: [{ role: "user", parts: [{ text: prompt }] }],
31
+ generationConfig: { maxOutputTokens: opts.maxTokens ?? 1024 },
32
+ }),
33
+ }, {
34
+ timeoutMs: this.timeoutMs,
35
+ maxRetries: this.maxRetries,
36
+ label: "Gemini",
37
+ });
38
+ return (data.candidates?.[0]?.content?.parts ?? [])
39
+ .map((p) => p.text ?? "")
40
+ .join("")
41
+ .trim();
42
+ }
43
+ }
44
+ //# sourceMappingURL=gemini.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../../src/adapters/llm/gemini.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAc9C,MAAM,OAAO,eAAe;IACjB,EAAE,CAAS;IACH,MAAM,CAAS;IACf,KAAK,CAAS;IACd,OAAO,CAAS;IAChB,SAAS,CAAU;IACnB,UAAU,CAAU;IAErC,YAAY,OAAsB,EAAE;QAClC,MAAM,MAAM,GACV,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC1E,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACxE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,kBAAkB,CAAC;QAC9C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,2CAA2C,CAAC;QAC3E,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,CAAC,EAAE,GAAG,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,OAAwB,EAAE;QACvD,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAClC,GAAG,IAAI,CAAC,OAAO,kBAAkB,IAAI,CAAC,KAAK,kBAAkB,EAC7D;YACE,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,gBAAgB,EAAE,IAAI,CAAC,MAAM;aAC9B;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,GAAG,CAAC,IAAI,CAAC,MAAM;oBACb,CAAC,CAAC,EAAE,iBAAiB,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;oBAC3D,CAAC,CAAC,EAAE,CAAC;gBACP,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;gBACvD,gBAAgB,EAAE,EAAE,eAAe,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,EAAE;aAC9D,CAAC;SACH,EACD;YACE,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,QAAQ;SAChB,CACF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC;aAChD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;aACxB,IAAI,CAAC,EAAE,CAAC;aACR,IAAI,EAAE,CAAC;IACZ,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ export interface HttpRetryOptions {
2
+ /** Per-request timeout (ms). Default 60s — a stalled connection rejects instead of hanging. */
3
+ timeoutMs?: number;
4
+ /** Retries on transient errors (429 / 5xx / timeout). Default 2. */
5
+ maxRetries?: number;
6
+ /** Provider name for error messages, e.g. "Anthropic". */
7
+ label?: string;
8
+ }
9
+ export declare function postJsonWithRetry<T>(url: string, init: {
10
+ headers: Record<string, string>;
11
+ body: string;
12
+ }, opts?: HttpRetryOptions): Promise<T>;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Shared POST-JSON transport for the HTTP-based LlmClient adapters (Anthropic, OpenAI, Gemini):
3
+ * a per-request timeout plus exponential back-off on transient failures (429 / 5xx / timeout).
4
+ * Each adapter builds its own request body and parses its own response shape.
5
+ */
6
+ const delay = (ms) => new Promise((r) => setTimeout(r, ms));
7
+ export async function postJsonWithRetry(url, init, opts = {}) {
8
+ const timeoutMs = opts.timeoutMs ?? 60_000;
9
+ const maxRetries = opts.maxRetries ?? 2;
10
+ const label = opts.label ?? "LLM";
11
+ for (let attempt = 0;; attempt++) {
12
+ const controller = new AbortController();
13
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
14
+ try {
15
+ const res = await fetch(url, {
16
+ method: "POST",
17
+ headers: init.headers,
18
+ body: init.body,
19
+ signal: controller.signal,
20
+ });
21
+ if (res.ok)
22
+ return (await res.json());
23
+ // Back off on transient errors (rate limit / overloaded / server), else fail.
24
+ if ((res.status === 429 || res.status >= 500) && attempt < maxRetries) {
25
+ await delay(500 * 2 ** attempt);
26
+ continue;
27
+ }
28
+ throw new Error(`${label} API ${res.status}: ${await res.text()}`);
29
+ }
30
+ catch (err) {
31
+ const aborted = err instanceof Error && err.name === "AbortError";
32
+ if (aborted && attempt >= maxRetries)
33
+ throw new Error(`${label} request timed out after ${timeoutMs}ms`);
34
+ if (aborted) {
35
+ await delay(500 * 2 ** attempt);
36
+ continue;
37
+ }
38
+ throw err;
39
+ }
40
+ finally {
41
+ clearTimeout(timer);
42
+ }
43
+ }
44
+ }
45
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/adapters/llm/http.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,KAAK,GAAG,CAAC,EAAU,EAAiB,EAAE,CAC1C,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAWxC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAW,EACX,IAAuD,EACvD,OAAyB,EAAE;IAE3B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC;IAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC;IAElC,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;QAC9D,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAC3B,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YACH,IAAI,GAAG,CAAC,EAAE;gBAAE,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAM,CAAC;YAC3C,8EAA8E;YAC9E,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;gBACtE,MAAM,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC;gBAChC,SAAS;YACX,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,GAAG,CAAC,MAAM,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACrE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC;YAClE,IAAI,OAAO,IAAI,OAAO,IAAI,UAAU;gBAClC,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,4BAA4B,SAAS,IAAI,CAAC,CAAC;YACrE,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC;gBAChC,SAAS;YACX,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * LlmClient backed by the OpenAI Chat Completions API (OPENAI_API_KEY). Uses fetch — no SDK.
3
+ */
4
+ import type { CompleteOptions, LlmClient } from "../../core/ports.js";
5
+ export interface OpenAIOptions {
6
+ apiKey?: string;
7
+ model?: string;
8
+ baseUrl?: string;
9
+ timeoutMs?: number;
10
+ maxRetries?: number;
11
+ }
12
+ export declare class OpenAILlmClient implements LlmClient {
13
+ readonly id: string;
14
+ private readonly apiKey;
15
+ private readonly model;
16
+ private readonly baseUrl;
17
+ private readonly timeoutMs?;
18
+ private readonly maxRetries?;
19
+ constructor(opts?: OpenAIOptions);
20
+ complete(prompt: string, opts?: CompleteOptions): Promise<string>;
21
+ }
@@ -0,0 +1,43 @@
1
+ import { postJsonWithRetry } from "./http.js";
2
+ export class OpenAILlmClient {
3
+ id;
4
+ apiKey;
5
+ model;
6
+ baseUrl;
7
+ timeoutMs;
8
+ maxRetries;
9
+ constructor(opts = {}) {
10
+ const apiKey = opts.apiKey ?? process.env.OPENAI_API_KEY;
11
+ if (!apiKey)
12
+ throw new Error("OpenAILlmClient requires OPENAI_API_KEY");
13
+ this.apiKey = apiKey;
14
+ this.model = opts.model ?? "gpt-4o";
15
+ this.baseUrl = opts.baseUrl ?? "https://api.openai.com";
16
+ this.timeoutMs = opts.timeoutMs;
17
+ this.maxRetries = opts.maxRetries;
18
+ this.id = `openai:${this.model}`;
19
+ }
20
+ async complete(prompt, opts = {}) {
21
+ const messages = [];
22
+ if (opts.system)
23
+ messages.push({ role: "system", content: opts.system });
24
+ messages.push({ role: "user", content: prompt });
25
+ const data = await postJsonWithRetry(`${this.baseUrl}/v1/chat/completions`, {
26
+ headers: {
27
+ "content-type": "application/json",
28
+ authorization: `Bearer ${this.apiKey}`,
29
+ },
30
+ body: JSON.stringify({
31
+ model: this.model,
32
+ max_tokens: opts.maxTokens ?? 1024,
33
+ messages,
34
+ }),
35
+ }, {
36
+ timeoutMs: this.timeoutMs,
37
+ maxRetries: this.maxRetries,
38
+ label: "OpenAI",
39
+ });
40
+ return (data.choices?.[0]?.message?.content ?? "").trim();
41
+ }
42
+ }
43
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/adapters/llm/openai.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAc9C,MAAM,OAAO,eAAe;IACjB,EAAE,CAAS;IACH,MAAM,CAAS;IACf,KAAK,CAAS;IACd,OAAO,CAAS;IAChB,SAAS,CAAU;IACnB,UAAU,CAAU;IAErC,YAAY,OAAsB,EAAE;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QACzD,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACxE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC;QACpC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,wBAAwB,CAAC;QACxD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,CAAC,EAAE,GAAG,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,OAAwB,EAAE;QACvD,MAAM,QAAQ,GAA6C,EAAE,CAAC;QAC9D,IAAI,IAAI,CAAC,MAAM;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACzE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAEjD,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAClC,GAAG,IAAI,CAAC,OAAO,sBAAsB,EACrC;YACE,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;aACvC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI;gBAClC,QAAQ;aACT,CAAC;SACH,EACD;YACE,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,QAAQ;SAChB,CACF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5D,CAAC;CACF"}
package/dist/browser.d.ts CHANGED
@@ -22,6 +22,8 @@ export { FakeDriver } from "./adapters/drivers/fake.js";
22
22
  export { SelfHealingDriver, parseHealChoice } from "./adapters/drivers/self-heal.js";
23
23
  export type { Heal, SelfHealOptions } from "./adapters/drivers/self-heal.js";
24
24
  export { AnthropicLlmClient } from "./adapters/llm/anthropic.js";
25
+ export { OpenAILlmClient } from "./adapters/llm/openai.js";
26
+ export { GeminiLlmClient } from "./adapters/llm/gemini.js";
25
27
  export { discover, parseDecision } from "./core/discover.js";
26
28
  export type { DiscoverOptions, Decision } from "./core/discover.js";
27
29
  export { LlmStepHealer } from "./core/step-heal.js";
package/dist/browser.js CHANGED
@@ -19,6 +19,8 @@ export { ConsoleReporter } from "./adapters/reporters/console.js";
19
19
  export { FakeDriver } from "./adapters/drivers/fake.js";
20
20
  export { SelfHealingDriver, parseHealChoice } from "./adapters/drivers/self-heal.js";
21
21
  export { AnthropicLlmClient } from "./adapters/llm/anthropic.js";
22
+ export { OpenAILlmClient } from "./adapters/llm/openai.js";
23
+ export { GeminiLlmClient } from "./adapters/llm/gemini.js";
22
24
  export { discover, parseDecision } from "./core/discover.js";
23
25
  export { LlmStepHealer } from "./core/step-heal.js";
24
26
  export { scoreTarget, scoreScenario, weakTargets } from "./core/freeze.js";
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,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;AAE7F,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,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAGrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,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;AAE7F,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,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAGrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { waitForCondition } from "./steps.js";
2
+ import { isBenignRequest, isMutation } from "./requests.js";
2
3
  const SYSTEM = "You are a QA agent driving a web browser to satisfy a natural-language intent. " +
3
4
  "At each turn you see the page's interactive elements and the actions taken so far. " +
4
5
  "Respond with ONE next action as strict JSON, no prose, no code fences. " +
@@ -121,7 +122,13 @@ function extractFirstJsonObject(text) {
121
122
  * `semantic` is set — otherwise the freeze stays deterministic (invariant #4).
122
123
  */
123
124
  function deriveAssertions(proposed, evidence, semantic) {
124
- const out = [{ kind: "no-failed-requests" }];
125
+ const out = [];
126
+ // Ground no-failed-requests: freeze it only if it actually HELD during discovery (no non-benign
127
+ // failure). A flow that survives a noisy 4xx would otherwise fail every replay on a check that was
128
+ // already false — the success-proving request below carries the real signal instead.
129
+ if (!evidence.logic.requests.some((r) => r.status >= 400 && !isBenignRequest(r.url))) {
130
+ out.push({ kind: "no-failed-requests" });
131
+ }
125
132
  const { navigated, finalUrl } = evidence.execution;
126
133
  // assert reaching the RIGHT destination (host+path), not just "navigated" — catches a flow
127
134
  // that lands on an error/wrong page yet technically navigated.
@@ -157,10 +164,13 @@ function dedupeAssertions(assertions) {
157
164
  }
158
165
  const ASSERT_SYSTEM = "You propose verification assertions for a QA scenario, grounded ONLY in the observed evidence — " +
159
166
  "never invent a request or page that is not shown. Given the intent and what the run observed, " +
160
- "return a JSON array of assertions confirming the intent was achieved. Prefer concrete deterministic " +
161
- 'checks: {"kind":"request-status","urlIncludes":"<url-substring>","status":200} for the key API call(s) ' +
162
- 'that prove success, and {"kind":"navigated","to":"<host+path>"} for the destination. ' +
163
- "Return [] if the defaults already suffice. JSON array only, no prose, no code fences.";
167
+ "return a JSON array of assertions confirming the intent was achieved. " +
168
+ "Prove the ACTION, not just the destination: prefer a " +
169
+ '{"kind":"request-status","urlIncludes":"<url-substring>","status":200} on the state-changing request ' +
170
+ "that performed the goal (a POST/PUT/PATCH such as an order/submit/create call) NOT a page navigation " +
171
+ "or GET, which a mere URL jump could satisfy without doing the work. " +
172
+ 'Add {"kind":"navigated","to":"<host+path>"} for the destination too. ' +
173
+ "Return [] only if no meaningful action was observed. JSON array only, no prose, no code fences.";
164
174
  const ASSERT_SYSTEM_SEMANTIC = ' You may also add {"kind":"expect","criterion":"<natural-language success criterion>"} ' +
165
175
  "for a check no mechanical assertion captures (judged later by an LLM critic).";
166
176
  /** Compact evidence rendering for the assertion-proposal prompt. */
@@ -170,10 +180,16 @@ function renderEvidence(evidence) {
170
180
  .slice(0, 40)
171
181
  .map((r) => `${r.status} ${r.method} ${r.url}`)
172
182
  .join("\n");
183
+ // Surface successful mutations separately — these are what prove an action happened (a checkout
184
+ // POST, etc.), so the model grounds the success check on the work, not a page load.
185
+ const mutations = logic.requests
186
+ .filter((r) => isMutation(r.method) && r.status < 400)
187
+ .map((r) => `${r.status} ${r.method} ${r.url}`);
173
188
  const errors = logic.console.filter((m) => m.type === "error").map((m) => m.text);
174
189
  return [
175
190
  `finalUrl: ${execution.finalUrl ?? "(none)"} (navigated: ${execution.navigated})`,
176
- `requests (${logic.requests.length}):`,
191
+ `state-changing requests that prove an action (prefer one of these): ${mutations.length ? "\n" + mutations.join("\n") : "(none)"}`,
192
+ `all requests (${logic.requests.length}):`,
177
193
  requests || "(none)",
178
194
  `console errors (${errors.length}): ${errors.slice(0, 5).join(" | ") || "(none)"}`,
179
195
  ].join("\n");
@@ -1 +1 @@
1
- {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/core/discover.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/core/discover.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAwC5D,MAAM,MAAM,GACV,iFAAiF;IACjF,qFAAqF;IACrF,yEAAyE;IACzE,WAAW;IACX,wFAAwF;IACxF,0EAA0E;IAC1E,sHAAsH;IACtH,uHAAuH;IACvH,oCAAoC;IACpC,uIAAuI;IACvI,sIAAsI;IACtI,qBAAqB;IACrB,iIAAiI;IACjI,gHAAgH;IAChH,mJAAmJ,CAAC;AAEtJ,MAAM,aAAa,GAAG,EAAE,CAAC;AACzB,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,kBAAkB;IAC5F,eAAe,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY;CAChF,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,QAAuB,EAAE,MAAc,EAAE,KAAa;IACjF,+FAA+F;IAC/F,kGAAkG;IAClG,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IACjG,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACZ,IAAI,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAClC,KAAK,MAAM,CAAC,IAAI,KAAK;YAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,KAAK,IAAI,EAAE,CAAC;QACzD,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IACzB,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,8CAA8C;SAC7F,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAuB;IACpD,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,WAAW,CAClB,MAAc,EACd,MAAc,EACd,UAAkB,EAClB,KAAa,EACb,QAAkB;IAElB,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM;QAC1B,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAClE,CAAC,CAAC,YAAY,CAAC;IACjB,yEAAyE;IACzE,MAAM,aAAa,GAAG,MAAM,IAAI,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,MAAM,IAAI,QAAQ,CAAC;IAC9G,OAAO;QACL,WAAW,MAAM,EAAE;QACnB,EAAE;QACF,GAAG,CAAC,QAAQ,CAAC,MAAM;YACjB,CAAC,CAAC,CAAC,4FAA4F,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACtI,CAAC,CAAC,EAAE,CAAC;QACP,uBAAuB;QACvB,OAAO;QACP,EAAE;QACF,uCAAuC;QACvC,aAAa;QACb,EAAE;QACF,yDAAyD;KAC1D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,GAAG,GAAG,sBAAsB,CAAC,IAAI,CAAyB,CAAC;IACjE,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAClF,IAAI,CAAC,GAAG,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IACrF,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAAC,IAAY;IAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC/E,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACnC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAChB,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,GAAG;gBAAE,GAAG,GAAG,KAAK,CAAC;iBAChB,IAAI,EAAE,KAAK,IAAI;gBAAE,GAAG,GAAG,IAAI,CAAC;iBAC5B,IAAI,EAAE,KAAK,GAAG;gBAAE,KAAK,GAAG,KAAK,CAAC;QACrC,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG;YAAE,KAAK,GAAG,IAAI,CAAC;aAC/B,IAAI,EAAE,KAAK,GAAG;YAAE,KAAK,EAAE,CAAC;aACxB,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC3C,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,gBAAgB,CACvB,QAAiC,EACjC,QAAkB,EAClB,QAAiB;IAEjB,MAAM,GAAG,GAAgB,EAAE,CAAC;IAC5B,gGAAgG;IAChG,mGAAmG;IACnG,qFAAqF;IACrF,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACrF,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC,SAAS,CAAC;IACnD,2FAA2F;IAC3F,+DAA+D;IAC/D,IAAI,SAAS,IAAI,QAAQ;QAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;SACpF,IAAI,SAAS;QAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IACpD,KAAK,MAAM,CAAC,IAAI,QAAQ,IAAI,EAAE,EAAE,CAAC;QAC/B,IAAI,CAAC,CAAC,IAAI,OAAQ,CAAwB,CAAC,IAAI,KAAK,QAAQ;YAAE,SAAS;QACvE,IAAI,CAAC,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;YAChC,6EAA6E;YAC7E,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAC1C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAC9D,CAAC;YACF,IAAI,OAAO;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAClG,CAAC;aAAM,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;YACpG,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IACD,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC;AAC/B,CAAC;AAED,uFAAuF;AACvF,SAAS,gBAAgB,CAAC,UAAuB;IAC/C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,aAAa,GACjB,kGAAkG;IAClG,gGAAgG;IAChG,wEAAwE;IACxE,uDAAuD;IACvD,uGAAuG;IACvG,yGAAyG;IACzG,sEAAsE;IACtE,uEAAuE;IACvE,iGAAiG,CAAC;AAEpG,MAAM,sBAAsB,GAC1B,yFAAyF;IACzF,+EAA+E,CAAC;AAElF,oEAAoE;AACpE,SAAS,cAAc,CAAC,QAAkB;IACxC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC;IACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ;SAC5B,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;SACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;SAC9C,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,gGAAgG;IAChG,oFAAoF;IACpF,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ;SAC7B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;SACrD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAClF,OAAO;QACL,aAAa,SAAS,CAAC,QAAQ,IAAI,QAAQ,gBAAgB,SAAS,CAAC,SAAS,GAAG;QACjF,uEAAuE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;QAClI,iBAAiB,KAAK,CAAC,QAAQ,CAAC,MAAM,IAAI;QAC1C,QAAQ,IAAI,QAAQ;QACpB,mBAAmB,MAAM,CAAC,MAAM,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,QAAQ,EAAE;KACnF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,iBAAiB,CAC9B,GAAc,EACd,MAAc,EACd,QAAkB,EAClB,QAAiB;IAEjB,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,aAAa,GAAG,sBAAsB,CAAC,CAAC,CAAC,aAAa,CAAC;IACjF,MAAM,MAAM,GAAG;QACb,WAAW,MAAM,EAAE;QACnB,EAAE;QACF,oBAAoB;QACpB,cAAc,CAAC,QAAQ,CAAC;QACxB,EAAE;QACF,uDAAuD;KACxD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,4FAA4F;AAC5F,SAAS,gBAAgB,CAAC,IAAY;IACpC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC/E,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAC5B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAChB,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,GAAG;gBAAE,GAAG,GAAG,KAAK,CAAC;iBAChB,IAAI,EAAE,KAAK,IAAI;gBAAE,GAAG,GAAG,IAAI,CAAC;iBAC5B,IAAI,EAAE,KAAK,GAAG;gBAAE,KAAK,GAAG,KAAK,CAAC;QACrC,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG;YAAE,KAAK,GAAG,IAAI,CAAC;aAC/B,IAAI,EAAE,KAAK,GAAG;YAAE,KAAK,EAAE,CAAC;aACxB,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC9C,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,8FAA8F;AAC9F,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED;;iDAEiD;AACjD,KAAK,UAAU,UAAU,CAAC,MAAc,EAAE,SAA6B;IACrE,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;IACtB,MAAM,QAAQ,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC;IAC7D,IAAI,QAAQ,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,EAAE,GAAG,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;IACjF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAc,EAAE,QAAkB;IACpE,yFAAyF;IACzF,+EAA+E;IAC/E,MAAM,OAAO,GAAG,GAAoB,EAAE;QACpC,IAAI,CAAC,QAAQ,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,CAAC,MAAM,0BAA0B,CAAC,CAAC;QAClF,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC;IACF,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;QACxB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;YAC/B,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC3B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QACnC,CAAC;QACD,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;YAC/B,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACjC,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC;QACzC,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;YAC/B,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC3B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QACnC,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;YAC/B,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YAChD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;QAC9D,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;YAC/B,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YAClD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;QACjE,CAAC;QACD,KAAK,UAAU;YACb,IAAI,CAAC,QAAQ,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACtE,MAAM,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YACpC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC;QACjD,KAAK,QAAQ;YACX,MAAM,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACxC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC3D,KAAK,MAAM;YACT,IAAI,CAAC,QAAQ,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAClE,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAChC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC;QAC7C,KAAK,SAAS;YACZ,IAAI,CAAC,QAAQ,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;YACzE,MAAM,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,6CAA6C;YAC7F,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;QACpD;YACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAc,EAAE,IAAqB;IAClE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC;IAC5F,MAAM,KAAK,GAAW,EAAE,CAAC;IAEzB,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,oFAAoF;IACpF,4FAA4F;IAC5F,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,cAAc,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;QAC7E,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE;YACzF,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QACH,UAAU,GAAG,MAAM,CAAC;QAEpB,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,yEAAyE;YACzE,QAAQ,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;YAC/E,SAAS;QACX,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC/B,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC;YACnB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG;gBACf,GAAG,CAAC,QAAQ,CAAC,UAAU,IAAI,EAAE,CAAC;gBAC9B,GAAG,CAAC,MAAM,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;aACpE,CAAC;YACF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,cAAc,CAAC,EAAE,CAAC;QACnG,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC;YAC9D,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YACnD,2FAA2F;YAC3F,IAAI,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE;gBAAE,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAClE,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YACnD,IAAI,MAAM;gBAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjB,MAAM,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,GAAG,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACnH,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC/E,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,iGAAiG;IACjG,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACxC,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;IAChF,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,KAAK;QACL,UAAU,EAAE,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,cAAc,CAAC;QAChE,SAAS,EAAE,IAAI;KAChB,CAAC;AACJ,CAAC"}
@@ -7,7 +7,12 @@ import type { Assertion, AssertionResult, Context, Evidence, PageElement, Result
7
7
  export interface ContextProvider {
8
8
  provide(task: string): Promise<Context>;
9
9
  }
10
- /** Intent → ordered Scenario. Frozen-replay planning uses no LLM (invariant #4); discovery is a separate LLM planner. */
10
+ /**
11
+ * Intent → ordered Scenario for the plan-then-execute pipeline (frozen replay uses no LLM, invariant #4).
12
+ * Discovery is NOT a Planner: `discover()` is a separate free function that interleaves observe→act→adapt
13
+ * against the live browser (invariant #3), so it can't be a pure `plan(ctx)`. The CLI's `discover` calls
14
+ * it directly, outside the Harness/Planner pipeline.
15
+ */
11
16
  export interface Planner {
12
17
  plan(ctx: Context): Promise<Scenario>;
13
18
  }
@@ -0,0 +1,6 @@
1
+ /** Requests whose failure is noise, not a regression — excluded from `no-failed-requests`. Built-in
2
+ * universal noise (favicon, robots) plus any URL-substring a product marks benign. */
3
+ export declare function isBenignRequest(url: string, benign?: readonly string[]): boolean;
4
+ /** Whether a request is a state-changing mutation (the kind that proves an action happened, vs a
5
+ * navigation/read) — used to ground a scenario's success assertion on what did the work. */
6
+ export declare function isMutation(method: string): boolean;
@@ -0,0 +1,14 @@
1
+ /** Requests whose failure is noise, not a regression — excluded from `no-failed-requests`. Built-in
2
+ * universal noise (favicon, robots) plus any URL-substring a product marks benign. */
3
+ export function isBenignRequest(url, benign = []) {
4
+ if (/\/favicon\.ico(\?|$)/i.test(url) || /\/robots\.txt(\?|$)/i.test(url))
5
+ return true;
6
+ return benign.some((s) => url.includes(s));
7
+ }
8
+ /** Whether a request is a state-changing mutation (the kind that proves an action happened, vs a
9
+ * navigation/read) — used to ground a scenario's success assertion on what did the work. */
10
+ export function isMutation(method) {
11
+ const m = method.toUpperCase();
12
+ return m === "POST" || m === "PUT" || m === "PATCH" || m === "DELETE";
13
+ }
14
+ //# sourceMappingURL=requests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests.js","sourceRoot":"","sources":["../../src/core/requests.ts"],"names":[],"mappings":"AAAA;sFACsF;AACtF,MAAM,UAAU,eAAe,CAAC,GAAW,EAAE,SAA4B,EAAE;IACzE,IAAI,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACvF,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;4FAC4F;AAC5F,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAC/B,OAAO,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,QAAQ,CAAC;AACxE,CAAC"}
package/dist/index.d.ts CHANGED
@@ -20,7 +20,10 @@ export { SelfHealingDriver, parseHealChoice } from "./adapters/drivers/self-heal
20
20
  export type { Heal, SelfHealOptions } from "./adapters/drivers/self-heal.js";
21
21
  export { ClaudeCodeLlmClient } from "./adapters/llm/claude-code.js";
22
22
  export { AnthropicLlmClient } from "./adapters/llm/anthropic.js";
23
+ export { OpenAILlmClient } from "./adapters/llm/openai.js";
24
+ export { GeminiLlmClient } from "./adapters/llm/gemini.js";
23
25
  export { createLlmClient } from "./adapters/llm/factory.js";
26
+ export type { LlmBackend, LlmFactoryOptions } from "./adapters/llm/factory.js";
24
27
  export { FileSkillStore, loadSkillFile } from "./adapters/skills/file-store.js";
25
28
  export { discover, parseDecision } from "./core/discover.js";
26
29
  export type { DiscoverOptions, Decision } from "./core/discover.js";
package/dist/index.js CHANGED
@@ -16,6 +16,8 @@ export { ChromeDevToolsDriver } from "./adapters/drivers/chrome.js";
16
16
  export { SelfHealingDriver, parseHealChoice } from "./adapters/drivers/self-heal.js";
17
17
  export { ClaudeCodeLlmClient } from "./adapters/llm/claude-code.js";
18
18
  export { AnthropicLlmClient } from "./adapters/llm/anthropic.js";
19
+ export { OpenAILlmClient } from "./adapters/llm/openai.js";
20
+ export { GeminiLlmClient } from "./adapters/llm/gemini.js";
19
21
  export { createLlmClient } from "./adapters/llm/factory.js";
20
22
  export { FileSkillStore, loadSkillFile } from "./adapters/skills/file-store.js";
21
23
  export { discover, parseDecision } from "./core/discover.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,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"}
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,0BAA0B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAG5D,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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cairn-engine",
3
- "version": "2.0.0",
3
+ "version": "2.2.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",
@@ -13,7 +13,11 @@
13
13
  "ai",
14
14
  "chrome-devtools",
15
15
  "mcp",
16
- "automation"
16
+ "automation",
17
+ "agentic",
18
+ "test-automation",
19
+ "regression-testing",
20
+ "playwright"
17
21
  ],
18
22
  "license": "MIT",
19
23
  "author": "team-poem (https://github.com/team-poem)",