@orkestrel/browser 0.0.20 → 0.0.22

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.
@@ -25,8 +25,8 @@ export declare const BASE64_LOOKUP: Readonly<Record<string, number>>;
25
25
  * units, one fewer when the last would split a surrogate pair (so a limit of 1 before a pair keeps
26
26
  * nothing), followed by `\n[characters 0–END of TOTAL; FOOTER]`. The footer has no default, so
27
27
  * every caller states what the cut result's reader does next: the toolset passes
28
- * `BROWSER_TOOL_VIEW_FOOTER` for a result that carries a view and `BROWSER_TOOL_CUT_FOOTER` for
29
- * any other.
28
+ * `BROWSER_TOOL_VIEW_FOOTER` for an action or `dialog` receipt that carries a view and
29
+ * `BROWSER_TOOL_CUT_FOOTER` for any other result, including `look` and `read` results.
30
30
  *
31
31
  * @param text - The page-authored or composed string
32
32
  * @param limit - The most characters kept before the footer, a positive integer
@@ -68,6 +68,9 @@ export declare const BROWSER_CODEGEN_BINDING_NAME = "__orkestrelBrowserCodegen";
68
68
  */
69
69
  export declare const BROWSER_CODEGEN_SOURCE = "(() => {\n\tconst binding = '__orkestrelBrowserCodegen'\n\twindow[binding + '__state']?.controller.abort()\n\tconst state = { controller: new AbortController(), nodes: [], indices: new WeakMap() }\n\twindow[binding + '__state'] = state\n\tfor (const event of ['click', 'input', 'change', 'keydown', 'focusout', 'submit', 'contextmenu', 'drop']) {\n\t\tdocument.addEventListener(event, (event) => {\n\t\t\tif (!event.isTrusted || typeof window[binding] !== 'function') return\n\t\t\tif (event.type === 'keydown' && event.key !== 'Enter') return\n\t\t\tconst element = event.composedPath()[0]\n\t\t\tif (!(element instanceof Element)) return\n\t\t\tlet index = state.indices.get(element)\n\t\t\tif (index === undefined) {\n\t\t\t\tindex = state.nodes.push(element) - 1\n\t\t\t\tstate.indices.set(element, index)\n\t\t\t}\n\t\t\tconst control = element.tagName === 'SELECT' ? (element.multiple ? 'multiple' : 'select')\n\t\t\t\t: element.tagName === 'OPTION' ? 'option'\n\t\t\t\t: element.tagName === 'INPUT' && element.type === 'password' ? 'password'\n\t\t\t\t: element.tagName === 'TEXTAREA' || element.isContentEditable ||\n\t\t\t\t\t(element.tagName === 'INPUT' && ['text', 'search', 'url', 'tel', 'email', 'number'].includes(element.type)) ? 'text' : 'other'\n\t\t\tconst payload = { event: event.type, index, top: window === window.top && element.ownerDocument === document, control, form: !!element.form }\n\t\t\tif (event.type === 'click') payload.detail = event.detail\n\t\t\tif (event.type === 'keydown') payload.key = 'Enter'\n\t\t\tif (event.type === 'input' && control === 'password') payload.secret = true\n\t\t\tif (event.type === 'input' && control === 'text') payload.value = element.isContentEditable ? element.textContent || '' : element.value\n\t\t\tif (event.type === 'change' && control === 'select') {\n\t\t\t\tpayload.value = element.value\n\t\t\t\tpayload.roundtrip = Array.from(element.options).find(option => option.value === element.value) === element.selectedOptions[0]\n\t\t\t}\n\t\t\tif (element.getRootNode() !== document) {\n\t\t\t\tpayload.event = 'unsupported'\n\t\t\t\tpayload.gap = 'the element is in a shadow root'\n\t\t\t} else if (event.type === 'contextmenu' || event.type === 'drop' || (event.type === 'click' && (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey) && !['select', 'multiple', 'option'].includes(control))) {\n\t\t\t\tpayload.event = 'unsupported'\n\t\t\t\tpayload.gap = 'an unsupported gesture'\n\t\t\t}\n\t\t\twindow[binding](JSON.stringify(payload.event === 'unsupported' ? { event: payload.event, index, top: payload.top, control, form: payload.form, gap: payload.gap } : payload))\n\t\t}, { capture: true, signal: state.controller.signal })\n\t}\n})()";
70
70
 
71
+ /** Matches protocol errors caused by replacement or closure of an execution context. */
72
+ export declare const BROWSER_CONTEXT_LOSS_PATTERN: RegExp;
73
+
71
74
  /**
72
75
  * Sets the default timeout for browser connection, requests, and navigation, `30_000`
73
76
  * milliseconds.
@@ -104,7 +107,7 @@ export declare const BROWSER_FRAME_WORLD_NAME = "__orkestrelBrowserFrame";
104
107
  */
105
108
  export declare const BROWSER_HAR_CREATOR: Readonly<{
106
109
  name: "@orkestrel/browser";
107
- version: "0.0.20";
110
+ version: "0.0.22";
108
111
  }>;
109
112
 
110
113
  /** Names accessibility roles that receive actionable outline references. */
@@ -249,6 +252,16 @@ export declare const BROWSER_SCHEMES: readonly string[];
249
252
  /** Names the attribute that tags temporary screenshot styles and masks. */
250
253
  export declare const BROWSER_SCREENSHOT_ATTRIBUTE = "data-orkestrel-screenshot";
251
254
 
255
+ /**
256
+ * Matches one word of an outline search and of a row's role and name: a run of at least 3 letters
257
+ * or digits.
258
+ *
259
+ * @remarks
260
+ * The 3-character floor drops words such as `a`, `to`, and `of`, which would otherwise score a row
261
+ * whose name shares them with the search.
262
+ */
263
+ export declare const BROWSER_SEARCH_PATTERN: RegExp;
264
+
252
265
  /**
253
266
  * Sets the default maximum node count accepted from a decoded CDP DOM snapshot, `100_000`.
254
267
  */
@@ -297,20 +310,21 @@ export declare const BROWSER_TOOL_CHANGED_NOTE = "(The page changed before the v
297
310
  *
298
311
  * @remarks
299
312
  * Every tool description is at most 25 words and says what the tool shows or does, and for
300
- * `look` and `read` when to call it; every parameter description is at most 100 characters.
313
+ * `look`, `read`, and `plain` when to call it; every parameter description is at most 100 characters.
301
314
  * Every tool declares at least one required parameter, because the streamed tool-call parser of
302
- * Ollama 0.34.4 rejects a call to a tool that declares no parameter. `look` takes `what` alone
303
- * and `read` takes `what` and `offset`; neither is scoped to an element, and an element's own
304
- * reading is `BrowserElementInterface.read`. `look`, `read`, and `journeys` annotate `pure` and
315
+ * Ollama 0.34.4 rejects a call to a tool that declares no parameter. `look`, `read`, and `plain` take
316
+ * `search` and `offset`; an element's own reading is `BrowserElementInterface.read`.
317
+ * `look`, `read`, `plain`, and `journeys` annotate `pure` and
305
318
  * `untrusted`, `wait` and `tabs` annotate `pure`, and the rest carry no annotation. `type` takes
306
319
  * `secret` beside `ref`, `text`, and `submit`. The journey tools `record`, `save`, `journeys`,
307
320
  * `edit`, and `replay` are advertised only by a toolset constructed with `journeys`.
321
+ * `wait` takes `absent` beside `text` and `timeout`.
308
322
  */
309
323
  export declare const BROWSER_TOOL_COPY: Readonly<Record<BrowserToolName, ToolDefinition>>;
310
324
 
311
325
  /**
312
- * Holds the clause that ends the footer of a cut result that carries no view: a read note, a tab
313
- * list, a wait, a page tool's output, or an error message.
326
+ * Holds the clause that ends the footer of a cut result other than an action or `dialog` receipt
327
+ * that carries a view, including `look` and `read` results.
314
328
  */
315
329
  export declare const BROWSER_TOOL_CUT_FOOTER = "the rest was cut";
316
330
 
@@ -351,7 +365,7 @@ export declare const BROWSER_TOOL_LIMIT = 4000;
351
365
  export declare const BROWSER_TOOL_NAME_PATTERN: RegExp;
352
366
 
353
367
  /**
354
- * Names every tool the browser toolset reserves: `look`, `read`, `click`, `type`, `press`,
368
+ * Names every tool the browser toolset reserves: `look`, `read`, `plain`, `click`, `type`, `press`,
355
369
  * `navigate`, `wait`, `dialog`, `tabs`, and `switch`.
356
370
  */
357
371
  export declare const BROWSER_TOOL_NAMES: readonly BrowserToolName[];
@@ -374,10 +388,10 @@ export declare const BROWSER_TOOL_TIMEOUT_LIMIT_MS = 30000;
374
388
  export declare const BROWSER_TOOL_TIMEOUT_MS = 5000;
375
389
 
376
390
  /**
377
- * Holds the clause that ends the footer of a cut result that carries a view, the result of
378
- * `look` and of every action, and names `read` as the call that returns the page's text.
391
+ * Holds the clause that ends the footer of a cut action or `dialog` receipt that carries a view,
392
+ * and names `look` as the call that finds an element the cut view leaves out.
379
393
  */
380
- export declare const BROWSER_TOOL_VIEW_FOOTER = "the rest was cut; call read for the page's text";
394
+ export declare const BROWSER_TOOL_VIEW_FOOTER = "the rest was cut; call look with words to find";
381
395
 
382
396
  /**
383
397
  * Names the accessibility roles the `type` tool writes to: `textbox`, `searchbox`, and
@@ -392,6 +406,15 @@ export declare const BROWSER_TOOL_VIEW_FOOTER = "the rest was cut; call read for
392
406
  */
393
407
  export declare const BROWSER_TYPED_ROLES: ReadonlySet<string>;
394
408
 
409
+ /**
410
+ * Names the finished transitions and animations that wake a parked wait.
411
+ *
412
+ * @remarks
413
+ * Chromium 154.0.4258.53 delivers these events in main and isolated worlds after a
414
+ * visibility or discrete display exit. Opacity alone leaves text in `innerText`.
415
+ */
416
+ export declare const BROWSER_WAIT_EVENTS: readonly string[];
417
+
395
418
  /**
396
419
  * Captures Chromium Accessibility-domain snapshots for one page.
397
420
  *
@@ -1109,8 +1132,9 @@ export declare interface BrowserElementInterface {
1109
1132
  /** Moves focus to the element. */
1110
1133
  focus(options?: BrowserCallOptions): Promise<void>;
1111
1134
  /**
1112
- * Captures the element's markup with its document's URL and title as a reading whose `stale` flag
1113
- * tracks later navigations of that document.
1135
+ * Captures the element's rendered markup with its document's URL and title as a reading whose
1136
+ * `stale` flag tracks later navigations of that document; {@link BrowserReadingInput} defines
1137
+ * the rendered markup.
1114
1138
  */
1115
1139
  read(options?: BrowserCallOptions): Promise<BrowserReadingInterface>;
1116
1140
  /**
@@ -1141,7 +1165,7 @@ export declare class BrowserElementManager implements BrowserElementManagerInter
1141
1165
  outline(options?: BrowserOutlineOptions): Promise<BrowserOutline>;
1142
1166
  /** A CSS query searches the page's main-frame document; use the accessibility outline for in-process child documents. */
1143
1167
  find(query: BrowserElementQuery, options?: BrowserCallOptions): Promise<readonly BrowserPageElementInterface[]>;
1144
- wait(query: BrowserElementQuery, options?: BrowserElementWaitOptions): Promise<readonly BrowserPageElementInterface[]>;
1168
+ wait(query: BrowserElementQuery, options?: BrowserWaitOptions): Promise<readonly BrowserPageElementInterface[]>;
1145
1169
  element(reference: string): BrowserPageElementInterface | undefined;
1146
1170
  elements(): readonly BrowserPageElementInterface[];
1147
1171
  clear(): void;
@@ -1163,13 +1187,16 @@ export declare interface BrowserElementManagerInput {
1163
1187
  readonly world: BrowserElementWorldFunction;
1164
1188
  readonly reference: BrowserReferenceFunction;
1165
1189
  readonly ready: BrowserReadinessFunction;
1190
+ /** Discards readiness after context loss and waits for the destination document. */
1191
+ readonly recover: BrowserReadinessFunction;
1166
1192
  }
1167
1193
 
1168
1194
  /** Captures, queries, and retains references to a view's elements. */
1169
1195
  export declare interface BrowserElementManagerInterface<TElement extends BrowserElementInterface = BrowserElementInterface> {
1170
1196
  /**
1171
1197
  * Captures the view's document as a document-order outline, binding a reference to each
1172
- * interactive element and bounding the referenced rows by `limit`.
1198
+ * interactive element and bounding the referenced rows by `limit`. The outline also lists the
1199
+ * rows that best match `search` and names the focused referenced row, both past `limit`.
1173
1200
  */
1174
1201
  outline(options?: BrowserOutlineOptions): Promise<BrowserOutline>;
1175
1202
  /**
@@ -1178,10 +1205,10 @@ export declare interface BrowserElementManagerInterface<TElement extends Browser
1178
1205
  */
1179
1206
  find(query: BrowserElementQuery, options?: BrowserCallOptions): Promise<readonly TElement[]>;
1180
1207
  /**
1181
- * Resolves with the elements matching `query` after a mutation produces a match, or after none
1208
+ * Resolves with the elements matching `query` after a mutation or a finished transition or animation produces a match, or after none
1182
1209
  * matches when `absent` is set; rejects at the deadline or on abort.
1183
1210
  */
1184
- wait(query: BrowserElementQuery, options?: BrowserElementWaitOptions): Promise<readonly TElement[]>;
1211
+ wait(query: BrowserElementQuery, options?: BrowserWaitOptions): Promise<readonly TElement[]>;
1185
1212
  /**
1186
1213
  * Returns the element a reference names, or `undefined` when the reference is unknown or was
1187
1214
  * dropped.
@@ -1235,11 +1262,6 @@ export declare interface BrowserElementSubject {
1235
1262
  readonly subject: string;
1236
1263
  }
1237
1264
 
1238
- /** Configures an element wait, including whether absence satisfies it. */
1239
- export declare interface BrowserElementWaitOptions extends BrowserCallOptions {
1240
- readonly absent?: boolean;
1241
- }
1242
-
1243
1265
  /** Resolves the page-owned isolated world for a particular frame and session. */
1244
1266
  export declare type BrowserElementWorldFunction = (frame: string, session: string, options?: BrowserCallOptions) => Promise<number>;
1245
1267
 
@@ -1412,11 +1434,11 @@ export declare interface BrowserFrameInterface {
1412
1434
  /** Resolves the frame document title. */
1413
1435
  title(options?: BrowserCallOptions): Promise<string>;
1414
1436
  /**
1415
- * Captures the document URL, title, and HTML in one size-guarded evaluation in the frame's
1437
+ * Captures the document URL, title, and rendered HTML in one size-guarded evaluation in the frame's
1416
1438
  * isolated world and returns them as a reading whose `stale` flag tracks later navigations.
1417
1439
  * A frame constructed without an epoch source (a standalone `BrowserFrame` with no `epoch`
1418
1440
  * argument) returns readings whose `stale` stays `false`, because no navigation counter is
1419
- * available to it.
1441
+ * available to it. {@link BrowserReadingInput} defines the rendered markup.
1420
1442
  */
1421
1443
  read(options?: BrowserCallOptions): Promise<BrowserReadingInterface>;
1422
1444
  /** Evaluates an expression in the frame execution world under the result-size guard. */
@@ -2389,13 +2411,24 @@ export declare interface BrowserNodeQuery {
2389
2411
  */
2390
2412
  export declare type BrowserOperationOptions = BrowserClickOptions & BrowserDragOptions;
2391
2413
 
2392
- /** Carries a document-order outline and its included and available element counts. */
2414
+ /**
2415
+ * Carries a document-order outline and its included and available element counts.
2416
+ *
2417
+ * @remarks
2418
+ * - `matches` — the rendered rows that best match the options' `search`, in document order and
2419
+ * past `limit` included; empty without a `search` or without a match
2420
+ * - `focus` — the rendered row of the referenced element that has focus, past `limit` included;
2421
+ * the last such row in document order when several do, and `undefined` when focus is on no
2422
+ * referenced element
2423
+ */
2393
2424
  export declare interface BrowserOutline {
2394
2425
  readonly url: string;
2395
2426
  readonly title: string;
2396
2427
  readonly text: string;
2397
2428
  readonly count: number;
2398
2429
  readonly total: number;
2430
+ readonly matches: readonly string[];
2431
+ readonly focus: string | undefined;
2399
2432
  }
2400
2433
 
2401
2434
  /** Associates an outline row with its frame, session, and optional actionable reference. */
@@ -2405,10 +2438,20 @@ export declare interface BrowserOutlineNode extends BrowserAXNode {
2405
2438
  readonly tool?: string;
2406
2439
  }
2407
2440
 
2408
- /** Configures an outline's element limit and optional subtree. */
2441
+ /**
2442
+ * Configures an outline's element limit, optional subtree, and search.
2443
+ *
2444
+ * @remarks
2445
+ * - `search` — the words that select the outline's `matches`: the text is lowercased and split
2446
+ * into whole words of at least 3 letters or digits (`BROWSER_SEARCH_PATTERN`), each referenced
2447
+ * row's role and accessible name are split the same way, and a row scores the number of distinct
2448
+ * search words equal to one of its words; every referenced row with the highest score above 0
2449
+ * matches
2450
+ */
2409
2451
  export declare interface BrowserOutlineOptions extends BrowserCallOptions {
2410
2452
  readonly limit?: number;
2411
2453
  readonly within?: string;
2454
+ readonly search?: string;
2412
2455
  }
2413
2456
 
2414
2457
  /**
@@ -2452,7 +2495,7 @@ export declare class BrowserPage extends BrowserFrame implements BrowserPageInte
2452
2495
  get mouse(): BrowserMouseInterface;
2453
2496
  get touch(): BrowserTouchInterface;
2454
2497
  read(options?: BrowserCallOptions): Promise<BrowserReadingInterface>;
2455
- wait(text: string, options?: BrowserCallOptions): Promise<void>;
2498
+ wait(text: string, options?: BrowserWaitOptions): Promise<void>;
2456
2499
  get network(): BrowserNetworkManagerInterface;
2457
2500
  get registry(): BrowserRegistryInterface;
2458
2501
  get navigation(): BrowserNavigationManagerInterface;
@@ -2586,8 +2629,8 @@ export declare interface BrowserPageInterface extends BrowserFrameInterface, Bro
2586
2629
  readonly keyboard: BrowserKeyboardInterface;
2587
2630
  readonly mouse: BrowserMouseInterface;
2588
2631
  readonly touch: BrowserTouchInterface;
2589
- /** Waits for visible text in the main document, rejecting at the deadline or on abort. */
2590
- wait(text: string, options?: BrowserCallOptions): Promise<void>;
2632
+ /** Waits for text in the main document body’s `innerText`, or its absence with `absent`, rejecting at the deadline or on abort. */
2633
+ wait(text: string, options?: BrowserWaitOptions): Promise<void>;
2591
2634
  readonly emitter: EmitterInterface<BrowserPageEventMap>;
2592
2635
  readonly registry: BrowserRegistryInterface;
2593
2636
  readonly network: BrowserNetworkManagerInterface;
@@ -2892,7 +2935,7 @@ export declare interface BrowserReadinessWait {
2892
2935
  * title: 'Example',
2893
2936
  * html: '<nav>Menu</nav><main><p>Body</p></main>',
2894
2937
  * })
2895
- * reading.markdown() // { text: 'Body', offset: 0, total: 4 }
2938
+ * reading.markdown({ distill: true }) // { text: 'Body', offset: 0, total: 4 }
2896
2939
  * ```
2897
2940
  */
2898
2941
  export declare class BrowserReading implements BrowserReadingInterface {
@@ -2910,13 +2953,45 @@ export declare class BrowserReading implements BrowserReadingInterface {
2910
2953
  * Describes the captured document a reading is built from.
2911
2954
  *
2912
2955
  * @remarks
2913
- * - `url` — the document URL, which distillation resolves relative links against
2956
+ * - `url` — the document URL, which each projection resolves relative links against
2914
2957
  * - `title` — the document title
2915
2958
  * - `html` — the serialized document HTML
2916
2959
  * - `epoch` — the navigation epoch recorded when the capture was issued. Default: the value
2917
2960
  * `navigation` returns at construction
2918
2961
  * - `navigation` — reads the source's navigation epoch at the moment of the call; a reading
2919
2962
  * built without it never reports stale
2963
+ *
2964
+ * A view, frame, or element captures rendered markup by importing its root into an HTML
2965
+ * document without a window, so that nothing in the copy loads or runs, and pruning the copy
2966
+ * against the live document's computed styles. The live document is never written.
2967
+ * - A root or flat-tree ancestor in its own document with `display: none` yields empty HTML.
2968
+ * - Descendants with `display: none` are removed.
2969
+ * - Text under `visibility: hidden` or `collapse`, and invisible elements without children,
2970
+ * are removed; visible descendants of invisible elements remain.
2971
+ * - A child node of an element with an open shadow root is removed when no slot takes it or
2972
+ * when its slot sits under an element whose computed `display` is `none`.
2973
+ * - Closed `details` keeps only its first `summary` child. Elements with `content-visibility:
2974
+ * hidden`, and `canvas`, `video`, and `audio` elements, lose their child nodes.
2975
+ * - SVG `switch` keeps the child element with client rects, or its first child element when
2976
+ * none has rects, including definitions referenced by `use`. Other branches are removed.
2977
+ * Forms, rendered dialogs, and buttons become neutral carriers. Text fields and textareas
2978
+ * carry live values; empty text fields and textareas carry visible placeholders. Selects carry the selected
2979
+ * label, or displayed option and group labels in a listbox's client area. Named graphics carry
2980
+ * one explicit alternative; printed button text takes precedence over its accessible name.
2981
+ * Links carry resolved live addresses. Region elements remain available to distillation.
2982
+ * Carriers and block `div`, `summary`, and `details` elements receive `br` separators around their
2983
+ * contents. The `html` handle is this normalized capture, not the original DOM serialization.
2984
+ * Direct element reads apply the same ancestor visibility and child-pruning rules.
2985
+ * Password and hidden inputs are removed entirely, including in the data-only fallback for
2986
+ * detached roots and documents without a window. Active floor elements are dropped.
2987
+ * Checkbox, radio, range, and color values aren't printed text. Native control captions,
2988
+ * localized dates, invalid or intermediate number edits, and MathML are omitted rather than
2989
+ * guessed. A file input carries its sole filename; native multiple-file summaries are omitted.
2990
+ * Valid committed numbers carry their live value.
2991
+ * Opacity, clipping outside listboxes, size, position, and `content-visibility: auto` remove
2992
+ * nothing. Shadow-root text, generated content, text transformations, localized number
2993
+ * formatting, textarea clipping, and significant spaces are outside the capture's fidelity.
2994
+ * Caller-supplied HTML is parsed as given; projection options and their safety floors apply.
2920
2995
  */
2921
2996
  export declare interface BrowserReadingInput {
2922
2997
  readonly url: string;
@@ -2933,12 +3008,13 @@ export declare interface BrowserReadingInput {
2933
3008
  * @remarks
2934
3009
  * - `url` — the document URL at capture
2935
3010
  * - `title` — the document title at capture
2936
- * - `html` — the parsed document handle every projection reads
3011
+ * - `html` — the parsed captured and normalized document handle every projection reads;
3012
+ * caller-supplied HTML remains as supplied
2937
3013
  * - `stale` — true when the source frame has navigated or detached since the capture; false
2938
3014
  * otherwise
2939
3015
  *
2940
- * Each projection runs over `html.distill({ base: url })` by default and over the whole document
2941
- * with `distill: false`. A reading computes each projection one time and cuts every slice from
3016
+ * Each projection runs over the whole document by default and over
3017
+ * `html.distill({ base: url })` with `distill: true`. A reading computes each projection one time and cuts every slice from
2942
3018
  * it, so successive slices of one reading and mode share one `total`.
2943
3019
  */
2944
3020
  export declare interface BrowserReadingInterface {
@@ -2959,12 +3035,23 @@ export declare interface BrowserReadingInterface {
2959
3035
  text(options?: BrowserReadOptions): BrowserReadResult;
2960
3036
  }
2961
3037
 
3038
+ /**
3039
+ * Describes a matching line and its character offset in a reading's projection.
3040
+ *
3041
+ * @remarks
3042
+ * Offsets count UTF-16 code units in the original text, including preceding line breaks.
3043
+ */
3044
+ export declare interface BrowserReadMatch {
3045
+ readonly offset: number;
3046
+ readonly text: string;
3047
+ }
3048
+
2962
3049
  /**
2963
3050
  * Describes the options for one slice of a reading's Markdown or plain-text projection.
2964
3051
  *
2965
3052
  * @remarks
2966
3053
  * - `distill` — if `true`, projects the distilled document; if `false`, projects the whole
2967
- * document. Default: `true`
3054
+ * document. Default: `false`
2968
3055
  * - `offset` — the character index the slice starts at, a non-negative integer. Default: `0`
2969
3056
  * - `limit` — the most characters the slice holds, a positive integer. Default: unbounded
2970
3057
  *
@@ -3129,7 +3216,7 @@ export declare interface BrowserRegistryInterface {
3129
3216
  tool(name: string, frame?: string): BrowserTool | undefined;
3130
3217
  /** Returns every registered tool, including shadowed frame registrations. */
3131
3218
  tools(): readonly BrowserTool[];
3132
- /** Projects tools as untrusted executable tools, omitting optional-what schemas. */
3219
+ /** Projects tools as untrusted executable tools, omitting optional-purpose schemas. */
3133
3220
  adopt(): Promise<readonly ToolInterface[]>;
3134
3221
  /** Invokes a tool and awaits its terminal event; rejects on abort, invalidation, or timeout. */
3135
3222
  execute(tool: BrowserTool, input: Readonly<Record<string, unknown>>, options?: BrowserCallOptions): Promise<BrowserInvocationResult>;
@@ -3876,11 +3963,11 @@ export declare interface BrowserRunStoreInterface {
3876
3963
  }
3877
3964
 
3878
3965
  /**
3879
- * Names a tool the browser toolset reserves: the seven generic tools, the staged `dialog`, the
3966
+ * Names a tool the browser toolset reserves: the generic tools, the staged `dialog`, the
3880
3967
  * opt-in `tabs` and `switch`, and the journey tools `record`, `save`, `journeys`, `edit`,
3881
3968
  * `replay`, and `forget`, which a toolset constructed with `journeys` reserves.
3882
3969
  */
3883
- export declare type BrowserToolName = 'look' | 'read' | 'click' | 'type' | 'press' | 'navigate' | 'wait' | 'dialog' | 'tabs' | 'switch' | 'record' | 'save' | 'journeys' | 'edit' | 'replay' | 'forget';
3970
+ export declare type BrowserToolName = 'look' | 'read' | 'plain' | 'click' | 'type' | 'press' | 'navigate' | 'wait' | 'dialog' | 'tabs' | 'switch' | 'record' | 'save' | 'journeys' | 'edit' | 'replay' | 'forget';
3884
3971
 
3885
3972
  /** Identifies a removed WebMCP tool by document and name. */
3886
3973
  export declare interface BrowserToolRemoval {
@@ -3893,7 +3980,7 @@ export declare interface BrowserRunStoreInterface {
3893
3980
  * view's own tools beside them.
3894
3981
  *
3895
3982
  * @remarks
3896
- * Every toolset advertises `look`, `read`, `click`, `type`, and `wait`, which need only the
3983
+ * Every toolset advertises `look`, `read`, `plain`, `click`, `type`, and `wait`, which need only the
3897
3984
  * `BrowserViewInterface` it is constructed over. With `options.page` it also advertises `press`
3898
3985
  * and `navigate`, stages the `dialog` tool while a dialog is open on the current page, follows a
3899
3986
  * popup the current page opens and returns to the opener when the popup closes, and adopts
@@ -3907,11 +3994,18 @@ export declare interface BrowserRunStoreInterface {
3907
3994
  * refuses every tool but `dialog` while a dialog is open, forwards `ToolContext.signal` into every
3908
3995
  * protocol call, refuses a call to a toolset tool that carries a parameter the tool does not
3909
3996
  * advertise, and cuts every returned string and every thrown message at `limit` characters plus
3910
- * a footer; the footer of a cut result that carries a view names `read` as the next call. `look`
3911
- * and `read` read the page, never one element. A page tool's error message and JSON output reach
3912
- * the toolset already cut at `BROWSER_REGISTRY_OUTPUT_LIMIT` (4 096) by the registry, so a
3913
- * `limit` over that shows at most 4 096 characters of either; a page tool's text output reaches
3914
- * the boundary whole.
3997
+ * a footer; the footer of a cut action or `dialog` receipt that carries a view names `look` as the next
3998
+ * call. `look`, `read`, and `plain` read the page and return pages of at most `limit`
3999
+ * characters and name the offset the next page starts at. A page ends after the last line break
4000
+ * in its window that lies past the page's start, or at the window's end when no such break fits,
4001
+ * without splitting a surrogate pair. The last page ends at the end of the outline or reading. A `look` whose
4002
+ * `search` matches referenced rows lists those rows first, and its pages reach every referenced row.
4003
+ * A `press` receipt names the referenced element that has focus after the key. A page tool's
4004
+ * error message and JSON output reach the toolset already cut at `BROWSER_REGISTRY_OUTPUT_LIMIT`
4005
+ * (4 096) by the registry, so a `limit` over that shows at most 4 096 characters of either; a page
4006
+ * tool's text output reaches the boundary whole.
4007
+ * `wait` with `absent` set to `true` settles when the text is not on the page, and a miss
4008
+ * returns the `timeout` outcome as an appearance miss does.
3915
4009
  *
3916
4010
  * `click`, `type`, `press`, `navigate`, and `switch` are actions: one runs at a time, in call
3917
4011
  * order, and holds the queue until its receipt. A queued action whose signal aborts leaves
@@ -3942,7 +4036,7 @@ export declare interface BrowserRunStoreInterface {
3942
4036
  * page placement's `type` with `submit` ends its action with `and submitted the form` when a read
3943
4037
  * recorded a submission, or when the navigation the receipt settled names `formSubmissionGet` or
3944
4038
  * `formSubmissionPost` as its reason, whatever the read answered, and with `and pressed Enter`
3945
- * otherwise. A `read`
4039
+ * otherwise. A `read` or `plain`
3946
4040
  * at an offset at or past its retained reading's end restarts that reading at 0. A receipt that
3947
4041
  * waits for a requested navigation shares one `BROWSER_TOOL_TIMEOUT_MS` deadline between that
3948
4042
  * wait and its view capture, of which `BROWSER_TOOL_CAPTURE_MS` is reserved for the capture. The
@@ -3958,9 +4052,9 @@ export declare interface BrowserRunStoreInterface {
3958
4052
  * A page tool is skipped, with `skip` emitted, when its name is reserved (`unresolved` included), when the manager holds
3959
4053
  * its name under a tool the toolset did not add (checked again immediately before each addition),
3960
4054
  * when its name falls outside `BROWSER_TOOL_NAME_PATTERN`, when its parameters or, for a source
3961
- * that supplies `tools()`, its selected registration declare `what` optional, or when that
4055
+ * that supplies `tools()`, its selected registration declare `purpose` optional, or when that
3962
4056
  * registration is marked `debugging`. The selected registration is the main frame's, then the
3963
- * earlier one. A page tool whose parameters require nothing advertises a required `what`, which
4057
+ * earlier one. A page tool whose parameters require nothing advertises a required `purpose`, which
3964
4058
  * is stripped before the tool runs. Every adopted tool is advertised `untrusted`. `destroy()`
3965
4059
  * removes only the tools the manager still holds under the instances the toolset added, never
3966
4060
  * closes a page, and ends only what `options.release` hands over, calling it one time last.
@@ -3971,7 +4065,7 @@ export declare interface BrowserRunStoreInterface {
3971
4065
  *
3972
4066
  * const toolset = new BrowserToolset(page, { page })
3973
4067
  * await toolset.start()
3974
- * const result = await toolset.tools.execute({ id: '1', name: 'look', arguments: { what: 'cart' } })
4068
+ * const result = await toolset.tools.execute({ id: '1', name: 'look', arguments: { search: 'cart' } })
3975
4069
  * await toolset.destroy()
3976
4070
  * ```
3977
4071
  */
@@ -4029,8 +4123,8 @@ export declare interface BrowserRunStoreInterface {
4029
4123
  * - `emitter` — emits `adopt`, `skip`, `select`, `action`, `hold`, and `release`
4030
4124
  * - `tools` — the manager the toolset fills, with execution through the `perform` boundary
4031
4125
  * - `native` — the generic tools alone, which a consumer publishes to a built-in agent: the
4032
- * seven for a page-backed toolset, and `look`, `read`, `click`, `type`, and `wait` for a
4033
- * view-backed one
4126
+ * `look`, `read`, `plain`, `click`, `type`, `press`, `navigate`, and `wait` for a page-backed
4127
+ * toolset, and `look`, `read`, `plain`, `click`, `type`, and `wait` for a view-backed one
4034
4128
  * - `view` — the view the tools act on
4035
4129
  */
4036
4130
  export declare interface BrowserToolsetInterface {
@@ -4142,7 +4236,7 @@ export declare interface BrowserRunStoreInterface {
4142
4236
  * - `reserved` — the name is one of the toolset's own tool names
4143
4237
  * - `held` — the manager holds the name under a tool the toolset did not add
4144
4238
  * - `pattern` — the name falls outside `BROWSER_TOOL_NAME_PATTERN`
4145
- * - `schema` — the page's input schema declares `what` as optional
4239
+ * - `schema` — the page's input schema declares `purpose` as optional
4146
4240
  * - `debugging` — the page marks the tool for developers
4147
4241
  */
4148
4242
  export declare type BrowserToolsetReason = 'reserved' | 'held' | 'pattern' | 'schema' | 'debugging';
@@ -4359,15 +4453,15 @@ export declare interface BrowserRunStoreInterface {
4359
4453
  /** Resolves the document title. */
4360
4454
  title(options?: BrowserCallOptions): Promise<string>;
4361
4455
  /**
4362
- * Captures the document URL, title, and markup as a reading whose `stale` flag tracks later
4363
- * navigations.
4456
+ * Captures the document URL, title, and rendered markup as a reading whose `stale` flag tracks
4457
+ * later navigations; {@link BrowserReadingInput} defines the rendered markup.
4364
4458
  */
4365
4459
  read(options?: BrowserCallOptions): Promise<BrowserReadingInterface>;
4366
4460
  /**
4367
- * Resolves when `text` is visible in the document; rejects with a `BrowserError` coded
4461
+ * Resolves when the main document body’s `innerText` contains `text`, or lacks it with `absent`; rejects with a `BrowserError` coded
4368
4462
  * `BROWSER_WAIT_TIMEOUT` at the deadline, and with `signal.reason` on abort.
4369
4463
  */
4370
- wait(text: string, options?: BrowserCallOptions): Promise<void>;
4464
+ wait(text: string, options?: BrowserWaitOptions): Promise<void>;
4371
4465
  }
4372
4466
 
4373
4467
  /** Describes the viewport dimensions for a browser page. */
@@ -4380,6 +4474,18 @@ export declare interface BrowserRunStoreInterface {
4380
4474
  readonly landscape?: boolean;
4381
4475
  }
4382
4476
 
4477
+ /**
4478
+ * Configures a text or element wait, including whether absence satisfies it.
4479
+ *
4480
+ * @remarks
4481
+ * - `absent` — if `true`, the wait resolves when the body's `innerText` lacks the text or no
4482
+ * element matches; if `false` or omitted, when the text is present or an element matches.
4483
+ * A condition that already holds resolves at the first check
4484
+ */
4485
+ export declare interface BrowserWaitOptions extends BrowserCallOptions {
4486
+ readonly absent?: boolean;
4487
+ }
4488
+
4383
4489
  /** Names the page load condition for navigation — the CDP load event awaited by `navigate()`. */
4384
4490
  export declare type BrowserWaitUntil = 'commit' | 'load' | 'domcontentloaded' | 'idle';
4385
4491
 
@@ -4762,6 +4868,20 @@ export declare interface BrowserRunStoreInterface {
4762
4868
  */
4763
4869
  export declare function collectBrowserJourneyTextBindings(steps: readonly BrowserJourneyStepInput[]): readonly string[];
4764
4870
 
4871
+ /**
4872
+ * Collects distinct lowercase words of at least 3 letters or digits.
4873
+ *
4874
+ * @param text - Text to scan
4875
+ * @returns The searchable whole words
4876
+ *
4877
+ * @example
4878
+ * ```ts
4879
+ * import { collectBrowserWords } from '@orkestrel/browser'
4880
+ * [...collectBrowserWords('The cart, the bag')] // ['the', 'cart', 'bag']
4881
+ * ```
4882
+ */
4883
+ export declare function collectBrowserWords(text: string): ReadonlySet<string>;
4884
+
4765
4885
  /**
4766
4886
  * Compiles the element-side actionability pass used before trusted input.
4767
4887
  *
@@ -4894,22 +5014,26 @@ export declare interface BrowserRunStoreInterface {
4894
5014
  export declare function compileHitFunction(): string;
4895
5015
 
4896
5016
  /**
4897
- * Compiles a mutation-driven wait with one deadline and explicit disconnect ownership.
5017
+ * Compiles a wait woken by mutations and finished transitions and animations, with one deadline and explicit disconnect ownership.
5018
+ * @remarks
5019
+ * `transitionend` and `animationend` inside a shadow root are not composed in Chromium
5020
+ * 154.0.4258.53, so this document listener does not see them. Mutations inside that root are
5021
+ * not observed either.
4898
5022
  * @param deadline - Maximum time in milliseconds
4899
5023
  * @param key - Isolated-world property owning this observer
4900
- * @param predicate - Optional expression checked immediately and after each mutation batch
5024
+ * @param predicate - Optional expression checked immediately and on the task after a mutation batch or a `BROWSER_WAIT_EVENTS` event
4901
5025
  * @returns Promise expression resolving true on a match or change, false at the deadline
4902
5026
  */
4903
5027
  export declare function compileQueryWaitExpression(deadline: number, key: string, predicate?: string): string;
4904
5028
 
4905
5029
  /**
4906
- * Compiles the in-page function that reads the document's URL, title, and serialized HTML.
5030
+ * Compiles the in-page function that reads the document's URL, title, and rendered HTML.
4907
5031
  *
4908
5032
  * @remarks
4909
- * The declaration takes no arguments and returns `{ url, title, html }` from `location.href`,
4910
- * `document.title`, and `document.documentElement.outerHTML`, with `html` empty for a document
4911
- * that has no root element. Call it inside {@link compileGuardedEvaluateExpression} to bound the
4912
- * result under {@link BROWSER_RESULT_LIMIT}.
5033
+ * The optional root defaults to `document.documentElement`. {@link BrowserReadingInput}
5034
+ * defines its inert capture, lowering, redaction, and limits. A missing root yields empty HTML.
5035
+ * Call it inside {@link compileGuardedEvaluateExpression} to bound the final serialized result
5036
+ * under {@link BROWSER_RESULT_LIMIT}.
4913
5037
  *
4914
5038
  * @returns A function declaration source
4915
5039
  */
@@ -5008,13 +5132,14 @@ export declare interface BrowserRunStoreInterface {
5008
5132
  export declare function compileSubmitReadExpression(token: number): string;
5009
5133
 
5010
5134
  /**
5011
- * Compiles a visible-text wait coalesced by animation frames.
5135
+ * Compiles a wait for the presence or absence of visible text, coalesced by tasks.
5012
5136
  * @param text - Text to find in the main document body
5013
5137
  * @param deadline - Maximum time in milliseconds
5014
5138
  * @param key - Isolated-world property owning this observer
5139
+ * @param absent - If `true`, resolves when the body's `innerText` lacks `text`; if `false`, when it contains it. Default: `false`
5015
5140
  * @returns Mutation-driven promise expression with one deadline
5016
5141
  */
5017
- export declare function compileTextWaitExpression(text: string, deadline: number, key: string): string;
5142
+ export declare function compileTextWaitExpression(text: string, deadline: number, key: string, absent?: boolean): string;
5018
5143
 
5019
5144
  /**
5020
5145
  * Composes a frame-local point with its ancestor frame offsets.
@@ -5150,7 +5275,7 @@ export declare interface BrowserRunStoreInterface {
5150
5275
  *
5151
5276
  * const toolset = createBrowserToolset(page, { context })
5152
5277
  * await toolset.start()
5153
- * const result = await toolset.tools.execute({ id: '1', name: 'look', arguments: { what: 'cart' } })
5278
+ * const result = await toolset.tools.execute({ id: '1', name: 'look', arguments: { search: 'cart' } })
5154
5279
  * ```
5155
5280
  *
5156
5281
  * @example Drive a page with a small model
@@ -5164,8 +5289,8 @@ export declare interface BrowserRunStoreInterface {
5164
5289
  * const system =
5165
5290
  * 'You control a web browser with tools and must call a tool before you answer. ' +
5166
5291
  * 'The first message shows the page as look returns it; references such as e4 name its elements. ' +
5167
- * 'To learn a fact, call read with what set to your question; when its result ends by naming an offset, call read again with that offset. ' +
5168
- * 'To search, call type with the search box reference, the words, and submit true. ' +
5292
+ * 'To learn a fact, call read with search set to words from your question; when its result ends by naming an offset, call read again with that offset. ' +
5293
+ * "To use the site's search box, call type with its reference, the words, and submit true. " +
5169
5294
  * 'To press a button or follow a link, call click with its reference from the latest result. Never invent a reference. ' +
5170
5295
  * 'If text you expect has not appeared, call wait once. ' +
5171
5296
  * 'When the task is done, answer in one short sentence.'
@@ -5175,11 +5300,11 @@ export declare interface BrowserRunStoreInterface {
5175
5300
  * const page = await browser.create({ url: 'https://shop.example.test/' })
5176
5301
  * const toolset = createBrowserToolset(page, { tools: createToolManager() })
5177
5302
  * await toolset.start()
5178
- * toolset.tools.tools().map((tool) => tool.name) // ['look', 'read', 'click', 'type', 'press', 'navigate', 'wait']
5303
+ * toolset.tools.tools().map((tool) => tool.name) // ['look', 'read', 'plain', 'click', 'type', 'press', 'navigate', 'wait']
5179
5304
  * const seeded = await toolset.tools.execute({
5180
5305
  * id: 'seed',
5181
5306
  * name: 'look',
5182
- * arguments: { what: 'the page' },
5307
+ * arguments: { search: '' },
5183
5308
  * })
5184
5309
  * const view = seeded.success ? String(seeded.value) : seeded.error
5185
5310
  * const agent = createAgent(createOllama({ model: 'qwen3.5:2b-q4_K_M' }), {
@@ -5266,10 +5391,10 @@ export declare interface BrowserRunStoreInterface {
5266
5391
  export declare function deriveBrowserJourneyTrigger(step: BrowserJourneyStepInput, inputs?: Readonly<Record<string, string>>): string;
5267
5392
 
5268
5393
  /**
5269
- * Derives the advertised input schema from an authored one, adding a required `what` parameter when the schema requires nothing.
5394
+ * Derives the advertised input schema from an authored one, adding a required `purpose` parameter when the schema requires nothing.
5270
5395
  * @param schema - Authored input schema, or undefined for a parameterless tool
5271
- * @returns An advertised schema, or undefined when the authored `what` parameter is optional
5272
- * @remarks The caller strips only a synthetic `what` parameter before invoking the page tool.
5396
+ * @returns An advertised schema, or undefined when the authored `purpose` parameter is optional
5397
+ * @remarks The caller strips only a synthetic `purpose` parameter before invoking the page tool.
5273
5398
  */
5274
5399
  export declare function deriveBrowserToolSchema(schema: Readonly<Record<string, unknown>> | undefined): Readonly<Record<string, unknown>> | undefined;
5275
5400
 
@@ -6100,15 +6225,111 @@ export declare interface BrowserRunStoreInterface {
6100
6225
  */
6101
6226
  export declare function renderBrowserJourneyFault(fault: BrowserStoreFault): string;
6102
6227
 
6228
+ /**
6229
+ * Renders matching rows in at most half the available reply room.
6230
+ *
6231
+ * @remarks
6232
+ * An oversized first row is cut with an ellipsis without splitting a surrogate pair, reserving
6233
+ * room for the first later row that can fit beside it only when the cut keeps the leading token
6234
+ * through its first space. Otherwise it cuts without reserving. Later rows that do not fit are
6235
+ * skipped. An empty collection or a cut with no character before the ellipsis produces no block.
6236
+ *
6237
+ * @param heading - The match count and search, ending with a colon
6238
+ * @param rows - Matching rows in document order
6239
+ * @param room - Characters available in the reply
6240
+ * @returns The bounded block with a trailing blank line, or an empty string
6241
+ *
6242
+ * @example
6243
+ * ```ts
6244
+ * import { renderBrowserMatches } from '@orkestrel/browser'
6245
+ * renderBrowserMatches('Matches:', ['[5] Cart'], 100) // 'Matches:\n[5] Cart\n\n'
6246
+ * ```
6247
+ */
6248
+ export declare function renderBrowserMatches(heading: string, rows: readonly string[], room: number): string;
6249
+
6103
6250
  /**
6104
6251
  * Renders document-order text and referenced elements with a bounded element count.
6252
+ *
6253
+ * @remarks
6254
+ * Each referenced row renders through `renderBrowserOutlineRow`, and the closing
6255
+ * `(COUNT of TOTAL elements)` line counts the rows included and available. `matches` holds the
6256
+ * rows `scanBrowserOutline` returns for `search`, and `focus` the last referenced row whose node
6257
+ * carries a `focused` property of `true`; both reach past `limit`.
6258
+ *
6105
6259
  * @param url - Document address
6106
6260
  * @param title - Document title
6107
6261
  * @param nodes - Ordered accessibility rows
6108
6262
  * @param limit - Maximum referenced rows to include
6109
- * @returns Outline text and element counts
6263
+ * @param search - The words whose best-matching rows `matches` lists. Default: none, which lists
6264
+ * none
6265
+ * @returns Outline text, element counts, matching rows, and the focused row
6266
+ *
6267
+ * @example
6268
+ * ```ts
6269
+ * import { renderBrowserOutline } from '@orkestrel/browser'
6270
+ *
6271
+ * const node = {
6272
+ * parent: undefined,
6273
+ * children: [],
6274
+ * backend: undefined,
6275
+ * frame: undefined,
6276
+ * ignored: false,
6277
+ * description: undefined,
6278
+ * value: undefined,
6279
+ * session: 'main',
6280
+ * }
6281
+ * const outline = renderBrowserOutline(
6282
+ * 'https://shop.example/cart',
6283
+ * 'Cart',
6284
+ * [
6285
+ * { ...node, id: '1', role: 'button', name: 'Close', properties: {}, reference: 'e1' },
6286
+ * { ...node, id: '2', role: 'button', name: 'Archive', properties: { focused: true }, reference: 'e2' },
6287
+ * ],
6288
+ * 1,
6289
+ * 'archive button',
6290
+ * )
6291
+ * outline.text // 'page "Cart" https://shop.example/cart\ne1 button "Close"\n(1 of 2 elements)'
6292
+ * outline.matches // ['e2 button "Archive"']
6293
+ * outline.focus // 'e2 button "Archive"'
6294
+ * ```
6295
+ */
6296
+ export declare function renderBrowserOutline(url: string, title: string, nodes: readonly BrowserOutlineNode[], limit: number, search?: string): BrowserOutline;
6297
+
6298
+ /**
6299
+ * Renders one outline row: the node's reference, its role, its quoted accessible name, and the
6300
+ * states it carries.
6301
+ *
6302
+ * @remarks
6303
+ * After the name the row appends `value="V"` when the node carries a non-empty value,
6304
+ * `pressed=true|false|mixed`, `expanded=true|false`, and `selected=true|false` when present,
6305
+ * `[checked]` when checked, `[disabled]` when disabled, and `[tool=NAME]` for a page tool's form,
6306
+ * in that order. A node without a reference renders without one.
6307
+ *
6308
+ * @param node - The outline node
6309
+ * @returns The rendered row
6310
+ *
6311
+ * @example
6312
+ * ```ts
6313
+ * import { renderBrowserOutlineRow } from '@orkestrel/browser'
6314
+ *
6315
+ * renderBrowserOutlineRow({
6316
+ * id: '4',
6317
+ * parent: undefined,
6318
+ * children: [],
6319
+ * backend: undefined,
6320
+ * frame: undefined,
6321
+ * ignored: false,
6322
+ * role: 'checkbox',
6323
+ * name: ' Gift wrap ',
6324
+ * description: undefined,
6325
+ * value: undefined,
6326
+ * properties: { checked: 'true' },
6327
+ * session: 'main',
6328
+ * reference: 'e4',
6329
+ * }) // 'e4 checkbox "Gift wrap" [checked]'
6330
+ * ```
6110
6331
  */
6111
- export declare function renderBrowserOutline(url: string, title: string, nodes: readonly BrowserOutlineNode[], limit: number): BrowserOutline;
6332
+ export declare function renderBrowserOutlineRow(node: BrowserOutlineNode): string;
6112
6333
 
6113
6334
  /**
6114
6335
  * Renders a tool receipt: the action and its status on one line, the interrupting dialog, then
@@ -6194,6 +6415,61 @@ export declare interface BrowserRunStoreInterface {
6194
6415
  */
6195
6416
  export declare function resolveBrowserJourneyBinding(value: unknown, inputs: Readonly<Record<string, string>>): string;
6196
6417
 
6418
+ /**
6419
+ * Returns the referenced outline nodes whose role and accessible name share the most words with a
6420
+ * search, in document order.
6421
+ *
6422
+ * @remarks
6423
+ * The search and each node's role and name are lowercased and split into whole words by
6424
+ * `BROWSER_SEARCH_PATTERN`, so a word shorter than 3 letters or digits never counts, and words
6425
+ * compare whole, with no substring or prefix match. A node scores the number of distinct search
6426
+ * words equal to one of its words, and every node with the highest score above 0 matches. Only a
6427
+ * node an outline renders as a referenced row takes part: one that is not ignored, carries a
6428
+ * reference, and whose role is not omitted, a heading, or text.
6429
+ *
6430
+ * @param nodes - Ordered accessibility rows
6431
+ * @param search - The words to match
6432
+ * @returns The best-matching nodes in document order; empty when no node shares a word
6433
+ *
6434
+ * @example
6435
+ * ```ts
6436
+ * import { scanBrowserOutline } from '@orkestrel/browser'
6437
+ *
6438
+ * const node = {
6439
+ * parent: undefined,
6440
+ * children: [],
6441
+ * backend: undefined,
6442
+ * frame: undefined,
6443
+ * ignored: false,
6444
+ * description: undefined,
6445
+ * value: undefined,
6446
+ * properties: {},
6447
+ * session: 'main',
6448
+ * }
6449
+ * const nodes = [
6450
+ * { ...node, id: '1', role: 'button', name: 'Close', reference: 'e1' },
6451
+ * { ...node, id: '2', role: 'button', name: 'Archive', reference: 'e2' },
6452
+ * ]
6453
+ * scanBrowserOutline(nodes, 'archive dialog button').map((match) => match.reference) // ['e2']
6454
+ * ```
6455
+ */
6456
+ export declare function scanBrowserOutline(nodes: readonly BrowserOutlineNode[], search: string): readonly BrowserOutlineNode[];
6457
+
6458
+ /**
6459
+ * Matches the lines sharing the most distinct search words, in document order.
6460
+ *
6461
+ * @param text - The complete projection
6462
+ * @param search - Words to match, using the outline's word rule
6463
+ * @returns The best-scoring lines and their original UTF-16 offsets; empty without a shared word
6464
+ *
6465
+ * @example
6466
+ * ```ts
6467
+ * import { scanBrowserText } from '@orkestrel/browser'
6468
+ * scanBrowserText('Cart\nBlue kettle', 'kettle') // [{ offset: 5, text: 'Blue kettle' }]
6469
+ * ```
6470
+ */
6471
+ export declare function scanBrowserText(text: string, search: string): readonly BrowserReadMatch[];
6472
+
6197
6473
  /**
6198
6474
  * Awaits every teardown step in order and returns the first failure.
6199
6475
  *
@@ -6357,8 +6633,8 @@ export declare interface BrowserRunStoreInterface {
6357
6633
  * ```ts
6358
6634
  * import { BROWSER_TOOL_COPY, validateBrowserToolArguments } from '@orkestrel/browser'
6359
6635
  *
6360
- * validateBrowserToolArguments(BROWSER_TOOL_COPY.look, { what: 'cart', ref: 'e1' })
6361
- * // throws 'The look tool takes no ref parameter; call look with what.'
6636
+ * validateBrowserToolArguments(BROWSER_TOOL_COPY.look, { search: 'cart', ref: 'e1' })
6637
+ * // throws 'The look tool takes no ref parameter; call look with search and offset.'
6362
6638
  * ```
6363
6639
  */
6364
6640
  export declare function validateBrowserToolArguments(definition: ToolDefinition, args: Readonly<Record<string, unknown>>): void;