@orkestrel/browser 0.0.13 → 0.0.15

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.
@@ -4,6 +4,8 @@ import { BrowserError } from '@orkestrel/browser';
4
4
  import { BrowserPageInterface } from '@orkestrel/browser';
5
5
  import { BrowserPageOptions } from '@orkestrel/browser';
6
6
  import { BrowserViewport } from '@orkestrel/browser';
7
+ import { BrowserWriterInterface } from '@orkestrel/browser';
8
+ import { BrowserWriterInterface as BrowserWriterInterface_2 } from '@orkestrel/browser';
7
9
  import { CDPTarget } from '@orkestrel/browser';
8
10
  import { CDPTransportEventMap } from '@orkestrel/browser';
9
11
  import { CDPTransportEventMap as CDPTransportEventMap_2 } from '@orkestrel/browser';
@@ -13,10 +15,20 @@ import { ChildProcess } from 'node:child_process';
13
15
  import { EmitterErrorHandler } from '@orkestrel/emitter';
14
16
  import { EmitterHooks } from '@orkestrel/emitter';
15
17
  import { EmitterInterface } from '@orkestrel/emitter';
16
- import { ScreenshotWriterInterface } from '@orkestrel/browser';
18
+ import { Result } from '@orkestrel/contract';
17
19
 
18
20
  /**
19
21
  * Discovers, launches, connects to, and owns Chromium-family browser sessions.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * import { Browser } from '@orkestrel/browser/server'
26
+ *
27
+ * const browser = new Browser({ headless: true })
28
+ * await browser.connect()
29
+ * const page = await browser.create({ url: 'https://example.com' })
30
+ * await browser.destroy()
31
+ * ```
20
32
  */
21
33
  export declare class Browser implements BrowserInterface {
22
34
  #private;
@@ -26,7 +38,6 @@ export declare class Browser implements BrowserInterface {
26
38
  get status(): BrowserStatus;
27
39
  get connection(): BrowserConnection | undefined;
28
40
  get owned(): boolean | undefined;
29
- get connected(): boolean;
30
41
  get pid(): number | undefined;
31
42
  discover(): Promise<BrowserDiscoveryResult>;
32
43
  connect(): Promise<void>;
@@ -40,83 +51,83 @@ export declare class Browser implements BrowserInterface {
40
51
  close(): Promise<void>;
41
52
  }
42
53
 
43
- /** Path appended to the CDP host to list open targets (pages, workers, etc). */
54
+ /** Names the path appended to the CDP host to list open targets (pages, workers, etc). */
44
55
  export declare const BROWSER_CDP_LIST_PATH = "/json/list";
45
56
 
46
- /** Protocol prefix for CDP discovery requests. */
57
+ /** Names the protocol prefix for CDP discovery requests. */
47
58
  export declare const BROWSER_CDP_PROTOCOL = "http";
48
59
 
49
- /** Path appended to the CDP host to fetch version metadata (endpoint discovery). */
60
+ /** Names the path appended to the CDP host to fetch version metadata (endpoint discovery). */
50
61
  export declare const BROWSER_CDP_VERSION_PATH = "/json/version";
51
62
 
52
- /** Default CDP port probed for an existing browser and used for launches. */
63
+ /** Sets the default CDP port probed for an existing browser and used for launches. */
53
64
  export declare const BROWSER_DEFAULT_CDP_PORT = 9222;
54
65
 
55
- /** Default host probed for an existing browser and used for launches (avoids `localhost` resolving to `::1` when Chromium binds `127.0.0.1`). */
66
+ /** Sets the default host probed for an existing browser and used for launches (avoids `localhost` resolving to `::1` when Chromium binds `127.0.0.1`). */
56
67
  export declare const BROWSER_DEFAULT_HOST = "127.0.0.1";
57
68
 
58
69
  /**
59
- * Case-insensitive substrings identifying an executable path/name's browser
70
+ * Lists the case-insensitive substrings identifying an executable path/name's browser
60
71
  * engine, checked by `parseBrowserEngine` in the order `edge` → `chromium` → `chrome`.
61
72
  */
62
73
  export declare const BROWSER_ENGINE_HINTS: Readonly<Record<BrowserEngine, readonly string[]>>;
63
74
 
64
- /** Environment variables checked (in order) for an explicit browser executable path override. */
75
+ /** Lists the environment variables checked (in order) for an explicit browser executable path override. */
65
76
  export declare const BROWSER_ENV_PATH_KEYS: readonly string[];
66
77
 
67
- /** Command names probed on PATH when no well-known executable path exists. */
78
+ /** Lists the command names probed on PATH when no well-known executable path exists. */
68
79
  export declare const BROWSER_EXECUTABLE_NAMES: readonly string[];
69
80
 
70
- /** Well-known Chrome/Chromium/Edge executable paths with no platform-specific root, keyed by `process.platform`. */
81
+ /** Lists the well-known Chrome/Chromium/Edge executable paths with no platform-specific root, keyed by `process.platform`. */
71
82
  export declare const BROWSER_EXECUTABLE_PATHS: Readonly<Record<string, readonly string[]>>;
72
83
 
73
- /** Flag enabling headless mode on a launched browser process. */
84
+ /** Names the flag that enables headless mode on a launched browser process. */
74
85
  export declare const BROWSER_HEADLESS_ARG = "--headless=new";
75
86
 
76
- /** Bound for each launched-process exit window during TERM-to-KILL teardown. */
87
+ /** Bounds each launched-process exit window during TERM-to-KILL teardown. */
77
88
  export declare const BROWSER_KILL_GRACE_MS = 3000;
78
89
 
79
- /** Flags always passed to a launched browser process, alongside the caller's own. */
90
+ /** Lists the flags always passed to a launched browser process, alongside the caller's own. */
80
91
  export declare const BROWSER_LAUNCH_ARGS: readonly string[];
81
92
 
82
- /** Bound for the `discover: false` port-occupancy probe before launching — short, since it only needs to detect an already-listening CDP endpoint, not perform full discovery. */
93
+ /** Bounds the `discover: false` port-occupancy probe before launching — short, because it only needs to detect an already-listening CDP endpoint, not perform full discovery. */
83
94
  export declare const BROWSER_PORT_PROBE_TIMEOUT_MS = 200;
84
95
 
85
- /** Machine-readable error-context cause for an owned browser process exiting. */
96
+ /** Names the machine-readable error-context cause for an owned browser process exiting. */
86
97
  export declare const BROWSER_PROCESS_EXIT_CAUSE = "process-exit";
87
98
 
88
- /** Prefix for isolated browser profiles created beneath the operating-system temp directory. */
99
+ /** Names the prefix for isolated browser profiles created beneath the operating-system temp directory. */
89
100
  export declare const BROWSER_PROFILE_PREFIX = "orkestrel-browser-";
90
101
 
91
- /** Per-OS default Playwright browser cache directory, relative to the home directory (win32 uses `LOCALAPPDATA` directly). */
102
+ /** Names the per-OS default Playwright browser cache directory, relative to the home directory (win32 uses `LOCALAPPDATA` directly). */
92
103
  export declare const BROWSER_STORE_CACHE_DIRS: Readonly<Record<string, string>>;
93
104
 
94
- /** Well-known Playwright browser store base directories checked in addition to `PLAYWRIGHT_BROWSERS_PATH`. */
105
+ /** Lists the well-known Playwright browser store base directories checked in addition to `PLAYWRIGHT_BROWSERS_PATH`. */
95
106
  export declare const BROWSER_STORE_DEFAULT_DIRS: readonly string[];
96
107
 
97
- /** Environment variable naming an additional Playwright browser store base directory. */
108
+ /** Names the environment variable that carries an additional Playwright browser store base directory. */
98
109
  export declare const BROWSER_STORE_ENV_KEY = "PLAYWRIGHT_BROWSERS_PATH";
99
110
 
100
- /** Glob pattern (relative to a store base) matching a versioned Chromium binary, keyed by `process.platform`. */
111
+ /** Names the glob pattern (relative to a store base) matching a versioned Chromium binary, keyed by `process.platform`. */
101
112
  export declare const BROWSER_STORE_GLOBS: Readonly<Record<string, string>>;
102
113
 
103
- /** Name of the top-level Chromium symlink/binary Playwright maintains inside a browser store base. */
114
+ /** Names the top-level Chromium symlink/binary Playwright maintains inside a browser store base. */
104
115
  export declare const BROWSER_STORE_LINK_NAME = "chromium";
105
116
 
106
- /** Machine-readable error-context cause for a CDP transport disconnecting while its browser remains alive. */
117
+ /** Names the machine-readable error-context cause for a CDP transport disconnecting while its browser remains alive. */
107
118
  export declare const BROWSER_TRANSPORT_LOSS_CAUSE = "transport-loss";
108
119
 
109
- /** Brief defer applied once when a transport loss is observed on an owned process, giving a near-simultaneous process-exit event (which libuv may reap slightly later than the socket close) first say over the diagnosis. */
120
+ /** Defers once, briefly, when a transport loss is observed on an owned process, giving a near-simultaneous process-exit event (which libuv may reap slightly later than the socket close) first say over the diagnosis. */
110
121
  export declare const BROWSER_TRANSPORT_LOSS_DEFER_MS = 50;
111
122
 
112
- /** Fallback Windows install roots used when the corresponding environment variable is absent. */
123
+ /** Lists the fallback Windows install roots used when the corresponding environment variable is absent. */
113
124
  export declare const BROWSER_WINDOWS_ROOT_FALLBACKS: Readonly<Record<string, string>>;
114
125
 
115
- /** Windows install-root-relative suffixes for Chrome/Edge/Chromium, joined against each candidate root (`PROGRAMFILES`, `PROGRAMFILES(X86)`, `LOCALAPPDATA`). */
126
+ /** Lists the Windows install-root-relative suffixes for Chrome/Edge/Chromium, joined against each candidate root (`PROGRAMFILES`, `PROGRAMFILES(X86)`, `LOCALAPPDATA`). */
116
127
  export declare const BROWSER_WINDOWS_SUFFIXES: readonly string[];
117
128
 
118
129
  /**
119
- * CDP (Chrome DevTools Protocol) connection configuration.
130
+ * Configures the CDP (Chrome DevTools Protocol) connection.
120
131
  *
121
132
  * @remarks
122
133
  * - `port` — port number to probe for an existing CDP endpoint (default `9222`)
@@ -137,47 +148,44 @@ export declare interface BrowserCDPOptions {
137
148
  readonly discover?: boolean;
138
149
  }
139
150
 
140
- /** How the browser connection was established. */
151
+ /** Names how the browser connection was established. */
141
152
  export declare type BrowserConnection = 'cdp' | 'launch' | 'persistent';
142
153
 
143
154
  /**
144
- * A CDP connection, discovery, or launch attempt failed.
155
+ * Reports that a CDP connection, discovery, or launch attempt failed.
145
156
  */
146
157
  export declare class BrowserConnectionError extends BrowserError {
147
158
  constructor(message: string, context?: Readonly<Record<string, unknown>>);
148
159
  }
149
160
 
150
161
  /**
151
- * An operation was attempted after the Browser was destroyed.
162
+ * Reports that an operation was attempted after the Browser was destroyed.
152
163
  */
153
164
  export declare class BrowserDestroyedError extends BrowserError {
154
165
  constructor(context?: Readonly<Record<string, unknown>>);
155
166
  }
156
167
 
157
168
  /**
158
- * Result of passive browser discovery.
169
+ * Describes the result of passive browser discovery.
159
170
  *
160
171
  * @remarks
161
172
  * Returned by `discover()` to report whether an existing browser is
162
- * reachable via CDP without actually connecting to it.
173
+ * reachable through CDP without actually connecting to it. A defined
174
+ * `endpoint` is the whole answer — no separate flag repeats it.
163
175
  *
164
- * - `found` — true when a browser responded on the CDP endpoint
165
- * - `endpoint` — the CDP WebSocket URL when found
176
+ * - `endpoint` — the CDP WebSocket URL, or undefined when nothing answered
166
177
  * - `browser` — browser product name reported by the endpoint
167
- * - `connection` — the connection mode that would be used
168
178
  */
169
179
  export declare interface BrowserDiscoveryResult {
170
- readonly found: boolean;
171
180
  readonly endpoint: string | undefined;
172
181
  readonly browser: string | undefined;
173
- readonly connection: BrowserConnection | undefined;
174
182
  }
175
183
 
176
- /** Supported browser engine (raw CDP targets Chromium-family browsers only). */
184
+ /** Names a supported browser engine (raw CDP targets Chromium-family browsers only). */
177
185
  export declare type BrowserEngine = 'chromium' | 'chrome' | 'edge';
178
186
 
179
187
  /**
180
- * Event map for a {@link BrowserInterface}.
188
+ * Maps the events a {@link BrowserInterface} emits.
181
189
  *
182
190
  * @remarks
183
191
  * - `idle` — no active connection (initial state, or after disconnect)
@@ -187,7 +195,8 @@ export declare type BrowserEngine = 'chromium' | 'chrome' | 'edge';
187
195
  * an external disconnect (process exit or transport loss); always preceded
188
196
  * by a coded `error` describing the cause
189
197
  * - `launch` — a new browser process was launched, carrying the engine
190
- * - `page` — a new page was created via the `create()` shortcut
198
+ * - `page` — a new page was created through the `create()` shortcut
199
+ * - `context` — an isolated browser context was created, carrying the context
191
200
  * - `error` — a connection or launch fault
192
201
  * - `destroy` — the browser and all resources were torn down
193
202
  */
@@ -204,13 +213,13 @@ export declare type BrowserEventMap = {
204
213
  };
205
214
 
206
215
  /**
207
- * Browser wrapper with discovery, connection management, and lifecycle control.
216
+ * Wraps a browser with discovery, connection management, and lifecycle control.
208
217
  *
209
218
  * @remarks
210
219
  * Encapsulates the full raw-CDP browser lifecycle behind a clean interface:
211
220
  *
212
221
  * **Connection strategy** (executed by `connect()`):
213
- * 1. If `cdp.endpoint` is set, connect directly via CDP
222
+ * 1. If `cdp.endpoint` is set, connect directly through CDP
214
223
  * 2. Probe `localhost:{cdp.port}` for an existing browser (passive discovery)
215
224
  * 3. If found, connect over CDP (preserves the existing browser session)
216
225
  * 4. Otherwise, launch a new browser process with raw-CDP flags
@@ -231,19 +240,23 @@ export declare type BrowserEventMap = {
231
240
  * process exiting on its own) drives the disconnected state, preceded by
232
241
  * a coded `error` — `connect()` on the same instance can reattach afterward.
233
242
  * - `destroy` — release local resources. On a launched browser this closes
234
- * pages/contexts, then kills and awaits the process plus its POSIX process
235
- * group. On an adopted browser it sends `Browser.close`. On a merely
243
+ * pages/contexts, then kills and awaits the process serving the CDP endpoint
244
+ * plus its POSIX process group. On an adopted browser it sends
245
+ * `Browser.close`. On a merely
236
246
  * attached browser this is a LOCAL DETACH ONLY because other clients may
237
247
  * share its targets. Idempotent.
238
248
  * - `close` — graceful REMOTE shutdown: best-effort sends CDP `Browser.close`
239
- * (works whether attached or owned), and when owned also awaits the
240
- * process's exit and POSIX group drain (escalating to a kill only if needed),
241
- * then performs the same local cleanup as `destroy()`. Use this to shut
242
- * down a browser this instance doesn't own but wants to terminate anyway.
249
+ * (works whether attached or owned), and when owned also awaits the exit of
250
+ * the process serving the CDP endpoint plus its POSIX process-group drain
251
+ * (escalating to a kill only if needed), then performs the same local cleanup
252
+ * as `destroy()`. Use this to shut down a browser this instance doesn't own
253
+ * but wants to terminate anyway.
243
254
  *
244
255
  * **Page management:**
245
256
  * - `context(index?)` → one context or first
246
257
  * - `contexts()` → all contexts
258
+ * - `isolate` — create and register an isolated CDP context with validated
259
+ * proxy, download, origin, and emulation options
247
260
  * - `create(options?)` → shortcut to open a page in the default context
248
261
  */
249
262
  export declare interface BrowserInterface {
@@ -252,26 +265,30 @@ export declare interface BrowserInterface {
252
265
  readonly status: BrowserStatus;
253
266
  readonly connection: BrowserConnection | undefined;
254
267
  /**
255
- * Whether this instance is responsible for terminating the represented browser.
268
+ * Reports whether this instance is responsible for terminating the represented browser.
256
269
  *
257
270
  * @remarks
258
271
  * `true` for launched and explicitly adopted sessions, `false` for an
259
272
  * active attachment, and `undefined` when no session is represented.
260
273
  */
261
274
  readonly owned: boolean | undefined;
262
- readonly connected: boolean;
263
275
  /**
264
- * The process this instance launched, if any, while it is believed alive.
276
+ * Reports the process serving this session's CDP endpoint, if any, while it is
277
+ * believed alive.
265
278
  *
266
279
  * @remarks
267
- * Remains readable after a persistent disconnect (the process keeps
268
- * running, detached from the transport) until `destroy()` or an
269
- * observed process exit clears it.
280
+ * A launch owns the process behind its endpoint rather than the process it
281
+ * spawned. The two are the same until the spawned process is a launcher
282
+ * that re-executes the browser and exits before the endpoint answers —
283
+ * Microsoft Edge on Windows — in which case this reports the process the
284
+ * launcher handed the endpoint to. Remains readable after a persistent
285
+ * disconnect (the process keeps running, detached from the transport)
286
+ * until `destroy()` or an observed process exit clears it.
270
287
  */
271
288
  readonly pid: number | undefined;
272
289
  discover(): Promise<BrowserDiscoveryResult>;
273
290
  connect(): Promise<void>;
274
- /** Assume responsibility for terminating the currently connected browser. */
291
+ /** Assumes responsibility for terminating the currently connected browser. */
275
292
  adopt(): void;
276
293
  disconnect(): Promise<void>;
277
294
  context(index?: number): BrowserContextInterface | undefined;
@@ -283,14 +300,14 @@ export declare interface BrowserInterface {
283
300
  }
284
301
 
285
302
  /**
286
- * An operation requiring an active connection was attempted while disconnected.
303
+ * Reports that an operation requiring an active connection was attempted while disconnected.
287
304
  */
288
305
  export declare class BrowserNotConnectedError extends BrowserError {
289
306
  constructor(context?: Readonly<Record<string, unknown>>);
290
307
  }
291
308
 
292
309
  /**
293
- * Options for creating a Browser.
310
+ * Describes the options for creating a Browser.
294
311
  *
295
312
  * @remarks
296
313
  * - `on` — initial event listeners wired at construction
@@ -327,7 +344,7 @@ export declare interface BrowserOptions {
327
344
  }
328
345
 
329
346
  /**
330
- * Resolved browser profile directory used for a Chromium-family launch.
347
+ * Describes the resolved browser profile directory used for a Chromium-family launch.
331
348
  *
332
349
  * @remarks
333
350
  * `temporary` is true only for an isolated profile created by
@@ -339,21 +356,30 @@ export declare interface BrowserProfileResult {
339
356
  readonly temporary: boolean;
340
357
  }
341
358
 
342
- /** Lifecycle status of a browser wrapper. */
359
+ /** Names the lifecycle status of a browser wrapper. */
343
360
  export declare type BrowserStatus = 'idle' | 'connecting' | 'connected' | 'disconnected' | 'error';
344
361
 
345
- /** Classify a `/json/version` `Browser` string into a {@link BrowserEngine} (`Edg/` → edge, `Chrome/` → chrome, else chromium). */
362
+ /** Classifies a `/json/version` `Browser` string into a {@link BrowserEngine} (`Edg/` → edge, `Chrome/` → chrome, else chromium). */
346
363
  export declare function browserToEngine(browser?: string): BrowserEngine;
347
364
 
365
+ /** Builds the default well-known install-path candidates for a platform, deriving Windows roots from env vars. */
366
+ export declare function buildInstallPaths(platform: string, env: Readonly<Record<string, string | undefined>>): readonly string[];
367
+
368
+ /** Builds the default Playwright browser store base directories to search for a managed Chromium. */
369
+ export declare function buildStoreBases(env: Readonly<Record<string, string | undefined>>, platform: string): readonly string[];
370
+
371
+ /** Derives Windows install roots from env vars, falling back to well-known literals when absent. */
372
+ export declare function buildWindowsRoots(env: Readonly<Record<string, string | undefined>>): readonly string[];
373
+
348
374
  /**
349
- * Create a raw-CDP Browser façade.
375
+ * Creates a raw-CDP Browser façade.
350
376
  *
351
377
  * @param options - Connection, launch, and viewport configuration
352
378
  * @returns A {@link BrowserInterface}
353
379
  *
354
380
  * @example
355
381
  * ```ts
356
- * import { createBrowser } from '@src/server'
382
+ * import { createBrowser } from '@orkestrel/browser/server'
357
383
  *
358
384
  * const browser = createBrowser()
359
385
  * await browser.connect()
@@ -362,7 +388,7 @@ export declare function browserToEngine(browser?: string): BrowserEngine;
362
388
  export declare function createBrowser(options?: BrowserOptions): BrowserInterface;
363
389
 
364
390
  /**
365
- * Resolve a persistent caller profile or create an isolated temporary one.
391
+ * Resolves a persistent caller profile or creates an isolated temporary one.
366
392
  *
367
393
  * @param path - Optional caller-owned persistent user-data directory
368
394
  * @returns The resolved profile and whether the library owns its lifecycle
@@ -370,56 +396,82 @@ export declare function createBrowser(options?: BrowserOptions): BrowserInterfac
370
396
  export declare function createBrowserProfile(path?: string): Promise<BrowserProfileResult>;
371
397
 
372
398
  /**
373
- * Create a Node `WebSocket`-backed CDP transport.
399
+ * Creates a filesystem-backed browser writer.
374
400
  *
375
- * @param options - The CDP WebSocket debugger URL (and optional timeout)
376
- * @returns A {@link CDPTransportInterface}
401
+ * @returns A {@link BrowserWriterInterface} that persists bytes through `node:fs/promises`
377
402
  */
378
- export declare function createCDPTransport(options: WebSocketCDPTransportOptions): CDPTransportInterface_2;
403
+ export declare function createBrowserWriter(): BrowserWriterInterface_2;
379
404
 
380
405
  /**
381
- * Create a filesystem-backed screenshot writer.
406
+ * Creates a Node `WebSocket`-backed CDP transport.
382
407
  *
383
- * @returns A {@link ScreenshotWriterInterface} that persists bytes via `node:fs/promises`
408
+ * @param options - The CDP WebSocket debugger URL (and optional timeout)
409
+ * @returns A {@link CDPTransportInterface}
384
410
  */
385
- export declare function createScreenshotWriter(): ScreenshotWriterInterface;
386
-
387
- /** Build the default well-known install-path candidates for a platform, deriving Windows roots from env vars. */
388
- export declare function defaultInstallPaths(platform: string, env: Readonly<Record<string, string | undefined>>): readonly string[];
389
-
390
- /** Build the default Playwright browser store base directories to search for a managed Chromium. */
391
- export declare function defaultStoreBases(env: Readonly<Record<string, string | undefined>>, platform: string): readonly string[];
411
+ export declare function createCDPTransport(options: WebSocketCDPTransportOptions): CDPTransportInterface_2;
392
412
 
393
413
  /**
394
- * Fetch the current CDP target list from a browser's `/json/list` endpoint.
414
+ * Fetches the current CDP target list from a browser's `/json/list` endpoint.
415
+ *
416
+ * @remarks
417
+ * The endpoint is a network boundary, so an unreachable host, a non-2xx
418
+ * response, and a body that is not a JSON array each come back as a failed
419
+ * `Result` carrying a coded `BrowserConnectionError`. An entry missing a
420
+ * required string field is skipped rather than failing the whole list.
395
421
  *
396
422
  * @param port - Port the browser exposes its CDP endpoint on
397
423
  * @param timeout - Request timeout in milliseconds
398
424
  * @param host - Host the browser exposes its CDP endpoint on (default `127.0.0.1`)
399
- * @returns Normalized CDP targets
425
+ * @returns The normalized CDP targets, or the fault that stopped the request
426
+ *
427
+ * @example
428
+ * ```ts
429
+ * import { fetchCDPTargets } from '@orkestrel/browser/server'
430
+ *
431
+ * const result = await fetchCDPTargets(9222, 2000)
432
+ * if (result.success) log(result.value.length)
433
+ * else log(result.error.code)
434
+ * ```
400
435
  */
401
- export declare function fetchCDPTargets(port: number, timeout: number, host?: string): Promise<readonly CDPTarget[]>;
436
+ export declare function fetchCDPTargets(port: number, timeout: number, host?: string): Promise<Result<readonly CDPTarget[], BrowserError>>;
402
437
 
403
- /** Check the env-override keys (`PLAYWRIGHT_EXECUTABLE_PATH`, `CHROME_PATH`) in order, returning every one that exists. */
404
- export declare function findAllEnvOverrides(env: Readonly<Record<string, string | undefined>>): readonly string[];
405
-
406
- /** Return every candidate path that exists on disk, in the given order. */
407
- export declare function findAllInstallPaths(paths: readonly string[]): readonly string[];
408
-
409
- /** Search one store base for the top-level `chromium` link and every `chromium-*` install, highest revision first. */
410
- export declare function findAllInStore(base: string, platform: string): readonly string[];
438
+ /**
439
+ * Persists captured browser bytes to the filesystem through `node:fs/promises`.
440
+ *
441
+ * @remarks
442
+ * Creates every missing parent directory of the target path before writing, so
443
+ * a caller may name a nested destination that does not exist yet.
444
+ *
445
+ * @example
446
+ * ```ts
447
+ * import { FileBrowserWriter } from '@orkestrel/browser/server'
448
+ *
449
+ * const writer = new FileBrowserWriter()
450
+ * await writer.write('shots/hero.png', new Uint8Array([137, 80, 78, 71]))
451
+ * ```
452
+ */
453
+ export declare class FileBrowserWriter implements BrowserWriterInterface {
454
+ /**
455
+ * Writes the captured bytes to a path, creating its parent directories.
456
+ *
457
+ * @param path - Destination file path
458
+ * @param data - Captured bytes to persist
459
+ * @returns A promise resolving once the bytes are on disk
460
+ */
461
+ write(path: string, data: Uint8Array): Promise<void>;
462
+ }
411
463
 
412
- /** Check the env-override keys (`PLAYWRIGHT_EXECUTABLE_PATH`, `CHROME_PATH`) in order for an existing file. */
413
- export declare function findEnvOverride(env: Readonly<Record<string, string | undefined>>): string | undefined;
464
+ /** Checks the env-override keys (`PLAYWRIGHT_EXECUTABLE_PATH`, `CHROME_PATH`) in order and returns every one that exists. */
465
+ export declare function findEnvOverrides(env: Readonly<Record<string, string | undefined>>): readonly string[];
414
466
 
415
- /** Return the first candidate path that exists on disk. */
416
- export declare function findInstallPath(paths: readonly string[]): string | undefined;
467
+ /** Returns every candidate path that exists on disk, in the given order. */
468
+ export declare function findInstallPaths(paths: readonly string[]): readonly string[];
417
469
 
418
- /** Search one store base for the top-level `chromium` link, else the highest-revision `chromium-*` install. */
419
- export declare function findInStore(base: string, platform: string): string | undefined;
470
+ /** Searches one store base for the top-level `chromium` link and every `chromium-*` install, highest revision first. */
471
+ export declare function findStorePaths(base: string, platform: string): readonly string[];
420
472
 
421
473
  /**
422
- * Locate a Chrome/Chromium/Edge executable on this machine — the first entry
474
+ * Locates a Chrome/Chromium/Edge executable on this machine — the first entry
423
475
  * of {@link findSystemBrowsers}.
424
476
  *
425
477
  * @param options - Overrides for the candidate sources; see {@link SystemBrowserOptions}
@@ -428,7 +480,7 @@ export declare function findInStore(base: string, platform: string): string | un
428
480
  export declare function findSystemBrowser(options?: SystemBrowserOptions): SystemBrowser | undefined;
429
481
 
430
482
  /**
431
- * Enumerate every Chrome/Chromium/Edge executable discoverable on this
483
+ * Enumerates every Chrome/Chromium/Edge executable discoverable on this
432
484
  * machine, deduplicated by normalized absolute path.
433
485
  *
434
486
  * @remarks
@@ -442,7 +494,7 @@ export declare function findSystemBrowser(options?: SystemBrowserOptions): Syste
442
494
  * and the per-OS Playwright cache directory) — the top-level `chromium`
443
495
  * link/binary, then the highest-revision `chromium-*` install found
444
496
  *
445
- * Each candidate is classified into a {@link BrowserEngine} via
497
+ * Each candidate is classified into a {@link BrowserEngine} through
446
498
  * `parseBrowserEngine` (unclassifiable candidates default to `'chromium'`),
447
499
  * and `options.engine` (when given) narrows the result to that engine.
448
500
  *
@@ -452,35 +504,40 @@ export declare function findSystemBrowser(options?: SystemBrowserOptions): Syste
452
504
  export declare function findSystemBrowsers(options?: SystemBrowserOptions): readonly SystemBrowser[];
453
505
 
454
506
  /**
455
- * Narrow an unknown value to BrowserConnectionError.
507
+ * Narrows an unknown value to BrowserConnectionError.
456
508
  *
457
509
  * @param value - Value to check
458
- * @returns True when value is a BrowserConnectionError instance
510
+ * @returns True if value is a BrowserConnectionError instance; false otherwise
459
511
  */
460
512
  export declare function isBrowserConnectionError(value: unknown): value is BrowserConnectionError;
461
513
 
462
514
  /**
463
- * Narrow an unknown value to BrowserDestroyedError.
515
+ * Narrows an unknown value to BrowserDestroyedError.
464
516
  *
465
517
  * @param value - Value to check
466
- * @returns True when value is a BrowserDestroyedError instance
518
+ * @returns True if value is a BrowserDestroyedError instance; false otherwise
467
519
  */
468
520
  export declare function isBrowserDestroyedError(value: unknown): value is BrowserDestroyedError;
469
521
 
470
522
  /**
471
- * Narrow an unknown value to BrowserNotConnectedError.
523
+ * Narrows an unknown value to BrowserNotConnectedError.
472
524
  *
473
525
  * @param value - Value to check
474
- * @returns True when value is a BrowserNotConnectedError instance
526
+ * @returns True if value is a BrowserNotConnectedError instance; false otherwise
475
527
  */
476
528
  export declare function isBrowserNotConnectedError(value: unknown): value is BrowserNotConnectedError;
477
529
 
478
530
  /**
479
- * Launch a browser process with raw-CDP debugging flags.
531
+ * Launches a browser process with raw-CDP debugging flags.
480
532
  *
481
533
  * @remarks
482
534
  * POSIX launches own an isolated process group so lifecycle teardown can
483
535
  * signal and await every Chromium subprocess without affecting the caller.
536
+ * Windows launches are not detached and own no group, so teardown there
537
+ * signals one process by identifier: the spawned process, or the process the
538
+ * launcher handed the endpoint to when that spawned process re-executed the
539
+ * browser and exited. Terminating a Chromium browser process takes its own
540
+ * subprocesses with it, so that single signal drains the tree.
484
541
  *
485
542
  * @param executable - Absolute path to the browser executable
486
543
  * @param port - Port the browser exposes its CDP endpoint on
@@ -491,11 +548,11 @@ export declare function isBrowserNotConnectedError(value: unknown): value is Bro
491
548
  */
492
549
  export declare function launchBrowserProcess(executable: string, port: number, headless: boolean, profile?: string, extra?: readonly string[]): ChildProcess;
493
550
 
494
- /** Normalize an executable path for cross-source deduplication (case-insensitive on Windows). */
551
+ /** Normalizes an executable path for cross-source deduplication (case-insensitive on Windows). */
495
552
  export declare function normalizeExecutablePath(path: string, platform: string): string;
496
553
 
497
554
  /**
498
- * Classify an executable path/name into a {@link BrowserEngine} by
555
+ * Classifies an executable path/name into a {@link BrowserEngine} by
499
556
  * case-insensitive hint, checked in the order edge → chromium → chrome.
500
557
  *
501
558
  * @param executable - Executable path or command name to classify
@@ -503,14 +560,30 @@ export declare function normalizeExecutablePath(path: string, platform: string):
503
560
  */
504
561
  export declare function parseBrowserEngine(executable: string): BrowserEngine | undefined;
505
562
 
506
- /** Probe PATH (`which`/`where`) for every resolvable command name, in the given order. */
507
- export declare function probeAllPathNames(names: readonly string[], platform: string): readonly string[];
563
+ /** Probes PATH (`which`/`where`) for every resolvable command name, in the given order. */
564
+ export declare function probePathNames(names: readonly string[], platform: string): readonly string[];
508
565
 
509
- /** Probe PATH (`which`/`where`) for the first resolvable command name. */
510
- export declare function probePathNames(names: readonly string[], platform: string): string | undefined;
566
+ /**
567
+ * Returns the first non-empty line of a command's output, without its
568
+ * surrounding whitespace.
569
+ *
570
+ * @remarks
571
+ * `where` reports every PATH match on its own CRLF-terminated line, so a
572
+ * carriage return left on the first line would travel into `existsSync` and
573
+ * `spawn` as part of the executable path.
574
+ *
575
+ * @param output - Raw decoded standard output of a command
576
+ * @returns The first line carrying text, or undefined when the output has none
577
+ *
578
+ * @example
579
+ * ```ts
580
+ * readFirstLine('C:\\bin\\chrome.exe\r\nC:\\other\\chrome.exe\r\n') // 'C:\\bin\\chrome.exe'
581
+ * ```
582
+ */
583
+ export declare function readFirstLine(output: string): string | undefined;
511
584
 
512
585
  /**
513
- * Remove a library-owned isolated browser profile.
586
+ * Removes a library-owned isolated browser profile.
514
587
  *
515
588
  * @remarks
516
589
  * The path must remain a direct child of the operating-system temp directory
@@ -522,7 +595,7 @@ export declare function probePathNames(names: readonly string[], platform: strin
522
595
  export declare function removeBrowserProfile(profile: BrowserProfileResult): Promise<void>;
523
596
 
524
597
  /**
525
- * One discovered browser executable on this machine.
598
+ * Represents one discovered browser executable on this machine.
526
599
  *
527
600
  * @remarks
528
601
  * Returned by `findSystemBrowsers`/`findSystemBrowser` — pairs the resolved
@@ -534,7 +607,7 @@ export declare type SystemBrowser = {
534
607
  };
535
608
 
536
609
  /**
537
- * Options overriding `findSystemBrowsers`'/`findSystemBrowser`'s candidate sources.
610
+ * Describes the options overriding `findSystemBrowsers`'/`findSystemBrowser`'s candidate sources.
538
611
  *
539
612
  * @remarks
540
613
  * Each field replaces the default candidate list for its category — a field
@@ -563,11 +636,12 @@ export declare interface SystemBrowserOptions {
563
636
  }
564
637
 
565
638
  /**
566
- * Poll a browser's CDP version endpoint until it responds or the timeout elapses.
639
+ * Polls a browser's CDP version endpoint until it responds or the timeout elapses.
567
640
  *
568
641
  * @param port - Port the browser exposes its CDP endpoint on
569
642
  * @param timeout - Maximum time to wait in milliseconds
570
643
  * @param host - Host the browser exposes its CDP endpoint on (default `127.0.0.1`)
644
+ * @param signal - Optional external abort; an abort while waiting rethrows rather than resolving
571
645
  * @returns The browser's WebSocket debugger URL
572
646
  *
573
647
  * @throws When the endpoint does not become ready before the timeout
@@ -575,13 +649,22 @@ export declare interface SystemBrowserOptions {
575
649
  export declare function waitForCDPReady(port: number, timeout: number, host?: string, signal?: AbortSignal): Promise<string>;
576
650
 
577
651
  /**
578
- * `@orkestrel/websocket`-backed raw CDP text transport.
652
+ * Provides a raw CDP text transport backed by `@orkestrel/websocket`.
579
653
  *
580
654
  * @remarks
581
655
  * Performs and validates the RFC 6455 HTTP upgrade, then delegates frame
582
656
  * handling to `@orkestrel/websocket`. Concurrent and repeated `start()` /
583
657
  * `close()` calls share their active transition, and a later `start()` opens a
584
658
  * fresh socket after the prior one closes.
659
+ *
660
+ * @example
661
+ * ```ts
662
+ * import { WebSocketCDPTransport } from '@orkestrel/browser/server'
663
+ *
664
+ * const transport = new WebSocketCDPTransport({ url: 'ws://127.0.0.1:9222/devtools/browser/abc' })
665
+ * await transport.start()
666
+ * await transport.close()
667
+ * ```
585
668
  */
586
669
  export declare class WebSocketCDPTransport implements CDPTransportInterface {
587
670
  #private;
@@ -593,7 +676,7 @@ export declare class WebSocketCDPTransport implements CDPTransportInterface {
593
676
  }
594
677
 
595
678
  /**
596
- * Options for creating a WebSocketCDPTransport.
679
+ * Describes the options for creating a WebSocketCDPTransport.
597
680
  *
598
681
  * @remarks
599
682
  * - `on` — initial event listeners wired at construction
@@ -608,7 +691,4 @@ export declare interface WebSocketCDPTransportOptions {
608
691
  readonly timeout?: number;
609
692
  }
610
693
 
611
- /** Derive Windows install roots from env vars, falling back to well-known literals when absent. */
612
- export declare function windowsRoots(env: Readonly<Record<string, string | undefined>>): readonly string[];
613
-
614
694
  export { }