/** * The explore loop — the discover loop's freeze-less sibling (#102). Same observe→decide→act * machinery (invariant #3: the loop exists exactly for exploring an unfamiliar app), but instead * of freezing a Scenario it wanders the app under a charter and collects FINDINGS — UX problems * derived mechanically from each action's observation delta, plus problems the model itself * records with `note`. Emits an ExploreReport; nothing here touches the replay path, so * invariant #4 (deterministic replay) is untouched. * * Module layout mirrors discover: prompt (LLM surface) · findings (pure delta analysis) · * this file owns only the loop. Decision parsing/execution and the ActionPolicy seam are * SHARED with discover — one execution path, one safety gate (invariant #2). */ import type { Driver, LlmClient } from "../ports.js"; import type { RunUsage, Step } from "../types.js"; import type { ActionPolicy, Decision } from "../discover/decision.js"; import type { Finding } from "./findings.js"; export interface ExploreOptions { driver: Driver; llm: LlmClient; /** Where the survey starts. */ baseUrl: string; /** Step cap for the loop — exploration wanders, so the default is looser than discover's. */ maxSteps?: number; /** Fired per decision (with the executed Step, when one ran) — a host's live timeline. */ onStep?: (decision: Decision, step?: Step) => void; /** Fired as each finding is recorded — a host's live findings feed. */ onFinding?: (finding: Finding) => void; /** Abort exploration between steps (a host's Stop button). */ signal?: AbortSignal; /** Gate proposed actions (block destructive controls, fence the origin, declare coverage done * via `stop`). The SAME seam discover takes — one safety surface for both loops. */ policy?: ActionPolicy; /** URL substrings whose 4xx/5xx is product noise — excluded from failed-request findings. */ benign?: string[]; /** Console-text substrings that are product noise — excluded from console-error findings. */ benignConsole?: string[]; /** Settle wall-time at/above this becomes a slow-settle finding. Default 5000ms. */ slowSettleMs?: number; } export interface ExploreReport { charter: string; /** Distinct destinations (host+path) the survey reached, in first-visit order. */ visited: string[]; /** Every executed step, including the seed goto — the reproduction trail findings point into. */ steps: Step[]; /** Deduped findings, first-seen order. Severity ordering is the renderer's job. */ findings: Finding[]; usage: RunUsage; /** True when the loop hit the step cap (or gave up on consecutive policy blocks) before the * model — or the policy's `stop` — called the charter covered. */ truncated: boolean; finalUrl?: string; } export declare function explore(charter: string, opts: ExploreOptions): Promise;