dsh-browser-plus 0.0.0-stage → 0.5.1
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/CHANGELOG.md +153 -0
- package/LICENSE +22 -0
- package/NOTICE.md +7 -0
- package/README.en.md +119 -0
- package/README.md +118 -2
- package/assets/dsh-browser-plus-256.png +0 -0
- package/assets/dsh-browser-plus-512.png +0 -0
- package/assets/dsh-browser-plus-small.svg +9 -0
- package/assets/dsh-browser-plus.ico +0 -0
- package/assets/dsh-browser-plus.svg +11 -0
- package/assets/readme-workspace.png +0 -0
- package/client/index.js +185 -0
- package/cordis.patch.yml +41 -0
- package/docs/MIGRATION.md +48 -0
- package/docs/README.md +22 -0
- package/docs/SOAK-CHECKLIST.md +98 -0
- package/docs/architecture.md +88 -0
- package/docs/tool-reference.md +126 -0
- package/docs/user-guide.md +137 -0
- package/docs/why-browser.md +45 -0
- package/lib/browser/runtime.d.ts +238 -0
- package/lib/browser/runtime.js +330 -0
- package/lib/browser/types.d.ts +758 -0
- package/lib/browser/types.js +18 -0
- package/lib/browser-electron/auth-cookies.d.ts +54 -0
- package/lib/browser-electron/auth-cookies.js +83 -0
- package/lib/browser-electron/chrome-state.d.ts +211 -0
- package/lib/browser-electron/chrome-state.js +12 -0
- package/lib/browser-electron/entry.d.ts +73 -0
- package/lib/browser-electron/entry.js +65 -0
- package/lib/browser-electron/fingerprint.d.ts +29 -0
- package/lib/browser-electron/fingerprint.js +42 -0
- package/lib/browser-electron/host-main.d.ts +19 -0
- package/lib/browser-electron/host-main.js +2691 -0
- package/lib/browser-electron/icon.d.ts +11 -0
- package/lib/browser-electron/icon.js +23 -0
- package/lib/browser-electron/page-chrome.d.ts +21 -0
- package/lib/browser-electron/page-chrome.js +2269 -0
- package/lib/browser-electron/provider.d.ts +767 -0
- package/lib/browser-electron/provider.js +2825 -0
- package/lib/browser-electron/remote-host.d.ts +145 -0
- package/lib/browser-electron/remote-host.js +993 -0
- package/lib/browser-electron/task-summary.d.ts +2 -0
- package/lib/browser-electron/task-summary.js +12 -0
- package/lib/browser-electron/task-thumbnail.d.ts +11 -0
- package/lib/browser-electron/task-thumbnail.js +9 -0
- package/lib/browser-electron/write-guard.d.ts +41 -0
- package/lib/browser-electron/write-guard.js +123 -0
- package/lib/client.js +185 -0
- package/lib/command-browser/index.d.ts +20 -0
- package/lib/command-browser/index.js +35 -0
- package/lib/http-browser/index.d.ts +28 -0
- package/lib/http-browser/index.js +110 -0
- package/lib/index.d.ts +27 -0
- package/lib/index.js +25 -0
- package/lib/task-todos/index.d.ts +25 -0
- package/lib/task-todos/index.js +100 -0
- package/lib/tool-browser/index.d.ts +31 -0
- package/lib/tool-browser/index.js +2026 -0
- package/package.json +120 -4
- package/screenshots.json +3 -0
- package/scripts/build-client.mjs +20 -0
- package/scripts/build-icons.mjs +80 -0
- package/scripts/capture-window.ps1 +79 -0
- package/scripts/crop-image.ps1 +20 -0
- package/scripts/smoke-browser-tools.mjs +2051 -0
- package/scripts/smoke-chrome-world.mjs +65 -0
- package/scripts/smoke-electron-host.mjs +50 -0
- package/scripts/test-orb-drag.mjs +83 -0
- package/src/browser/runtime.ts +506 -0
- package/src/browser/types.ts +741 -0
- package/src/browser-electron/auth-cookies.ts +125 -0
- package/src/browser-electron/chrome-state.ts +192 -0
- package/src/browser-electron/entry.ts +125 -0
- package/src/browser-electron/fingerprint.ts +45 -0
- package/src/browser-electron/host-main.ts +2526 -0
- package/src/browser-electron/icon.ts +26 -0
- package/src/browser-electron/page-chrome.ts +2281 -0
- package/src/browser-electron/provider.ts +3366 -0
- package/src/browser-electron/remote-host.ts +1051 -0
- package/src/browser-electron/task-summary.ts +10 -0
- package/src/browser-electron/task-thumbnail.ts +17 -0
- package/src/browser-electron/write-guard.ts +134 -0
- package/src/command-browser/index.ts +61 -0
- package/src/http-browser/index.ts +139 -0
- package/src/index.ts +65 -0
- package/src/task-todos/index.ts +114 -0
- package/src/tool-browser/index.ts +2071 -0
- package/src/types/electron-shim.d.ts +143 -0
|
@@ -0,0 +1,758 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vocabulary for the browser capability seam (`ctx.browser`). One seam owns
|
|
3
|
+
* provider registration, session lifecycle, cancellation, errors, and product
|
|
4
|
+
* configuration; providers differ only in what backs a session (an Electron
|
|
5
|
+
* `WebContentsView` in the desktop shell, a headless Chromium relay for
|
|
6
|
+
* remote deployments, and so on).
|
|
7
|
+
* @module dsh-browser-plus/browser/types
|
|
8
|
+
*/
|
|
9
|
+
import { HarnessError } from '@deepseek-ai/dsh-llm';
|
|
10
|
+
/**
|
|
11
|
+
* Stable identity of one browser session, resolved by the Host through a
|
|
12
|
+
* Typert `LookupMap` to the live session object (the same mechanism
|
|
13
|
+
* `Agent → agentId` uses). The id is opaque to the wire; only the provider
|
|
14
|
+
* and its host binding can interpret it.
|
|
15
|
+
*/
|
|
16
|
+
export type BrowserSessionId = string;
|
|
17
|
+
/**
|
|
18
|
+
* What one browser-capable backend is asked to do. Navigation is the minimal
|
|
19
|
+
* operation every provider shares; the seam deliberately keeps the request
|
|
20
|
+
* minimal so a provider swap never changes how the model asks.
|
|
21
|
+
*/
|
|
22
|
+
export interface BrowserNavigateRequest {
|
|
23
|
+
/** The URL to open. Admission (HTTP(S) only, no credentials/private targets) is provider-owned. */
|
|
24
|
+
readonly url: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Click at viewport coordinates. Coordinates are viewport-relative pixels in
|
|
28
|
+
* the session's own coordinate space — the same space the human interacts
|
|
29
|
+
* with, so a real view and a relay agree without scaling.
|
|
30
|
+
*/
|
|
31
|
+
/** Type text into the focused element. */
|
|
32
|
+
export interface BrowserTypeRequest {
|
|
33
|
+
/** The text to insert. */
|
|
34
|
+
readonly text: string;
|
|
35
|
+
}
|
|
36
|
+
/** Key press into the page, as one keyDown+keyUp pair. */
|
|
37
|
+
export interface BrowserPressKeyRequest {
|
|
38
|
+
/** The key to press: a single character ('a', '1'), an Enter/Tab/Escape,
|
|
39
|
+
* navigation key (ArrowUp/ArrowDown/…), Home/End/PageUp/PageDown,
|
|
40
|
+
* Backspace/Delete, or F1..F12. */
|
|
41
|
+
readonly key: string;
|
|
42
|
+
/** Modifier keys held during the press. */
|
|
43
|
+
readonly modifiers?: readonly ('alt' | 'ctrl' | 'meta' | 'shift')[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* How a pointer action addresses its target.
|
|
47
|
+
*
|
|
48
|
+
* Coordinates are used as given. A selector or text is resolved inside the page
|
|
49
|
+
* and scrolled into view first, so an agent can act on "the sign-in button"
|
|
50
|
+
* without spending a snapshot round-trip to learn its ref — the same way
|
|
51
|
+
* browser_fill already addresses its fields.
|
|
52
|
+
*/
|
|
53
|
+
export interface BrowserPointerTarget {
|
|
54
|
+
/** Viewport-relative x in CSS pixels; required with y when neither selector nor text is given. */
|
|
55
|
+
readonly x?: number;
|
|
56
|
+
/** Viewport-relative y in CSS pixels. */
|
|
57
|
+
readonly y?: number;
|
|
58
|
+
/** CSS selector; the first visible match is used. */
|
|
59
|
+
readonly selector?: string;
|
|
60
|
+
/** Visible text, aria-label or value to match (case-insensitive); the innermost visible match wins. */
|
|
61
|
+
readonly text?: string;
|
|
62
|
+
/** Mouse button. Default left; right opens the page's own context menu. */
|
|
63
|
+
readonly button?: 'left' | 'right' | 'middle';
|
|
64
|
+
/** Modifiers held during the action: ctrl-click opens a link in a new tab, shift extends a selection. */
|
|
65
|
+
readonly modifiers?: readonly ('alt' | 'ctrl' | 'meta' | 'shift')[];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* A press-drag-release gesture from one target to another. Both ends use the
|
|
69
|
+
* same addressing as a click, so a drag can go from "the slider thumb" to a
|
|
70
|
+
* coordinate, or between two selectors.
|
|
71
|
+
*/
|
|
72
|
+
export interface BrowserDragRequest {
|
|
73
|
+
/** Where the gesture starts. */
|
|
74
|
+
readonly from: BrowserPointerTarget;
|
|
75
|
+
/** Where it ends. */
|
|
76
|
+
readonly to: BrowserPointerTarget;
|
|
77
|
+
/** Intermediate move events. More steps look more like a hand; default 12, max 60. */
|
|
78
|
+
readonly steps?: number;
|
|
79
|
+
}
|
|
80
|
+
/** Where a drag started and ended. */
|
|
81
|
+
export interface BrowserDragResult {
|
|
82
|
+
readonly from: BrowserPointerResult;
|
|
83
|
+
readonly to: BrowserPointerResult;
|
|
84
|
+
}
|
|
85
|
+
/** Where a pointer action actually landed. */
|
|
86
|
+
export interface BrowserPointerResult {
|
|
87
|
+
readonly x: number;
|
|
88
|
+
readonly y: number;
|
|
89
|
+
/** Short description of the element that was resolved; absent for a coordinate target. */
|
|
90
|
+
readonly target?: string;
|
|
91
|
+
}
|
|
92
|
+
/** Scroll the active page by a CSS-pixel delta. */
|
|
93
|
+
export interface BrowserScrollRequest {
|
|
94
|
+
/** Horizontal delta in CSS pixels. Default 0. */
|
|
95
|
+
readonly deltaX?: number;
|
|
96
|
+
/** Vertical delta in CSS pixels. Default one viewport height downward. */
|
|
97
|
+
readonly deltaY?: number;
|
|
98
|
+
}
|
|
99
|
+
/** Final page scroll position after a scroll operation. */
|
|
100
|
+
export interface BrowserScrollResult {
|
|
101
|
+
/** Horizontal scroll offset in CSS pixels. */
|
|
102
|
+
readonly x: number;
|
|
103
|
+
/** Vertical scroll offset in CSS pixels. */
|
|
104
|
+
readonly y: number;
|
|
105
|
+
/** Maximum horizontal scroll offset in CSS pixels. */
|
|
106
|
+
readonly maxX: number;
|
|
107
|
+
/** Maximum vertical scroll offset in CSS pixels. */
|
|
108
|
+
readonly maxY: number;
|
|
109
|
+
}
|
|
110
|
+
/** One element reference from a specific browser snapshot. */
|
|
111
|
+
export interface BrowserRefRequest {
|
|
112
|
+
/** Opaque id returned by browser_open or browser_snapshot. */
|
|
113
|
+
readonly snapshotId: string;
|
|
114
|
+
/** Element reference number from that snapshot. */
|
|
115
|
+
readonly ref: number;
|
|
116
|
+
}
|
|
117
|
+
/** Scroll one referenced element into the visible viewport. */
|
|
118
|
+
export interface BrowserScrollIntoViewRequest extends BrowserRefRequest {
|
|
119
|
+
/** Vertical alignment for the referenced element. Default center. */
|
|
120
|
+
readonly block?: 'start' | 'center' | 'end' | 'nearest';
|
|
121
|
+
}
|
|
122
|
+
/** Set a file input's value from a local path. */
|
|
123
|
+
export interface BrowserUploadFileRequest {
|
|
124
|
+
/** Absolute path of the file to attach. */
|
|
125
|
+
readonly filePath: string;
|
|
126
|
+
/** CSS selector of the file input; defaults to the first input[type="file"]. */
|
|
127
|
+
readonly selector?: string;
|
|
128
|
+
}
|
|
129
|
+
/** Outcome of a file upload. */
|
|
130
|
+
export interface BrowserUploadFileResult {
|
|
131
|
+
/** The path uploaded. */
|
|
132
|
+
readonly path: string;
|
|
133
|
+
}
|
|
134
|
+
/** Which state a wait is watching for. */
|
|
135
|
+
export type BrowserWaitForState = 'visible' | 'attached' | 'hidden' | 'detached';
|
|
136
|
+
/** Wait for a selector, some text, or both to reach a state. */
|
|
137
|
+
export interface BrowserWaitForRequest {
|
|
138
|
+
/** CSS selector to wait for. Omit to watch the document's own text (give `text`). */
|
|
139
|
+
readonly selector?: string;
|
|
140
|
+
/** Text that must be present: inside the matched element when a selector is given, otherwise anywhere in the document. */
|
|
141
|
+
readonly text?: string;
|
|
142
|
+
/**
|
|
143
|
+
* The state to wait for. `visible` (the default) needs a matching element at least 4x4 px and not
|
|
144
|
+
* visibility:hidden / display:none; `attached` only needs it to exist; `hidden` and `detached`
|
|
145
|
+
* wait for the opposite, so they are how you wait for something to go away.
|
|
146
|
+
*/
|
|
147
|
+
readonly state?: BrowserWaitForState;
|
|
148
|
+
/** Total budget in ms. Default 15000. */
|
|
149
|
+
readonly timeoutMs?: number;
|
|
150
|
+
/** Back-compat for `state: 'attached'` (`visible: false`). Prefer `state`. */
|
|
151
|
+
readonly visible?: boolean;
|
|
152
|
+
}
|
|
153
|
+
/** Outcome of a successful wait. */
|
|
154
|
+
export interface BrowserWaitForResult {
|
|
155
|
+
/** The awaited condition is now true. */
|
|
156
|
+
readonly found: true;
|
|
157
|
+
/** Which state was awaited. */
|
|
158
|
+
readonly state: BrowserWaitForState;
|
|
159
|
+
/** The selector waited on, or `''` for a text-only wait. */
|
|
160
|
+
readonly selector: string;
|
|
161
|
+
/** Matched element's tag name, or `''` when nothing matched (a `detached` wait). */
|
|
162
|
+
readonly tag: string;
|
|
163
|
+
/** Matched element's visible text (first 200 chars), or the document text that satisfied a text wait. */
|
|
164
|
+
readonly text: string;
|
|
165
|
+
}
|
|
166
|
+
/** Print the active tab to a PDF file. */
|
|
167
|
+
export interface BrowserPdfRequest {
|
|
168
|
+
/** Absolute path of the .pdf to write. Must be inside the write roots. */
|
|
169
|
+
readonly savePath: string;
|
|
170
|
+
/** Landscape orientation. Default portrait. */
|
|
171
|
+
readonly landscape?: boolean;
|
|
172
|
+
/** Include background colours and images. Default true. */
|
|
173
|
+
readonly printBackground?: boolean;
|
|
174
|
+
/** Paper width in inches. CDP default is 8.5. */
|
|
175
|
+
readonly paperWidth?: number;
|
|
176
|
+
/** Paper height in inches. CDP default is 11. */
|
|
177
|
+
readonly paperHeight?: number;
|
|
178
|
+
}
|
|
179
|
+
/** Where the PDF landed. */
|
|
180
|
+
export interface BrowserPdfResult {
|
|
181
|
+
readonly path: string;
|
|
182
|
+
readonly bytes: number;
|
|
183
|
+
}
|
|
184
|
+
/** Draw or clear the DevTools-style highlight box over a selector's first match. */
|
|
185
|
+
export interface BrowserHighlightRequest {
|
|
186
|
+
/** CSS selector whose first match to highlight. Ignored when clear is true. */
|
|
187
|
+
readonly selector?: string;
|
|
188
|
+
/** Remove any existing highlight instead of drawing one. */
|
|
189
|
+
readonly clear?: boolean;
|
|
190
|
+
}
|
|
191
|
+
/** What the highlight call found. */
|
|
192
|
+
export interface BrowserHighlightResult {
|
|
193
|
+
/** A match was found and highlighted. */
|
|
194
|
+
readonly matched: boolean;
|
|
195
|
+
/** The highlight was cleared. */
|
|
196
|
+
readonly cleared: boolean;
|
|
197
|
+
/** CDP node id of the match, when there was one. */
|
|
198
|
+
readonly nodeId?: number;
|
|
199
|
+
/** Content box in CSS pixels, when the element has one. */
|
|
200
|
+
readonly box?: {
|
|
201
|
+
readonly x: number;
|
|
202
|
+
readonly y: number;
|
|
203
|
+
readonly width: number;
|
|
204
|
+
readonly height: number;
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/** One field of a batch form fill. Match by selector, or by name/label/placeholder. */
|
|
208
|
+
export interface BrowserFillField {
|
|
209
|
+
/** CSS selector; when present, candidates are scoped to it. */
|
|
210
|
+
readonly selector?: string;
|
|
211
|
+
/** Match by the field's `name` attribute. */
|
|
212
|
+
readonly name?: string;
|
|
213
|
+
/** Match by associated `<label>` text or `aria-label`. */
|
|
214
|
+
readonly label?: string;
|
|
215
|
+
/** Match by `placeholder` text. */
|
|
216
|
+
readonly placeholder?: string;
|
|
217
|
+
/** Field kind; defaults to text. */
|
|
218
|
+
readonly kind?: 'text' | 'textarea' | 'checkbox' | 'radio' | 'select';
|
|
219
|
+
/** Value to set: string, number, or boolean (checkbox/radio). For a
|
|
220
|
+
* multi-select or radio group, the option value (or visible text). */
|
|
221
|
+
readonly value: string | number | boolean;
|
|
222
|
+
}
|
|
223
|
+
/** Batch form fill: set several fields, optionally submitting the form. */
|
|
224
|
+
export interface BrowserFillRequest {
|
|
225
|
+
/** The fields to fill, in order. */
|
|
226
|
+
readonly fields: readonly BrowserFillField[];
|
|
227
|
+
/** Submit the containing form after filling. Default false. */
|
|
228
|
+
readonly submit?: boolean;
|
|
229
|
+
/** Total evaluation budget for the whole batch in ms. Default 30000. */
|
|
230
|
+
readonly timeoutMs?: number;
|
|
231
|
+
}
|
|
232
|
+
/** One field's outcome in a batch fill. */
|
|
233
|
+
export interface BrowserFillFieldResult {
|
|
234
|
+
readonly ok: boolean;
|
|
235
|
+
/** The field description matched (selector/name/label/placeholder). */
|
|
236
|
+
readonly target: string;
|
|
237
|
+
/** How the value was applied: input | textarea | select | checkbox | radio | contenteditable. */
|
|
238
|
+
readonly method?: string;
|
|
239
|
+
/** Error text when the field could not be filled. */
|
|
240
|
+
readonly error?: string;
|
|
241
|
+
}
|
|
242
|
+
/** Outcome of a batch form fill. */
|
|
243
|
+
export interface BrowserFillResult {
|
|
244
|
+
/** Per-field outcomes, in request order. */
|
|
245
|
+
readonly fields: readonly BrowserFillFieldResult[];
|
|
246
|
+
/** Whether the containing form was submitted. */
|
|
247
|
+
readonly submitted: boolean;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* A screenshot of the current page state. `dataUrl` is a base64 data URL the
|
|
251
|
+
* tool layer renders directly; the live view itself never crosses the wire
|
|
252
|
+
* (the human watches the real view in the desktop shape).
|
|
253
|
+
*/
|
|
254
|
+
export interface BrowserScreenshotResult {
|
|
255
|
+
/** Base64 PNG data URL of the capture. */
|
|
256
|
+
readonly dataUrl: string;
|
|
257
|
+
/** File path the capture was also saved to, when the request asked for it. */
|
|
258
|
+
readonly path?: string;
|
|
259
|
+
}
|
|
260
|
+
/** Screenshot capture options. PNG only (CDP JPEG hangs on Electron 43). */
|
|
261
|
+
export interface BrowserScreenshotRequest {
|
|
262
|
+
/** Capture the full scrollable page instead of the viewport. Default false. */
|
|
263
|
+
readonly fullPage?: boolean;
|
|
264
|
+
/** Absolute file path to also save the PNG to (for vision-tool reads). */
|
|
265
|
+
readonly savePath?: string;
|
|
266
|
+
}
|
|
267
|
+
/** Download options: fetch a URL into a local file, keeping the session's cookies. */
|
|
268
|
+
export interface BrowserDownloadRequest {
|
|
269
|
+
/** The URL to download. */
|
|
270
|
+
readonly url: string;
|
|
271
|
+
/** Absolute path of the file to write. */
|
|
272
|
+
readonly savePath: string;
|
|
273
|
+
}
|
|
274
|
+
/** A serializable cookie, exported from or imported into the browser session. */
|
|
275
|
+
export interface ExportedCookie {
|
|
276
|
+
/** Cookie URL (scheme + domain + path), as accepted by cookies.set. */
|
|
277
|
+
readonly url: string;
|
|
278
|
+
readonly name: string;
|
|
279
|
+
readonly value: string;
|
|
280
|
+
readonly domain?: string;
|
|
281
|
+
readonly path?: string;
|
|
282
|
+
readonly secure?: boolean;
|
|
283
|
+
readonly httpOnly?: boolean;
|
|
284
|
+
readonly expirationDate?: number;
|
|
285
|
+
/** SameSite policy in Chromium's spelling; both spellings are accepted on import. */
|
|
286
|
+
readonly sameSite?: 'no_restriction' | 'lax' | 'strict' | 'unspecified';
|
|
287
|
+
}
|
|
288
|
+
/** Which cookies a clear request removes: a domain scope, one name, or an explicit wipe. */
|
|
289
|
+
export interface BrowserClearAuthRequest {
|
|
290
|
+
/** Domain scope; matches that domain and every subdomain. */
|
|
291
|
+
readonly domain?: string;
|
|
292
|
+
/** Exact cookie name to remove within the scope. */
|
|
293
|
+
readonly name?: string;
|
|
294
|
+
/** Remove every addressable cookie; requires this explicit opt-in. */
|
|
295
|
+
readonly all?: boolean;
|
|
296
|
+
}
|
|
297
|
+
/** Outcome of a cookie clear: how many went and which names. */
|
|
298
|
+
export interface BrowserClearAuthResult {
|
|
299
|
+
readonly removed: number;
|
|
300
|
+
readonly names: readonly string[];
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Execute arbitrary JavaScript in the session's page context. This is the
|
|
304
|
+
* primary interaction path — DOM-referenced, not screen-coordinate-based:
|
|
305
|
+
* focus/input/click go through the page's own JS (native setters for
|
|
306
|
+
* framework-controlled inputs), matching how a human-driven agent operates.
|
|
307
|
+
*/
|
|
308
|
+
export interface BrowserExecuteRequest {
|
|
309
|
+
/** The JavaScript expression to evaluate in the page context. */
|
|
310
|
+
readonly script: string;
|
|
311
|
+
/** Optional arguments injected into the script scope as `arguments[0..n]`. */
|
|
312
|
+
readonly args?: readonly unknown[];
|
|
313
|
+
/** Evaluation budget in ms; a wedged page rejects with a timeout. Default 30000. */
|
|
314
|
+
readonly timeoutMs?: number;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Result of an execute. Mirrors CDP `Runtime.evaluate` semantics: either a
|
|
318
|
+
* value (by value, not by reference) or the exception thrown.
|
|
319
|
+
*/
|
|
320
|
+
export type BrowserExecuteResult = {
|
|
321
|
+
readonly ok: true;
|
|
322
|
+
readonly value: unknown;
|
|
323
|
+
} | {
|
|
324
|
+
readonly ok: false;
|
|
325
|
+
readonly exception: string;
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* A background scrape batch. The point is that results never travel back
|
|
329
|
+
* through the model: each page appends one JSON line to `outPath`, so a batch
|
|
330
|
+
* of thousands costs the same number of tokens as a batch of one.
|
|
331
|
+
*/
|
|
332
|
+
export interface BrowserScrapeRequest {
|
|
333
|
+
/** URLs to visit, in order. */
|
|
334
|
+
readonly urls: readonly string[];
|
|
335
|
+
/**
|
|
336
|
+
* Expression evaluated on each page once it is ready. Its JSON value becomes
|
|
337
|
+
* the record's `data`; an async IIFE is fine, the evaluation awaits promises.
|
|
338
|
+
*/
|
|
339
|
+
readonly script: string;
|
|
340
|
+
/** JSONL destination; must resolve inside the browser-electron write roots. */
|
|
341
|
+
readonly outPath: string;
|
|
342
|
+
/** Optional CSS selector awaited on each page before the script runs. */
|
|
343
|
+
readonly waitFor?: string;
|
|
344
|
+
/** Per-URL budget in ms for the wait and the extraction. Default 30000. */
|
|
345
|
+
readonly timeoutMs?: number;
|
|
346
|
+
/**
|
|
347
|
+
* How many pages to load at once. Default 1, which writes rows in URL order.
|
|
348
|
+
* Each worker owns a tab of its own, so a higher value costs that many tabs;
|
|
349
|
+
* every row carries its URL's index as `seq` so the caller can restore order.
|
|
350
|
+
*/
|
|
351
|
+
readonly concurrency?: number;
|
|
352
|
+
}
|
|
353
|
+
/** Progress of one scrape batch. The rows themselves live in the file. */
|
|
354
|
+
export interface BrowserScrapeStatus {
|
|
355
|
+
readonly id: string;
|
|
356
|
+
/** `stopped` means it was asked to stop; rows already written are kept. */
|
|
357
|
+
readonly state: 'running' | 'done' | 'stopped';
|
|
358
|
+
readonly total: number;
|
|
359
|
+
readonly done: number;
|
|
360
|
+
/** Pages whose navigation or extraction failed; they still get a row. */
|
|
361
|
+
readonly failed: number;
|
|
362
|
+
readonly path: string;
|
|
363
|
+
/** Set when the whole batch aborted for a reason other than a page error. */
|
|
364
|
+
readonly error?: string;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* One interactive element in a snapshot, with a stable reference number the
|
|
368
|
+
* tool layer (and the model) can cite to target the element.
|
|
369
|
+
*/
|
|
370
|
+
export interface BrowserSnapshotElement {
|
|
371
|
+
/** 1-based reference number, stable for the lifetime of one snapshot. */
|
|
372
|
+
readonly ref: number;
|
|
373
|
+
/** Element kind: 'input' | 'button' | 'link' | 'textarea' | 'select' | 'checkbox' | 'other'. */
|
|
374
|
+
readonly kind: string;
|
|
375
|
+
/** Text content or placeholder/label, truncated for the snapshot. */
|
|
376
|
+
readonly label: string;
|
|
377
|
+
/** Best-effort CSS selector; may be empty when none is derivable. */
|
|
378
|
+
readonly selector: string;
|
|
379
|
+
/** Best-effort locator for re-targeting (id/name/aria-label/text). */
|
|
380
|
+
readonly loc: string;
|
|
381
|
+
/** Viewport-relative center, for coordinate fallbacks. */
|
|
382
|
+
readonly x: number;
|
|
383
|
+
readonly y: number;
|
|
384
|
+
/** Index into `frames` when the element lives inside an iframe; absent at the top level. */
|
|
385
|
+
readonly frame?: number;
|
|
386
|
+
}
|
|
387
|
+
/** One iframe found on the page. */
|
|
388
|
+
export interface BrowserSnapshotFrame {
|
|
389
|
+
/** Index into the page's iframe list; matches `BrowserSnapshotElement.frame`. */
|
|
390
|
+
readonly index: number;
|
|
391
|
+
/** The frame's src, or its document URL when it has one. */
|
|
392
|
+
readonly url: string;
|
|
393
|
+
/** False when the frame is cross-origin, so its contents cannot be read. */
|
|
394
|
+
readonly readable: boolean;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* AI-friendly page snapshot: a compact, numbered inventory of interactive
|
|
398
|
+
* elements plus page facts. Not raw HTML — the model dialogues with this.
|
|
399
|
+
*/
|
|
400
|
+
export interface BrowserSnapshotResult {
|
|
401
|
+
/** Opaque id that binds the element references to this exact page snapshot. */
|
|
402
|
+
readonly snapshotId: string;
|
|
403
|
+
/** Final page URL. */
|
|
404
|
+
readonly url: string;
|
|
405
|
+
/** Page title, if any. */
|
|
406
|
+
readonly title?: string;
|
|
407
|
+
/** Numbered interactive elements. */
|
|
408
|
+
readonly elements: readonly BrowserSnapshotElement[];
|
|
409
|
+
/** True when the snapshot was truncated (element cap reached). */
|
|
410
|
+
readonly truncated: boolean;
|
|
411
|
+
/** Every iframe on the page, including the cross-origin ones that could not be read. */
|
|
412
|
+
readonly frames?: readonly BrowserSnapshotFrame[];
|
|
413
|
+
/** Human-verification challenge blocking the page, when one is detected. */
|
|
414
|
+
readonly challenge?: BrowserChallenge;
|
|
415
|
+
/** True when a human interacted with the page within the last minute. */
|
|
416
|
+
readonly userControlling?: boolean;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* A detected human-verification (bot-detection / CAPTCHA) challenge blocking
|
|
420
|
+
* the page. Detection is best-effort and marker-based; a clean result is not a
|
|
421
|
+
* guarantee that no challenge exists.
|
|
422
|
+
*/
|
|
423
|
+
export interface BrowserChallenge {
|
|
424
|
+
/** Whether a challenge currently blocks the page. */
|
|
425
|
+
readonly blocked: boolean;
|
|
426
|
+
/** Machine-readable kind: cloudflare | hcaptcha | recaptcha | turnstile | generic. */
|
|
427
|
+
readonly kind?: string;
|
|
428
|
+
/** Short human-readable description, e.g. 'Cloudflare "Just a moment" interstitial'. */
|
|
429
|
+
readonly reason?: string;
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Content fetch formats. `html` is the raw DOM; `markdown` is a structured
|
|
433
|
+
* reading view; `txt` is plain text (smallest); `json` is structured data.
|
|
434
|
+
*/
|
|
435
|
+
export type BrowserContentFormat = 'html' | 'markdown' | 'txt' | 'json';
|
|
436
|
+
/** Content fetch request: format, optional selector scoping, and caps. */
|
|
437
|
+
export interface BrowserContentRequest {
|
|
438
|
+
/** Desired format. */
|
|
439
|
+
readonly format: BrowserContentFormat;
|
|
440
|
+
/** Optional CSS selector limiting the fetch to one region (e.g. `#main`). */
|
|
441
|
+
readonly selector?: string;
|
|
442
|
+
/** Maximum characters of the returned content. */
|
|
443
|
+
readonly maxChars?: number;
|
|
444
|
+
/** Evaluation timeout in ms; the fetch aborts after this. Default 30000. */
|
|
445
|
+
readonly timeoutMs?: number;
|
|
446
|
+
}
|
|
447
|
+
/** A fetched page content in the requested format. */
|
|
448
|
+
export interface BrowserContentResult {
|
|
449
|
+
/** The content in the requested format, capped at `maxChars`. */
|
|
450
|
+
readonly content: string;
|
|
451
|
+
/** True when the content was truncated. */
|
|
452
|
+
readonly truncated: boolean;
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* A tab inside a browser session. Tabs share the session's profile/cookies
|
|
456
|
+
* and are switchable without losing state.
|
|
457
|
+
*/
|
|
458
|
+
export interface BrowserTab {
|
|
459
|
+
/** Stable tab id within the session. */
|
|
460
|
+
readonly id: string;
|
|
461
|
+
/** Current URL, or empty for a blank tab. */
|
|
462
|
+
readonly url: string;
|
|
463
|
+
/** Page title, if any. */
|
|
464
|
+
readonly title?: string;
|
|
465
|
+
/** Whether this tab is the active one. */
|
|
466
|
+
readonly active: boolean;
|
|
467
|
+
}
|
|
468
|
+
/** Request to open a URL: into the active tab or a new tab. */
|
|
469
|
+
export interface BrowserOpenRequest {
|
|
470
|
+
/** The URL to open. */
|
|
471
|
+
readonly url: string;
|
|
472
|
+
/** Open in a new tab (parallel). Default false (reuse the active tab). */
|
|
473
|
+
readonly newTab?: boolean;
|
|
474
|
+
}
|
|
475
|
+
/** Options for opening or recovering a browser task session. */
|
|
476
|
+
export interface BrowserOpenOptions {
|
|
477
|
+
/** Stable browser-task key; keyed providers may recover the existing session for this task. */
|
|
478
|
+
readonly key?: string;
|
|
479
|
+
/** Optional display name shown in the task manager and active window title. */
|
|
480
|
+
readonly label?: string;
|
|
481
|
+
}
|
|
482
|
+
/** One browser task represented in the shared visible window. */
|
|
483
|
+
export interface BrowserSpaceInfo {
|
|
484
|
+
/** Stable browser-task key. */
|
|
485
|
+
readonly key: string;
|
|
486
|
+
/** Task display label, or '' for unlabeled. */
|
|
487
|
+
readonly label: string;
|
|
488
|
+
}
|
|
489
|
+
/** Visible activity state for a browser task. */
|
|
490
|
+
export type BrowserTaskStatus = 'idle' | 'running' | 'waiting-user' | 'failed';
|
|
491
|
+
/** Which collaborator currently owns page-changing actions. */
|
|
492
|
+
export type BrowserControlOwner = 'agent' | 'human';
|
|
493
|
+
/** Intentional Agent-to-human handoff mode. */
|
|
494
|
+
export type BrowserHandoffState = 'waiting-user' | 'agent';
|
|
495
|
+
/** Compact task information shared by browser tools and the visible workspace. */
|
|
496
|
+
export interface BrowserTaskInfo extends BrowserSpaceInfo {
|
|
497
|
+
/** Whether this task is currently visible in the shared browser window. */
|
|
498
|
+
readonly active: boolean;
|
|
499
|
+
/** Number of tabs in the task's session. */
|
|
500
|
+
readonly tabs: number;
|
|
501
|
+
/** Current visible activity state. */
|
|
502
|
+
readonly status: BrowserTaskStatus;
|
|
503
|
+
/** Who currently owns page-changing actions. */
|
|
504
|
+
readonly control: BrowserControlOwner;
|
|
505
|
+
/** Latest completed or in-progress operation, when known. */
|
|
506
|
+
readonly latestAction?: string;
|
|
507
|
+
/** Epoch milliseconds of the last task-state change. */
|
|
508
|
+
readonly updatedAt: number;
|
|
509
|
+
/** Short display-safe failure detail, when the task failed. */
|
|
510
|
+
readonly error?: string;
|
|
511
|
+
}
|
|
512
|
+
/** Partial task-state update produced by the tool and provider layers. */
|
|
513
|
+
export interface BrowserTaskUpdate {
|
|
514
|
+
readonly status?: BrowserTaskStatus;
|
|
515
|
+
readonly control?: BrowserControlOwner;
|
|
516
|
+
readonly latestAction?: string;
|
|
517
|
+
readonly error?: string;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* A browser-capable backend. Registered with `ctx.browser.registerBrowserProvider`.
|
|
521
|
+
* `id` is a stable string, unique across the seam.
|
|
522
|
+
*/
|
|
523
|
+
export interface BrowserProvider {
|
|
524
|
+
readonly id: string;
|
|
525
|
+
/** Cheap local usability check; must not make network calls. */
|
|
526
|
+
available(): boolean;
|
|
527
|
+
/**
|
|
528
|
+
* Open or recover a session. The provider mints the session id and prepares its
|
|
529
|
+
* backing surface (a view, a headless page, and so on); keyed providers may return
|
|
530
|
+
* the existing session for the same stable task key. Sessions are isolated from
|
|
531
|
+
* each other; a session must not be visible to any other session's caller.
|
|
532
|
+
*/
|
|
533
|
+
open(options?: BrowserOpenOptions): Promise<BrowserSessionId>;
|
|
534
|
+
/** Open a URL, optionally in a new tab. Honor `signal` for cancellation. */
|
|
535
|
+
openUrl(session: BrowserSessionId, request: BrowserOpenRequest, signal?: AbortSignal): Promise<void>;
|
|
536
|
+
/** List the session's tabs. */
|
|
537
|
+
listTabs(session: BrowserSessionId): Promise<readonly BrowserTab[]>;
|
|
538
|
+
/** Switch to a tab by id. Unknown id -> `BROWSER_TAB_UNKNOWN`. */
|
|
539
|
+
switchTab(session: BrowserSessionId, tabId: string): Promise<void>;
|
|
540
|
+
/** Close one tab. Closing the active tab activates the next. */
|
|
541
|
+
closeTab(session: BrowserSessionId, tabId: string): Promise<boolean>;
|
|
542
|
+
/** Close every tab and reset the session's state. */
|
|
543
|
+
reset(session: BrowserSessionId): Promise<void>;
|
|
544
|
+
/** Navigate the active tab. Honor `signal` for cancellation. */
|
|
545
|
+
navigate(session: BrowserSessionId, request: BrowserNavigateRequest, signal?: AbortSignal): Promise<void>;
|
|
546
|
+
/** Navigate to the previous history entry when one exists. */
|
|
547
|
+
back(session: BrowserSessionId, signal?: AbortSignal): Promise<boolean>;
|
|
548
|
+
/** Navigate to the next history entry when one exists. */
|
|
549
|
+
forward(session: BrowserSessionId, signal?: AbortSignal): Promise<boolean>;
|
|
550
|
+
/** Reload the active page. */
|
|
551
|
+
reload(session: BrowserSessionId, signal?: AbortSignal): Promise<void>;
|
|
552
|
+
/** Stop loading the active page. */
|
|
553
|
+
stopLoading(session: BrowserSessionId, signal?: AbortSignal): Promise<void>;
|
|
554
|
+
/** Execute JS in the active tab's page context. */
|
|
555
|
+
execute(session: BrowserSessionId, request: BrowserExecuteRequest, signal?: AbortSignal): Promise<BrowserExecuteResult>;
|
|
556
|
+
/** Produce an AI-friendly snapshot of the active tab. */
|
|
557
|
+
snapshot(session: BrowserSessionId, options?: {
|
|
558
|
+
query?: string;
|
|
559
|
+
limit?: number;
|
|
560
|
+
}, signal?: AbortSignal): Promise<BrowserSnapshotResult>;
|
|
561
|
+
/** Apply device/viewport/media emulation to the session's active tab. */
|
|
562
|
+
emulate(session: BrowserSessionId, options?: {
|
|
563
|
+
width?: number;
|
|
564
|
+
height?: number;
|
|
565
|
+
deviceScaleFactor?: number;
|
|
566
|
+
mobile?: boolean;
|
|
567
|
+
userAgent?: string;
|
|
568
|
+
colorScheme?: 'light' | 'dark' | 'no-preference';
|
|
569
|
+
clear?: boolean;
|
|
570
|
+
}): Promise<{
|
|
571
|
+
applied: string[];
|
|
572
|
+
}>;
|
|
573
|
+
/** Console messages the host captured for the session's active tab. */
|
|
574
|
+
consoleMessages(session: BrowserSessionId, options?: {
|
|
575
|
+
limit?: number;
|
|
576
|
+
level?: string;
|
|
577
|
+
clear?: boolean;
|
|
578
|
+
}): Promise<{
|
|
579
|
+
messages: Array<{
|
|
580
|
+
level: string;
|
|
581
|
+
text: string;
|
|
582
|
+
at: string;
|
|
583
|
+
}>;
|
|
584
|
+
}>;
|
|
585
|
+
/** Network requests the host captured for the session's active tab. */
|
|
586
|
+
networkRequests(session: BrowserSessionId, options?: {
|
|
587
|
+
limit?: number;
|
|
588
|
+
failedOnly?: boolean;
|
|
589
|
+
urlContains?: string;
|
|
590
|
+
clear?: boolean;
|
|
591
|
+
}): Promise<{
|
|
592
|
+
requests: Array<{
|
|
593
|
+
method: string;
|
|
594
|
+
url: string;
|
|
595
|
+
status?: number;
|
|
596
|
+
mime?: string;
|
|
597
|
+
kind?: string;
|
|
598
|
+
failed?: string;
|
|
599
|
+
ms?: number;
|
|
600
|
+
at: string;
|
|
601
|
+
}>;
|
|
602
|
+
}>;
|
|
603
|
+
/** Set how the host answers the next JS dialog (alert/confirm/prompt). */
|
|
604
|
+
setDialogPolicy(session: BrowserSessionId, policy: {
|
|
605
|
+
behavior: 'accept' | 'dismiss';
|
|
606
|
+
promptText?: string;
|
|
607
|
+
}): Promise<{
|
|
608
|
+
dialog: unknown;
|
|
609
|
+
policy: {
|
|
610
|
+
behavior: 'accept' | 'dismiss';
|
|
611
|
+
promptText?: string;
|
|
612
|
+
};
|
|
613
|
+
}>;
|
|
614
|
+
/** Drain any pending dialog, then report the last one and the current policy. */
|
|
615
|
+
inspectDialog(session: BrowserSessionId): Promise<{
|
|
616
|
+
dialog: unknown;
|
|
617
|
+
policy: {
|
|
618
|
+
behavior: 'accept' | 'dismiss';
|
|
619
|
+
promptText?: string;
|
|
620
|
+
};
|
|
621
|
+
}>;
|
|
622
|
+
/** The last JS dialog the host reported, plus the current policy. */
|
|
623
|
+
dialogState(session: BrowserSessionId): {
|
|
624
|
+
dialog: unknown;
|
|
625
|
+
policy: {
|
|
626
|
+
behavior: 'accept' | 'dismiss';
|
|
627
|
+
promptText?: string;
|
|
628
|
+
};
|
|
629
|
+
};
|
|
630
|
+
/** Click one element referenced by an exact snapshot. */
|
|
631
|
+
clickRef(session: BrowserSessionId, request: BrowserRefRequest, signal?: AbortSignal): Promise<void>;
|
|
632
|
+
/** Scroll one element referenced by an exact snapshot into view. */
|
|
633
|
+
scrollIntoView(session: BrowserSessionId, request: BrowserScrollIntoViewRequest, signal?: AbortSignal): Promise<BrowserScrollResult>;
|
|
634
|
+
/** Check whether a human-verification challenge is blocking the active tab. */
|
|
635
|
+
detectChallenge(session: BrowserSessionId, signal?: AbortSignal): Promise<BrowserChallenge>;
|
|
636
|
+
/** Fetch page content in a requested format. */
|
|
637
|
+
content(session: BrowserSessionId, request: BrowserContentRequest, signal?: AbortSignal): Promise<BrowserContentResult>;
|
|
638
|
+
/** Click at viewport coordinates (fallback path; execute is preferred). Honor `signal` for cancellation. */
|
|
639
|
+
click(session: BrowserSessionId, request: BrowserPointerTarget, signal?: AbortSignal): Promise<BrowserPointerResult>;
|
|
640
|
+
/** Type into the focused element (fallback path). Honor `signal` for cancellation. */
|
|
641
|
+
type(session: BrowserSessionId, request: BrowserTypeRequest, signal?: AbortSignal): Promise<void>;
|
|
642
|
+
/** Press a key (keyDown + keyUp) into the active tab. Honor `signal` for cancellation. */
|
|
643
|
+
pressKey(session: BrowserSessionId, request: BrowserPressKeyRequest, signal?: AbortSignal): Promise<void>;
|
|
644
|
+
/** Double-click (one press/release pair, clickCount 2). Honor `signal` for cancellation. */
|
|
645
|
+
doubleClick(session: BrowserSessionId, request: BrowserPointerTarget, signal?: AbortSignal): Promise<BrowserPointerResult>;
|
|
646
|
+
/** Move the pointer without clicking. Honor `signal` for cancellation. */
|
|
647
|
+
hover(session: BrowserSessionId, request: BrowserPointerTarget, signal?: AbortSignal): Promise<BrowserPointerResult>;
|
|
648
|
+
/**
|
|
649
|
+
* Press on one target, move to another, release. Drives sliders, sortable
|
|
650
|
+
* lists and canvas editors. Honor `signal` for cancellation.
|
|
651
|
+
*/
|
|
652
|
+
drag(session: BrowserSessionId, request: BrowserDragRequest, signal?: AbortSignal): Promise<BrowserDragResult>;
|
|
653
|
+
/** Scroll the active page by CSS-pixel deltas. */
|
|
654
|
+
scroll(session: BrowserSessionId, request: BrowserScrollRequest, signal?: AbortSignal): Promise<BrowserScrollResult>;
|
|
655
|
+
/** Attach a local file to a file input. Honor `signal` for cancellation. */
|
|
656
|
+
uploadFile(session: BrowserSessionId, request: BrowserUploadFileRequest, signal?: AbortSignal): Promise<BrowserUploadFileResult>;
|
|
657
|
+
/** Wait until an element matching the selector exists (and optionally is visible). Honor `signal` for cancellation. */
|
|
658
|
+
waitForElement(session: BrowserSessionId, request: BrowserWaitForRequest, signal?: AbortSignal): Promise<BrowserWaitForResult>;
|
|
659
|
+
/** Print the active tab to a PDF file. */
|
|
660
|
+
pdf(session: BrowserSessionId, request: BrowserPdfRequest, signal?: AbortSignal): Promise<BrowserPdfResult>;
|
|
661
|
+
/** Draw or clear the DevTools-style highlight box over a selector's first match. */
|
|
662
|
+
highlight(session: BrowserSessionId, request: BrowserHighlightRequest, signal?: AbortSignal): Promise<BrowserHighlightResult>;
|
|
663
|
+
/** Fill a form's fields in one batch. Honor `signal` for cancellation. */
|
|
664
|
+
fillForm(session: BrowserSessionId, request: BrowserFillRequest, signal?: AbortSignal): Promise<BrowserFillResult>;
|
|
665
|
+
/** Capture the current page. Honor `signal` for cancellation. */
|
|
666
|
+
screenshot(session: BrowserSessionId, request?: BrowserScreenshotRequest, signal?: AbortSignal): Promise<BrowserScreenshotResult>;
|
|
667
|
+
/** Download a URL to a local file. Honor `signal` for cancellation. */
|
|
668
|
+
download(session: BrowserSessionId, request: BrowserDownloadRequest, signal?: AbortSignal): Promise<{
|
|
669
|
+
readonly path: string;
|
|
670
|
+
}>;
|
|
671
|
+
/** Export the session's cookies (login state). */
|
|
672
|
+
flushAuth(session: BrowserSessionId): Promise<readonly ExportedCookie[]>;
|
|
673
|
+
/** Import cookies into the session (restore login state); returns the number of cookies restored. */
|
|
674
|
+
restoreAuth(session: BrowserSessionId, cookies: readonly ExportedCookie[]): Promise<number>;
|
|
675
|
+
/**
|
|
676
|
+
* Import cookies from a JSON export on disk (read-guarded by the provider's
|
|
677
|
+
* read roots). `failed` counts entries the file carried that could not be set.
|
|
678
|
+
*/
|
|
679
|
+
importAuth(session: BrowserSessionId, path: string): Promise<{
|
|
680
|
+
readonly restored: number;
|
|
681
|
+
readonly failed: number;
|
|
682
|
+
}>;
|
|
683
|
+
/** Start a background scrape batch; it writes its rows itself. */
|
|
684
|
+
startScrape(session: BrowserSessionId, request: BrowserScrapeRequest): Promise<BrowserScrapeStatus>;
|
|
685
|
+
/** Progress of one batch. */
|
|
686
|
+
scrapeStatus(id: string): Promise<BrowserScrapeStatus>;
|
|
687
|
+
/** Ask a running batch to stop; rows already written are kept. */
|
|
688
|
+
stopScrape(id: string): Promise<BrowserScrapeStatus>;
|
|
689
|
+
/** Every batch this process knows about, oldest first. */
|
|
690
|
+
listScrapes(): Promise<readonly BrowserScrapeStatus[]>;
|
|
691
|
+
/** Remove cookies for a site scope; returns how many went and their names. */
|
|
692
|
+
clearAuth(session: BrowserSessionId, request: BrowserClearAuthRequest): Promise<BrowserClearAuthResult>;
|
|
693
|
+
/** Return the session's chronological operation log. */
|
|
694
|
+
history(session: BrowserSessionId): Promise<readonly BrowserHistoryEntry[]>;
|
|
695
|
+
/** Replay one recorded operation by sequence number. */
|
|
696
|
+
replay(session: BrowserSessionId, seq: number): Promise<void>;
|
|
697
|
+
/** Set the browser task label for a session; selected task controls the shared title. */
|
|
698
|
+
setSpace(session: BrowserSessionId, label: string): Promise<void>;
|
|
699
|
+
/** List browser tasks (legacy spaces) with their labels. */
|
|
700
|
+
listSpaces(): Promise<readonly BrowserSpaceInfo[]>;
|
|
701
|
+
/** List browser tasks with live collaboration status. */
|
|
702
|
+
listTasks(): Promise<readonly BrowserTaskInfo[]>;
|
|
703
|
+
/** Read the collaboration state of this session's task. */
|
|
704
|
+
getTask(session: BrowserSessionId): Promise<BrowserTaskInfo>;
|
|
705
|
+
/** Apply a visible activity/control update to this session's task. */
|
|
706
|
+
updateTask(session: BrowserSessionId, update: BrowserTaskUpdate): Promise<BrowserTaskInfo>;
|
|
707
|
+
/** Mark this task as waiting for the user or returned to Agent control. */
|
|
708
|
+
setHandoff(session: BrowserSessionId, state: BrowserHandoffState): Promise<BrowserTaskInfo>;
|
|
709
|
+
/** Close the session and destroy its backing surface. Idempotent. */
|
|
710
|
+
close(session: BrowserSessionId): Promise<void>;
|
|
711
|
+
/**
|
|
712
|
+
* Bring the shared browser window to the front, creating it (and a default
|
|
713
|
+
* session) when nothing is open yet. Optional: a provider whose browser has
|
|
714
|
+
* no window of its own omits it, and callers must report that as unsupported
|
|
715
|
+
* rather than pretending a window was raised.
|
|
716
|
+
*/
|
|
717
|
+
ensureWindowVisible?(): Promise<void>;
|
|
718
|
+
/**
|
|
719
|
+
* Mirror one task's Agent todo list into the shared window, where the floating
|
|
720
|
+
* orb renders it. Optional: a provider without a window of its own omits it.
|
|
721
|
+
* `taskKey` is the same task key the tools use (the calling Agent's id).
|
|
722
|
+
*/
|
|
723
|
+
pushTaskTodos?(taskKey: string, todos: readonly BrowserTaskTodo[]): Promise<void>;
|
|
724
|
+
}
|
|
725
|
+
/** One entry of an Agent's todo list, as the floating orb shows it. */
|
|
726
|
+
export interface BrowserTaskTodo {
|
|
727
|
+
readonly content: string;
|
|
728
|
+
readonly status: 'pending' | 'in_progress' | 'completed';
|
|
729
|
+
}
|
|
730
|
+
/** One recorded browser operation, in chronological order (seq 1, 2, 3…). */
|
|
731
|
+
export interface BrowserHistoryEntry {
|
|
732
|
+
/** Monotonic sequence number within the session. */
|
|
733
|
+
readonly seq: number;
|
|
734
|
+
/** The operation name. Replayable: navigate | execute | click | type |
|
|
735
|
+
* pressKey. Also recorded but not replayable: fill | download |
|
|
736
|
+
* flushAuth | restoreAuth | clearAuth | setSpace | doubleClick | hover |
|
|
737
|
+
* uploadFile | waitForElement. */
|
|
738
|
+
readonly action: string;
|
|
739
|
+
/** The operation's arguments. */
|
|
740
|
+
readonly params: Record<string, unknown>;
|
|
741
|
+
/** Whether the operation succeeded. */
|
|
742
|
+
readonly ok: boolean;
|
|
743
|
+
/** Truncated result text, when the operation returned one. */
|
|
744
|
+
readonly result?: string;
|
|
745
|
+
/** Error text, when the operation failed. */
|
|
746
|
+
readonly error?: string;
|
|
747
|
+
/** Epoch millis of the operation. */
|
|
748
|
+
readonly at: number;
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Typed browser error with a machine-routable, open-string `code` and chained
|
|
752
|
+
* `cause`. Consumers must tolerate provider-specific codes. Shared codes cover
|
|
753
|
+
* unavailable, missing, unusable, ambiguous, or duplicate providers, unknown
|
|
754
|
+
* or closed sessions, cancellation, and provider failure; a provider adds its
|
|
755
|
+
* own (e.g. `BROWSER_CDP_ATTACH_FAILED`).
|
|
756
|
+
*/
|
|
757
|
+
export declare class BrowserError extends HarnessError {
|
|
758
|
+
}
|