browserclaw 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of browserclaw might be problematic. Click here for more details.

@@ -0,0 +1,728 @@
1
+ interface FrameEvalResult {
2
+ frameUrl: string;
3
+ frameName: string;
4
+ result: unknown;
5
+ }
6
+
7
+ /** Supported browser types that can be detected and launched. */
8
+ type ChromeKind = 'chrome' | 'brave' | 'edge' | 'chromium' | 'canary' | 'custom';
9
+ /** A detected browser executable on the system. */
10
+ interface ChromeExecutable {
11
+ /** The type of browser (chrome, brave, edge, etc.) */
12
+ kind: ChromeKind;
13
+ /** Absolute path to the browser executable */
14
+ path: string;
15
+ }
16
+ /** Options for launching a new browser instance. */
17
+ interface LaunchOptions {
18
+ /** Run in headless mode (no visible window). Default: `false` */
19
+ headless?: boolean;
20
+ /** Path to a specific browser executable. Auto-detected if omitted. */
21
+ executablePath?: string;
22
+ /** CDP port to use. Default: `9222` */
23
+ cdpPort?: number;
24
+ /** Disable Chrome's sandbox (needed in some Docker/CI environments). Default: `false` */
25
+ noSandbox?: boolean;
26
+ /** Custom user data directory. Auto-generated if omitted. */
27
+ userDataDir?: string;
28
+ /** Profile name shown in the Chrome title bar. Default: `'browserclaw'` */
29
+ profileName?: string;
30
+ /** Profile accent color as a hex string (e.g. `'#FF4500'`). Default: `'#FF4500'` */
31
+ profileColor?: string;
32
+ /** Additional Chrome command-line arguments (e.g. `['--start-maximized']`). */
33
+ chromeArgs?: string[];
34
+ }
35
+ /** Options for connecting to an existing browser instance. */
36
+ interface ConnectOptions {
37
+ /** CDP endpoint URL (e.g. `'http://localhost:9222'`) */
38
+ cdpUrl: string;
39
+ }
40
+ /**
41
+ * Describes a single interactive element found during a snapshot.
42
+ * Used to resolve refs (e.g. `e1`) back to Playwright locators.
43
+ */
44
+ interface RoleRefInfo {
45
+ /** ARIA role of the element (e.g. `'button'`, `'textbox'`, `'link'`) */
46
+ role: string;
47
+ /** Accessible name of the element */
48
+ name?: string;
49
+ /** Disambiguation index when multiple elements share the same role + name */
50
+ nth?: number;
51
+ }
52
+ /** Map of ref IDs (e.g. `'e1'`, `'e2'`) to their element information. */
53
+ type RoleRefs = Record<string, RoleRefInfo>;
54
+ /** Result of taking a page snapshot. */
55
+ interface SnapshotResult {
56
+ /** AI-readable text representation of the page with numbered refs */
57
+ snapshot: string;
58
+ /** Map of ref IDs to element information for targeting actions */
59
+ refs: RoleRefs;
60
+ /** Statistics about the snapshot */
61
+ stats?: SnapshotStats;
62
+ }
63
+ /** Statistics about a snapshot's content. */
64
+ interface SnapshotStats {
65
+ /** Number of lines in the snapshot text */
66
+ lines: number;
67
+ /** Number of characters in the snapshot text */
68
+ chars: number;
69
+ /** Total number of refs assigned */
70
+ refs: number;
71
+ /** Number of interactive element refs (buttons, links, inputs, etc.) */
72
+ interactive: number;
73
+ }
74
+ /** Options for controlling snapshot output. */
75
+ interface SnapshotOptions {
76
+ /** Only include interactive elements (buttons, links, inputs, etc.) */
77
+ interactive?: boolean;
78
+ /** Remove structural containers that don't contain interactive elements */
79
+ compact?: boolean;
80
+ /** Maximum tree depth to include */
81
+ maxDepth?: number;
82
+ /** Maximum character count before truncation (aria mode only) */
83
+ maxChars?: number;
84
+ /** CSS selector to scope the snapshot to a specific element */
85
+ selector?: string;
86
+ /** Frame selector for snapshotting inside iframes (role mode only) */
87
+ frameSelector?: string;
88
+ /**
89
+ * Snapshot strategy:
90
+ * - `'aria'` (default) — uses Playwright's `_snapshotForAI()`, produces refs like `e1`
91
+ * - `'role'` — uses Playwright's `ariaSnapshot()` + `getByRole()` resolution
92
+ */
93
+ mode?: 'role' | 'aria';
94
+ }
95
+ /** A node in the raw ARIA accessibility tree. */
96
+ interface AriaNode {
97
+ /** Ref ID for this node (e.g. `'ax1'`) */
98
+ ref: string;
99
+ /** ARIA role (e.g. `'button'`, `'heading'`, `'generic'`) */
100
+ role: string;
101
+ /** Accessible name */
102
+ name: string;
103
+ /** Current value (for inputs, sliders, etc.) */
104
+ value?: string;
105
+ /** Accessible description */
106
+ description?: string;
107
+ /** Backend DOM node ID (for CDP operations) */
108
+ backendDOMNodeId?: number;
109
+ /** Depth in the accessibility tree (0 = root) */
110
+ depth: number;
111
+ }
112
+ /** Result of a raw ARIA tree snapshot. */
113
+ interface AriaSnapshotResult {
114
+ /** Flat list of accessibility tree nodes */
115
+ nodes: AriaNode[];
116
+ }
117
+ /** A form field to fill as part of a batch `fill()` operation. */
118
+ interface FormField {
119
+ /** Ref ID of the form field (e.g. `'e3'`) */
120
+ ref: string;
121
+ /** Field type: `'text'`, `'checkbox'`, `'radio'`, etc. */
122
+ type: string;
123
+ /** Value to set. Booleans for checkboxes, strings for text fields. */
124
+ value?: string | number | boolean;
125
+ }
126
+ /** Options for click actions. */
127
+ interface ClickOptions {
128
+ /** Double-click instead of single click */
129
+ doubleClick?: boolean;
130
+ /** Mouse button to use */
131
+ button?: 'left' | 'right' | 'middle';
132
+ /** Modifier keys to hold during click */
133
+ modifiers?: ('Alt' | 'Control' | 'Meta' | 'Shift')[];
134
+ /** Timeout in milliseconds. Default: `8000` */
135
+ timeoutMs?: number;
136
+ }
137
+ /** Options for type actions. */
138
+ interface TypeOptions {
139
+ /** Press Enter after typing */
140
+ submit?: boolean;
141
+ /** Type character-by-character with delay (75ms per key) instead of instant fill */
142
+ slowly?: boolean;
143
+ /** Timeout in milliseconds. Default: `8000` */
144
+ timeoutMs?: number;
145
+ }
146
+ /**
147
+ * Options for waiting on various conditions.
148
+ * Multiple conditions can be combined — they are checked in order.
149
+ */
150
+ interface WaitOptions {
151
+ /** Wait for a fixed duration (milliseconds) */
152
+ timeMs?: number;
153
+ /** Wait until text appears on the page */
154
+ text?: string;
155
+ /** Wait until text disappears from the page */
156
+ textGone?: string;
157
+ /** Wait until a CSS selector matches a visible element */
158
+ selector?: string;
159
+ /** Wait until the URL matches a pattern (supports `**` wildcards) */
160
+ url?: string;
161
+ /** Wait for a specific page load state */
162
+ loadState?: 'load' | 'domcontentloaded' | 'networkidle';
163
+ /** Wait until a JavaScript function returns truthy (evaluated in browser context) */
164
+ fn?: string;
165
+ /** Timeout for each condition in milliseconds. Default: `20000` */
166
+ timeoutMs?: number;
167
+ }
168
+ /** Options for screenshot capture. */
169
+ interface ScreenshotOptions {
170
+ /** Capture the full scrollable page instead of just the viewport */
171
+ fullPage?: boolean;
172
+ /** Capture a specific element by ref ID */
173
+ ref?: string;
174
+ /** Capture a specific element by CSS selector */
175
+ element?: string;
176
+ /** Image format. Default: `'png'` */
177
+ type?: 'png' | 'jpeg';
178
+ }
179
+ /** A console message captured from the browser page. */
180
+ interface ConsoleMessage {
181
+ /** Message type: `'log'`, `'info'`, `'warning'`, `'error'`, `'debug'` */
182
+ type: string;
183
+ /** The message text */
184
+ text: string;
185
+ /** ISO 8601 timestamp */
186
+ timestamp: string;
187
+ /** Source location where the message was logged */
188
+ location?: {
189
+ url?: string;
190
+ lineNumber?: number;
191
+ columnNumber?: number;
192
+ };
193
+ }
194
+ /** An uncaught error from the browser page. */
195
+ interface PageError {
196
+ /** Error message */
197
+ message: string;
198
+ /** Error name (e.g. `'TypeError'`) */
199
+ name?: string;
200
+ /** Stack trace */
201
+ stack?: string;
202
+ /** ISO 8601 timestamp */
203
+ timestamp: string;
204
+ }
205
+ /** A network request captured from the browser page. */
206
+ interface NetworkRequest {
207
+ /** Internal request ID (e.g. `'r1'`, `'r2'`) */
208
+ id: string;
209
+ /** ISO 8601 timestamp */
210
+ timestamp: string;
211
+ /** HTTP method (e.g. `'GET'`, `'POST'`) */
212
+ method: string;
213
+ /** Request URL */
214
+ url: string;
215
+ /** Resource type (e.g. `'document'`, `'xhr'`, `'fetch'`, `'image'`) */
216
+ resourceType: string;
217
+ /** HTTP status code (set when response is received) */
218
+ status?: number;
219
+ /** Whether the response status was 2xx */
220
+ ok?: boolean;
221
+ /** Error text if the request failed */
222
+ failureText?: string;
223
+ }
224
+ /** Web storage type. */
225
+ type StorageKind = 'local' | 'session';
226
+ /** Cookie data for setting a browser cookie. */
227
+ interface CookieData {
228
+ /** Cookie name */
229
+ name: string;
230
+ /** Cookie value */
231
+ value: string;
232
+ /** URL to associate the cookie with (alternative to domain+path) */
233
+ url?: string;
234
+ /** Cookie domain */
235
+ domain?: string;
236
+ /** Cookie path */
237
+ path?: string;
238
+ /** Expiration as Unix timestamp in seconds */
239
+ expires?: number;
240
+ /** HTTP-only flag */
241
+ httpOnly?: boolean;
242
+ /** Secure flag */
243
+ secure?: boolean;
244
+ /** SameSite attribute */
245
+ sameSite?: 'Strict' | 'Lax' | 'None';
246
+ }
247
+ /** Information about an open browser tab. */
248
+ interface BrowserTab {
249
+ /** CDP target ID (used to identify this tab in API calls) */
250
+ targetId: string;
251
+ /** Page title */
252
+ title: string;
253
+ /** Current URL */
254
+ url: string;
255
+ /** Target type (usually `'page'`) */
256
+ type: string;
257
+ }
258
+
259
+ /**
260
+ * Represents a single browser page/tab with ref-based automation.
261
+ *
262
+ * The workflow is: **snapshot → read refs → act on refs**.
263
+ *
264
+ * @example
265
+ * ```ts
266
+ * const page = await browser.open('https://example.com');
267
+ *
268
+ * // 1. Take a snapshot to get refs
269
+ * const { snapshot, refs } = await page.snapshot();
270
+ * // snapshot: AI-readable text tree
271
+ * // refs: { "e1": { role: "link", name: "More info" }, ... }
272
+ *
273
+ * // 2. Act on refs
274
+ * await page.click('e1');
275
+ * await page.type('e3', 'hello');
276
+ * ```
277
+ */
278
+ declare class CrawlPage {
279
+ private readonly cdpUrl;
280
+ private readonly targetId;
281
+ /** @internal */
282
+ constructor(cdpUrl: string, targetId: string);
283
+ /** The CDP target ID for this page. Use this to identify the page in multi-tab scenarios. */
284
+ get id(): string;
285
+ /**
286
+ * Take an AI-readable snapshot of the page.
287
+ *
288
+ * Returns a text tree with numbered refs (`e1`, `e2`, ...) that map to
289
+ * interactive elements. Use these refs with actions like `click()` and `type()`.
290
+ *
291
+ * @param opts - Snapshot options (mode, filtering, depth limits)
292
+ * @returns Snapshot text, ref map, and statistics
293
+ *
294
+ * @example
295
+ * ```ts
296
+ * // Default snapshot (aria mode)
297
+ * const { snapshot, refs } = await page.snapshot();
298
+ *
299
+ * // Interactive elements only, compact
300
+ * const result = await page.snapshot({ interactive: true, compact: true });
301
+ *
302
+ * // Role-based mode (uses getByRole resolution)
303
+ * const result = await page.snapshot({ mode: 'role' });
304
+ * ```
305
+ */
306
+ snapshot(opts?: SnapshotOptions): Promise<SnapshotResult>;
307
+ /**
308
+ * Take a raw ARIA accessibility tree snapshot via CDP.
309
+ *
310
+ * Unlike `snapshot()`, this returns structured node data rather than
311
+ * an AI-readable text tree. Useful for programmatic accessibility analysis.
312
+ *
313
+ * @param opts - Options (limit: max nodes to return, default 500)
314
+ * @returns Array of accessibility tree nodes
315
+ */
316
+ ariaSnapshot(opts?: {
317
+ limit?: number;
318
+ }): Promise<AriaSnapshotResult>;
319
+ /**
320
+ * Click an element by ref.
321
+ *
322
+ * @param ref - Ref ID from a snapshot (e.g. `'e1'`)
323
+ * @param opts - Click options (double-click, button, modifiers)
324
+ *
325
+ * @example
326
+ * ```ts
327
+ * await page.click('e1');
328
+ * await page.click('e2', { doubleClick: true });
329
+ * await page.click('e3', { button: 'right' });
330
+ * await page.click('e4', { modifiers: ['Control'] });
331
+ * ```
332
+ */
333
+ click(ref: string, opts?: ClickOptions): Promise<void>;
334
+ /**
335
+ * Type text into an input element by ref.
336
+ *
337
+ * By default, uses Playwright's `fill()` for instant input. Use `slowly: true`
338
+ * to simulate real keystroke typing with a 75ms delay per character.
339
+ *
340
+ * @param ref - Ref ID of the input element (e.g. `'e3'`)
341
+ * @param text - Text to type
342
+ * @param opts - Type options (submit, slowly)
343
+ *
344
+ * @example
345
+ * ```ts
346
+ * await page.type('e3', 'hello world');
347
+ * await page.type('e3', 'slow typing', { slowly: true });
348
+ * await page.type('e3', 'search query', { submit: true }); // press Enter after
349
+ * ```
350
+ */
351
+ type(ref: string, text: string, opts?: TypeOptions): Promise<void>;
352
+ /**
353
+ * Hover over an element by ref.
354
+ *
355
+ * @param ref - Ref ID from a snapshot
356
+ * @param opts - Timeout options
357
+ */
358
+ hover(ref: string, opts?: {
359
+ timeoutMs?: number;
360
+ }): Promise<void>;
361
+ /**
362
+ * Select option(s) in a `<select>` dropdown by ref.
363
+ *
364
+ * @param ref - Ref ID of the select element
365
+ * @param values - One or more option labels/values to select
366
+ *
367
+ * @example
368
+ * ```ts
369
+ * await page.select('e5', 'Option A');
370
+ * await page.select('e5', 'Option A', 'Option B'); // multi-select
371
+ * ```
372
+ */
373
+ select(ref: string, ...values: string[]): Promise<void>;
374
+ /**
375
+ * Drag one element to another.
376
+ *
377
+ * @param startRef - Ref ID of the element to drag
378
+ * @param endRef - Ref ID of the drop target
379
+ * @param opts - Timeout options
380
+ */
381
+ drag(startRef: string, endRef: string, opts?: {
382
+ timeoutMs?: number;
383
+ }): Promise<void>;
384
+ /**
385
+ * Fill multiple form fields at once.
386
+ *
387
+ * Supports text inputs, checkboxes, and radio buttons.
388
+ *
389
+ * @param fields - Array of form fields to fill
390
+ *
391
+ * @example
392
+ * ```ts
393
+ * await page.fill([
394
+ * { ref: 'e2', type: 'text', value: 'Jane Doe' },
395
+ * { ref: 'e4', type: 'text', value: 'jane@example.com' },
396
+ * { ref: 'e6', type: 'checkbox', value: true },
397
+ * ]);
398
+ * ```
399
+ */
400
+ fill(fields: FormField[]): Promise<void>;
401
+ /**
402
+ * Scroll an element into the visible viewport.
403
+ *
404
+ * @param ref - Ref ID of the element to scroll to
405
+ * @param opts - Timeout options
406
+ */
407
+ scrollIntoView(ref: string, opts?: {
408
+ timeoutMs?: number;
409
+ }): Promise<void>;
410
+ /**
411
+ * Press a keyboard key or key combination.
412
+ *
413
+ * Uses Playwright's key names. Supports combinations with `+`.
414
+ *
415
+ * @param key - Key to press (e.g. `'Enter'`, `'Tab'`, `'Control+a'`, `'Meta+c'`)
416
+ * @param opts - Options (delayMs: hold time between keydown and keyup)
417
+ *
418
+ * @example
419
+ * ```ts
420
+ * await page.press('Enter');
421
+ * await page.press('Control+a');
422
+ * await page.press('Meta+Shift+p');
423
+ * ```
424
+ */
425
+ press(key: string, opts?: {
426
+ delayMs?: number;
427
+ }): Promise<void>;
428
+ /**
429
+ * Navigate to a URL.
430
+ *
431
+ * @param url - The URL to navigate to
432
+ * @param opts - Timeout options
433
+ * @returns The final URL after navigation (may differ due to redirects)
434
+ */
435
+ goto(url: string, opts?: {
436
+ timeoutMs?: number;
437
+ }): Promise<{
438
+ url: string;
439
+ }>;
440
+ /**
441
+ * Wait for various conditions on the page.
442
+ *
443
+ * Multiple conditions can be specified — they are checked in order.
444
+ *
445
+ * @param opts - Wait conditions (text, URL, load state, selector, etc.)
446
+ *
447
+ * @example
448
+ * ```ts
449
+ * await page.waitFor({ loadState: 'networkidle' });
450
+ * await page.waitFor({ text: 'Welcome back' });
451
+ * await page.waitFor({ url: '**\/dashboard' });
452
+ * await page.waitFor({ timeMs: 1000 }); // sleep
453
+ * ```
454
+ */
455
+ waitFor(opts: WaitOptions): Promise<void>;
456
+ /**
457
+ * Run JavaScript in the browser page context.
458
+ *
459
+ * The function string is evaluated in the browser's sandbox, not in Node.js.
460
+ * Pass a `ref` to receive the element as the first argument.
461
+ *
462
+ * @param fn - JavaScript function body as a string
463
+ * @param opts - Options (ref: scope evaluation to a specific element)
464
+ * @returns The return value of the evaluated function
465
+ *
466
+ * @example
467
+ * ```ts
468
+ * const title = await page.evaluate('() => document.title');
469
+ * const text = await page.evaluate('(el) => el.textContent', { ref: 'e1' });
470
+ * const count = await page.evaluate('() => document.querySelectorAll("img").length');
471
+ * ```
472
+ */
473
+ evaluate(fn: string, opts?: {
474
+ ref?: string;
475
+ }): Promise<unknown>;
476
+ /**
477
+ * Run JavaScript in ALL frames on the page (including cross-origin iframes).
478
+ *
479
+ * Playwright can access cross-origin frames via CDP, bypassing the same-origin policy.
480
+ * This is essential for filling payment iframes (Stripe, etc.).
481
+ *
482
+ * @param fn - JavaScript function body as a string
483
+ * @returns Array of results from each frame where evaluation succeeded
484
+ *
485
+ * @example
486
+ * ```ts
487
+ * const results = await page.evaluateInAllFrames(`() => {
488
+ * const el = document.querySelector('input[name="cardnumber"]');
489
+ * return el ? 'found' : null;
490
+ * }`);
491
+ * ```
492
+ */
493
+ evaluateInAllFrames(fn: string): Promise<FrameEvalResult[]>;
494
+ /**
495
+ * Take a screenshot of the page or a specific element.
496
+ *
497
+ * @param opts - Screenshot options (fullPage, ref, element, type)
498
+ * @returns PNG or JPEG image as a Buffer
499
+ *
500
+ * @example
501
+ * ```ts
502
+ * const screenshot = await page.screenshot();
503
+ * const fullPage = await page.screenshot({ fullPage: true });
504
+ * const element = await page.screenshot({ ref: 'e1' });
505
+ * ```
506
+ */
507
+ screenshot(opts?: ScreenshotOptions): Promise<Buffer>;
508
+ /**
509
+ * Export the page as a PDF.
510
+ *
511
+ * Only works in headless mode.
512
+ *
513
+ * @returns PDF document as a Buffer
514
+ */
515
+ pdf(): Promise<Buffer>;
516
+ /**
517
+ * Get console messages captured from the page.
518
+ *
519
+ * Messages are buffered automatically. Use `level` to filter by minimum severity.
520
+ *
521
+ * @param opts - Filter options (level: `'debug'` | `'log'` | `'info'` | `'warning'` | `'error'`)
522
+ * @returns Array of captured console messages
523
+ */
524
+ consoleLogs(opts?: {
525
+ level?: string;
526
+ }): Promise<ConsoleMessage[]>;
527
+ /**
528
+ * Get uncaught errors from the page.
529
+ *
530
+ * @param opts - Options (clear: reset the error buffer after reading)
531
+ * @returns Array of captured page errors
532
+ */
533
+ pageErrors(opts?: {
534
+ clear?: boolean;
535
+ }): Promise<PageError[]>;
536
+ /**
537
+ * Get network requests captured from the page.
538
+ *
539
+ * @param opts - Options (filter: URL substring match, clear: reset the buffer)
540
+ * @returns Array of captured network requests
541
+ *
542
+ * @example
543
+ * ```ts
544
+ * const all = await page.networkRequests();
545
+ * const apiCalls = await page.networkRequests({ filter: '/api/' });
546
+ * const fresh = await page.networkRequests({ clear: true }); // read and clear
547
+ * ```
548
+ */
549
+ networkRequests(opts?: {
550
+ filter?: string;
551
+ clear?: boolean;
552
+ }): Promise<NetworkRequest[]>;
553
+ /**
554
+ * Resize the browser viewport.
555
+ *
556
+ * @param width - Viewport width in pixels
557
+ * @param height - Viewport height in pixels
558
+ */
559
+ resize(width: number, height: number): Promise<void>;
560
+ /**
561
+ * Get all cookies for the current browser context.
562
+ *
563
+ * @returns Array of cookie objects
564
+ */
565
+ cookies(): Promise<any[]>;
566
+ /**
567
+ * Set a cookie in the browser context.
568
+ *
569
+ * @param cookie - Cookie data (must include `name`, `value`, and either `url` or `domain`+`path`)
570
+ *
571
+ * @example
572
+ * ```ts
573
+ * await page.setCookie({
574
+ * name: 'token',
575
+ * value: 'abc123',
576
+ * url: 'https://example.com',
577
+ * });
578
+ * ```
579
+ */
580
+ setCookie(cookie: CookieData): Promise<void>;
581
+ /** Clear all cookies in the browser context. */
582
+ clearCookies(): Promise<void>;
583
+ /**
584
+ * Get values from localStorage or sessionStorage.
585
+ *
586
+ * @param kind - `'local'` for localStorage, `'session'` for sessionStorage
587
+ * @param key - Optional specific key to retrieve (returns all if omitted)
588
+ * @returns Key-value map of storage entries
589
+ */
590
+ storageGet(kind: StorageKind, key?: string): Promise<Record<string, string>>;
591
+ /**
592
+ * Set a value in localStorage or sessionStorage.
593
+ *
594
+ * @param kind - `'local'` for localStorage, `'session'` for sessionStorage
595
+ * @param key - Storage key
596
+ * @param value - Storage value
597
+ */
598
+ storageSet(kind: StorageKind, key: string, value: string): Promise<void>;
599
+ /**
600
+ * Clear all entries in localStorage or sessionStorage.
601
+ *
602
+ * @param kind - `'local'` for localStorage, `'session'` for sessionStorage
603
+ */
604
+ storageClear(kind: StorageKind): Promise<void>;
605
+ }
606
+ /**
607
+ * Main entry point for browserclaw.
608
+ *
609
+ * Launch or connect to a browser, then open pages and automate them
610
+ * using the snapshot + ref pattern.
611
+ *
612
+ * @example
613
+ * ```ts
614
+ * import { BrowserClaw } from 'browserclaw';
615
+ *
616
+ * const browser = await BrowserClaw.launch({ headless: false });
617
+ * const page = await browser.open('https://example.com');
618
+ *
619
+ * const { snapshot, refs } = await page.snapshot();
620
+ * console.log(snapshot); // AI-readable page tree
621
+ * console.log(refs); // { "e1": { role: "link", name: "More info" }, ... }
622
+ *
623
+ * await page.click('e1');
624
+ * await browser.stop();
625
+ * ```
626
+ */
627
+ declare class BrowserClaw {
628
+ private readonly cdpUrl;
629
+ private chrome;
630
+ private constructor();
631
+ /**
632
+ * Launch a new Chrome instance and connect to it.
633
+ *
634
+ * Automatically detects Chrome, Brave, Edge, or Chromium on the system.
635
+ * Creates a dedicated browser profile to avoid conflicts with your daily browser.
636
+ *
637
+ * @param opts - Launch options (headless, executablePath, cdpPort, etc.)
638
+ * @returns A connected BrowserClaw instance
639
+ *
640
+ * @example
641
+ * ```ts
642
+ * // Default: visible Chrome window
643
+ * const browser = await BrowserClaw.launch();
644
+ *
645
+ * // Headless mode
646
+ * const browser = await BrowserClaw.launch({ headless: true });
647
+ *
648
+ * // Specific browser
649
+ * const browser = await BrowserClaw.launch({
650
+ * executablePath: '/usr/bin/google-chrome',
651
+ * });
652
+ * ```
653
+ */
654
+ static launch(opts?: LaunchOptions): Promise<BrowserClaw>;
655
+ /**
656
+ * Connect to an already-running Chrome instance via its CDP endpoint.
657
+ *
658
+ * The Chrome instance must have been started with `--remote-debugging-port`.
659
+ *
660
+ * @param cdpUrl - CDP endpoint URL (e.g. `'http://localhost:9222'`)
661
+ * @returns A connected BrowserClaw instance
662
+ *
663
+ * @example
664
+ * ```ts
665
+ * // Chrome started with: chrome --remote-debugging-port=9222
666
+ * const browser = await BrowserClaw.connect('http://localhost:9222');
667
+ * ```
668
+ */
669
+ static connect(cdpUrl: string): Promise<BrowserClaw>;
670
+ /**
671
+ * Open a URL in a new tab and return the page handle.
672
+ *
673
+ * @param url - URL to navigate to
674
+ * @returns A CrawlPage for the new tab
675
+ *
676
+ * @example
677
+ * ```ts
678
+ * const page = await browser.open('https://example.com');
679
+ * const { snapshot, refs } = await page.snapshot();
680
+ * ```
681
+ */
682
+ open(url: string): Promise<CrawlPage>;
683
+ /**
684
+ * Get a CrawlPage handle for the currently active tab.
685
+ *
686
+ * @returns CrawlPage for the first/active page
687
+ */
688
+ currentPage(): Promise<CrawlPage>;
689
+ /**
690
+ * List all open tabs.
691
+ *
692
+ * @returns Array of tab information objects
693
+ */
694
+ tabs(): Promise<BrowserTab[]>;
695
+ /**
696
+ * Bring a tab to the foreground.
697
+ *
698
+ * @param targetId - CDP target ID of the tab (from `tabs()` or `page.id`)
699
+ */
700
+ focus(targetId: string): Promise<void>;
701
+ /**
702
+ * Close a tab.
703
+ *
704
+ * @param targetId - CDP target ID of the tab to close
705
+ */
706
+ close(targetId: string): Promise<void>;
707
+ /**
708
+ * Get a CrawlPage handle for a specific tab by its target ID.
709
+ *
710
+ * Unlike `open()`, this doesn't create a new tab — it wraps an existing one.
711
+ *
712
+ * @param targetId - CDP target ID of the tab
713
+ * @returns CrawlPage for the specified tab
714
+ */
715
+ page(targetId: string): CrawlPage;
716
+ /** The CDP endpoint URL for this browser connection. */
717
+ get url(): string;
718
+ /**
719
+ * Stop the browser and clean up all resources.
720
+ *
721
+ * If the browser was launched by `BrowserClaw.launch()`, the Chrome process
722
+ * will be terminated. If connected via `BrowserClaw.connect()`, only the
723
+ * Playwright connection is closed.
724
+ */
725
+ stop(): Promise<void>;
726
+ }
727
+
728
+ export { type AriaNode, type AriaSnapshotResult, BrowserClaw, type BrowserTab, type ChromeExecutable, type ChromeKind, type ClickOptions, type ConnectOptions, type ConsoleMessage, type CookieData, CrawlPage, type FormField, type FrameEvalResult, type LaunchOptions, type NetworkRequest, type PageError, type RoleRefInfo, type RoleRefs, type ScreenshotOptions, type SnapshotOptions, type SnapshotResult, type SnapshotStats, type StorageKind, type TypeOptions, type WaitOptions };