browser-pilot 0.0.17 → 0.0.18

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/README.md CHANGED
@@ -143,6 +143,23 @@ bp env visibility hidden -s realtime
143
143
  - `listen` preserved as a compatibility alias to `trace tail`
144
144
  - `audio` for active control, `trace` for explanation, `env` for browser-state controls
145
145
 
146
+ ## Cloud provider
147
+
148
+ When local Chrome is not available, [Browser Use](https://browser-use.com) is the recommended cloud provider:
149
+
150
+ ```bash
151
+ BROWSER_USE_API_KEY=bu_... bp connect --provider browser-use
152
+ ```
153
+
154
+ ```typescript
155
+ const browser = await connect({
156
+ provider: 'browser-use',
157
+ apiKey: process.env.BROWSER_USE_API_KEY,
158
+ });
159
+ ```
160
+
161
+ See [Providers](./docs/providers.md) for BrowserBase, Browserless, and other options.
162
+
146
163
  ## Programmatic example
147
164
 
148
165
  ```typescript
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  Browser,
3
3
  connect
4
- } from "./chunk-IRLHCVNH.mjs";
4
+ } from "./chunk-FSB25GRR.mjs";
5
5
  import "./chunk-LCNFBXB5.mjs";
6
6
  import "./chunk-MRY3HRFJ.mjs";
7
7
  import "./chunk-DTVRFXKI.mjs";
package/dist/browser.cjs CHANGED
@@ -558,6 +558,108 @@ function buildCDPClient(transport, options = {}) {
558
558
  return client;
559
559
  }
560
560
 
561
+ // src/providers/browser-use.ts
562
+ var BrowserUseProvider = class {
563
+ name = "browser-use";
564
+ apiKey;
565
+ baseUrl;
566
+ proxyCountryCode;
567
+ profileId;
568
+ timeout;
569
+ allowResizing;
570
+ customProxy;
571
+ constructor(options) {
572
+ this.apiKey = options.apiKey;
573
+ this.baseUrl = options.baseUrl ?? "https://api.browser-use.com/api/v2";
574
+ this.proxyCountryCode = options.proxyCountryCode === void 0 ? "uk" : options.proxyCountryCode;
575
+ this.profileId = options.profileId;
576
+ this.timeout = options.timeout;
577
+ this.allowResizing = options.allowResizing;
578
+ this.customProxy = options.customProxy;
579
+ }
580
+ async createSession(options = {}) {
581
+ const body = {};
582
+ body["proxyCountryCode"] = this.proxyCountryCode;
583
+ if (options.width) body["browserScreenWidth"] = options.width;
584
+ if (options.height) body["browserScreenHeight"] = options.height;
585
+ if (this.profileId) body["profileId"] = this.profileId;
586
+ if (this.timeout !== void 0) body["timeout"] = this.timeout;
587
+ if (this.allowResizing !== void 0) body["allowResizing"] = this.allowResizing;
588
+ if (this.customProxy) body["customProxy"] = this.customProxy;
589
+ const response = await fetch(`${this.baseUrl}/browsers`, {
590
+ method: "POST",
591
+ headers: {
592
+ "X-Browser-Use-API-Key": this.apiKey,
593
+ "Content-Type": "application/json"
594
+ },
595
+ body: JSON.stringify(body)
596
+ });
597
+ if (!response.ok) {
598
+ const text = await response.text();
599
+ this.throwApiError(response.status, text);
600
+ }
601
+ const session = await response.json();
602
+ if (!session.cdpUrl) {
603
+ throw new Error("Browser Use session does not have a cdpUrl");
604
+ }
605
+ return this.toProviderSession(session);
606
+ }
607
+ async resumeSession(sessionId) {
608
+ const response = await fetch(`${this.baseUrl}/browsers/${sessionId}`, {
609
+ headers: {
610
+ "X-Browser-Use-API-Key": this.apiKey
611
+ }
612
+ });
613
+ if (!response.ok) {
614
+ const text = await response.text();
615
+ throw new Error(`Browser Use resumeSession failed: ${response.status} ${text}`);
616
+ }
617
+ const session = await response.json();
618
+ if (session.status !== "active" || !session.cdpUrl) {
619
+ throw new Error(
620
+ "Browser Use session is not active or does not have a cdpUrl (may be stopped)"
621
+ );
622
+ }
623
+ return this.toProviderSession(session);
624
+ }
625
+ toProviderSession(session) {
626
+ return {
627
+ wsUrl: session.cdpUrl,
628
+ sessionId: session.id,
629
+ metadata: {
630
+ liveUrl: session.liveUrl,
631
+ status: session.status,
632
+ timeoutAt: session.timeoutAt,
633
+ proxyCountryCode: this.proxyCountryCode
634
+ },
635
+ close: async () => {
636
+ await fetch(`${this.baseUrl}/browsers/${session.id}`, {
637
+ method: "PATCH",
638
+ headers: {
639
+ "X-Browser-Use-API-Key": this.apiKey,
640
+ "Content-Type": "application/json"
641
+ },
642
+ body: JSON.stringify({ action: "stop" })
643
+ });
644
+ }
645
+ };
646
+ }
647
+ throwApiError(status, body) {
648
+ switch (status) {
649
+ case 402:
650
+ throw new Error(`Browser Use: insufficient credits (min $0.10 required). ${body}`);
651
+ case 403:
652
+ throw new Error(`Browser Use: invalid API key. ${body}`);
653
+ case 422:
654
+ throw new Error(`Browser Use: validation error. ${body}`);
655
+ case 429:
656
+ throw new Error(`Browser Use: rate limit exceeded. ${body}`);
657
+ default:
658
+ throw new Error(`Browser Use createSession failed: ${status} ${body}`);
659
+ }
660
+ }
661
+ };
662
+
561
663
  // src/providers/browserbase.ts
562
664
  var BrowserBaseProvider = class {
563
665
  name = "browserbase";
@@ -1067,6 +1169,17 @@ async function resolveBrowserEndpoint(options = {}, deps = defaultDependencies)
1067
1169
  );
1068
1170
  }
1069
1171
 
1172
+ // src/runtime/env.ts
1173
+ function getProcessEnv() {
1174
+ if (typeof globalThis.process !== "undefined" && globalThis.process.env) {
1175
+ return globalThis.process.env;
1176
+ }
1177
+ return {};
1178
+ }
1179
+ function getEnv(name) {
1180
+ return getProcessEnv()[name];
1181
+ }
1182
+
1070
1183
  // src/providers/index.ts
1071
1184
  function createProvider(options) {
1072
1185
  switch (options.provider) {
@@ -1088,6 +1201,18 @@ function createProvider(options) {
1088
1201
  return new BrowserlessProvider({
1089
1202
  token: options.apiKey
1090
1203
  });
1204
+ case "browser-use": {
1205
+ const apiKey = options.apiKey ?? getEnv("BROWSER_USE_API_KEY");
1206
+ if (!apiKey) {
1207
+ throw new Error("Browser Use provider requires apiKey or BROWSER_USE_API_KEY env var");
1208
+ }
1209
+ return new BrowserUseProvider({
1210
+ apiKey,
1211
+ proxyCountryCode: options.proxyCountryCode === void 0 ? "uk" : options.proxyCountryCode,
1212
+ profileId: options.profileId,
1213
+ timeout: options.cloudTimeout
1214
+ });
1215
+ }
1091
1216
  case "generic":
1092
1217
  if (!options.wsUrl) {
1093
1218
  throw new Error("Generic provider requires wsUrl");
@@ -9474,6 +9599,9 @@ var Browser = class _Browser {
9474
9599
  }
9475
9600
  const provider = createProvider(connectOptions);
9476
9601
  const session = await provider.createSession(connectOptions.session);
9602
+ if (session.metadata?.["liveUrl"]) {
9603
+ console.error(`Live viewer: ${session.metadata["liveUrl"]}`);
9604
+ }
9477
9605
  const cdp = await createCDPClient(session.wsUrl, {
9478
9606
  debug: connectOptions.debug,
9479
9607
  timeout: connectOptions.timeout
@@ -1,6 +1,6 @@
1
1
  import { C as CDPClient } from './client-B5QBRgIy.cjs';
2
2
  import { TargetInfo as TargetInfo$1 } from './cdp.cjs';
3
- import { b as ConnectOptions } from './types-DeVSWhXj.cjs';
3
+ import { b as ConnectOptions } from './types-D2pJQpWs.cjs';
4
4
  import { W as Page, $ as SnapshotNode, c as Condition, O as OutcomeStatus, M as MatchedCondition } from './types-Yuybzq53.cjs';
5
5
  export { m as ActionOptions, n as ActionResult, o as ConsoleHandler, p as ConsoleMessage, q as ConsoleMessageType, r as CustomSelectConfig, D as DeltaChange, t as DeltaResult, u as Dialog, v as DialogHandler, w as DialogType, x as Download, E as ElementInfo, y as ElementNotFoundError, z as EmulationState, F as ErrorHandler, av as FailureHint, I as FileInput, J as FillOptions, K as FormField, L as FormOption, N as GeolocationOptions, Q as InteractiveElement, T as KeyValuePair, U as NavigationError, V as NetworkIdleOptions, X as PageError, Y as PageSnapshot, Z as PageState, _ as ReviewResult, a0 as SnapshotOptions, a1 as SubmitOptions, a2 as SummaryCard, a3 as TableData, a4 as TimeoutError, a5 as TypeOptions, a6 as UserAgentMetadata, a7 as UserAgentOptions, a8 as ViewportOptions, a9 as WaitForOptions, s as computeDelta, G as extractPageState, H as extractReview } from './types-Yuybzq53.cjs';
6
6
 
package/dist/browser.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { C as CDPClient } from './client-B5QBRgIy.js';
2
2
  import { TargetInfo as TargetInfo$1 } from './cdp.js';
3
- import { b as ConnectOptions } from './types-DeVSWhXj.js';
3
+ import { b as ConnectOptions } from './types-D2pJQpWs.js';
4
4
  import { W as Page, $ as SnapshotNode, c as Condition, O as OutcomeStatus, M as MatchedCondition } from './types-B_v62K7C.js';
5
5
  export { m as ActionOptions, n as ActionResult, o as ConsoleHandler, p as ConsoleMessage, q as ConsoleMessageType, r as CustomSelectConfig, D as DeltaChange, t as DeltaResult, u as Dialog, v as DialogHandler, w as DialogType, x as Download, E as ElementInfo, y as ElementNotFoundError, z as EmulationState, F as ErrorHandler, av as FailureHint, I as FileInput, J as FillOptions, K as FormField, L as FormOption, N as GeolocationOptions, Q as InteractiveElement, T as KeyValuePair, U as NavigationError, V as NetworkIdleOptions, X as PageError, Y as PageSnapshot, Z as PageState, _ as ReviewResult, a0 as SnapshotOptions, a1 as SubmitOptions, a2 as SummaryCard, a3 as TableData, a4 as TimeoutError, a5 as TypeOptions, a6 as UserAgentMetadata, a7 as UserAgentOptions, a8 as ViewportOptions, a9 as WaitForOptions, s as computeDelta, G as extractPageState, H as extractReview } from './types-B_v62K7C.js';
6
6
 
package/dist/browser.mjs CHANGED
@@ -14,8 +14,8 @@ import {
14
14
  recoverPinnedTarget,
15
15
  recoverStaleRef,
16
16
  submitAndVerify
17
- } from "./chunk-FEEGNSHB.mjs";
18
- import "./chunk-EZNZ72VA.mjs";
17
+ } from "./chunk-SW52ALBD.mjs";
18
+ import "./chunk-ASEIFKKV.mjs";
19
19
  import "./chunk-BVZALQT4.mjs";
20
20
  import {
21
21
  ElementNotFoundError,
@@ -2,6 +2,108 @@ import {
2
2
  createCDPClient
3
3
  } from "./chunk-BVZALQT4.mjs";
4
4
 
5
+ // src/providers/browser-use.ts
6
+ var BrowserUseProvider = class {
7
+ name = "browser-use";
8
+ apiKey;
9
+ baseUrl;
10
+ proxyCountryCode;
11
+ profileId;
12
+ timeout;
13
+ allowResizing;
14
+ customProxy;
15
+ constructor(options) {
16
+ this.apiKey = options.apiKey;
17
+ this.baseUrl = options.baseUrl ?? "https://api.browser-use.com/api/v2";
18
+ this.proxyCountryCode = options.proxyCountryCode === void 0 ? "uk" : options.proxyCountryCode;
19
+ this.profileId = options.profileId;
20
+ this.timeout = options.timeout;
21
+ this.allowResizing = options.allowResizing;
22
+ this.customProxy = options.customProxy;
23
+ }
24
+ async createSession(options = {}) {
25
+ const body = {};
26
+ body["proxyCountryCode"] = this.proxyCountryCode;
27
+ if (options.width) body["browserScreenWidth"] = options.width;
28
+ if (options.height) body["browserScreenHeight"] = options.height;
29
+ if (this.profileId) body["profileId"] = this.profileId;
30
+ if (this.timeout !== void 0) body["timeout"] = this.timeout;
31
+ if (this.allowResizing !== void 0) body["allowResizing"] = this.allowResizing;
32
+ if (this.customProxy) body["customProxy"] = this.customProxy;
33
+ const response = await fetch(`${this.baseUrl}/browsers`, {
34
+ method: "POST",
35
+ headers: {
36
+ "X-Browser-Use-API-Key": this.apiKey,
37
+ "Content-Type": "application/json"
38
+ },
39
+ body: JSON.stringify(body)
40
+ });
41
+ if (!response.ok) {
42
+ const text = await response.text();
43
+ this.throwApiError(response.status, text);
44
+ }
45
+ const session = await response.json();
46
+ if (!session.cdpUrl) {
47
+ throw new Error("Browser Use session does not have a cdpUrl");
48
+ }
49
+ return this.toProviderSession(session);
50
+ }
51
+ async resumeSession(sessionId) {
52
+ const response = await fetch(`${this.baseUrl}/browsers/${sessionId}`, {
53
+ headers: {
54
+ "X-Browser-Use-API-Key": this.apiKey
55
+ }
56
+ });
57
+ if (!response.ok) {
58
+ const text = await response.text();
59
+ throw new Error(`Browser Use resumeSession failed: ${response.status} ${text}`);
60
+ }
61
+ const session = await response.json();
62
+ if (session.status !== "active" || !session.cdpUrl) {
63
+ throw new Error(
64
+ "Browser Use session is not active or does not have a cdpUrl (may be stopped)"
65
+ );
66
+ }
67
+ return this.toProviderSession(session);
68
+ }
69
+ toProviderSession(session) {
70
+ return {
71
+ wsUrl: session.cdpUrl,
72
+ sessionId: session.id,
73
+ metadata: {
74
+ liveUrl: session.liveUrl,
75
+ status: session.status,
76
+ timeoutAt: session.timeoutAt,
77
+ proxyCountryCode: this.proxyCountryCode
78
+ },
79
+ close: async () => {
80
+ await fetch(`${this.baseUrl}/browsers/${session.id}`, {
81
+ method: "PATCH",
82
+ headers: {
83
+ "X-Browser-Use-API-Key": this.apiKey,
84
+ "Content-Type": "application/json"
85
+ },
86
+ body: JSON.stringify({ action: "stop" })
87
+ });
88
+ }
89
+ };
90
+ }
91
+ throwApiError(status, body) {
92
+ switch (status) {
93
+ case 402:
94
+ throw new Error(`Browser Use: insufficient credits (min $0.10 required). ${body}`);
95
+ case 403:
96
+ throw new Error(`Browser Use: invalid API key. ${body}`);
97
+ case 422:
98
+ throw new Error(`Browser Use: validation error. ${body}`);
99
+ case 429:
100
+ throw new Error(`Browser Use: rate limit exceeded. ${body}`);
101
+ default:
102
+ throw new Error(`Browser Use createSession failed: ${status} ${body}`);
103
+ }
104
+ }
105
+ };
106
+
5
107
  // src/providers/browserbase.ts
6
108
  var BrowserBaseProvider = class {
7
109
  name = "browserbase";
@@ -514,6 +616,17 @@ async function resolveBrowserEndpoint(options = {}, deps = defaultDependencies)
514
616
  );
515
617
  }
516
618
 
619
+ // src/runtime/env.ts
620
+ function getProcessEnv() {
621
+ if (typeof globalThis.process !== "undefined" && globalThis.process.env) {
622
+ return globalThis.process.env;
623
+ }
624
+ return {};
625
+ }
626
+ function getEnv(name) {
627
+ return getProcessEnv()[name];
628
+ }
629
+
517
630
  // src/providers/index.ts
518
631
  function createProvider(options) {
519
632
  switch (options.provider) {
@@ -535,6 +648,18 @@ function createProvider(options) {
535
648
  return new BrowserlessProvider({
536
649
  token: options.apiKey
537
650
  });
651
+ case "browser-use": {
652
+ const apiKey = options.apiKey ?? getEnv("BROWSER_USE_API_KEY");
653
+ if (!apiKey) {
654
+ throw new Error("Browser Use provider requires apiKey or BROWSER_USE_API_KEY env var");
655
+ }
656
+ return new BrowserUseProvider({
657
+ apiKey,
658
+ proxyCountryCode: options.proxyCountryCode === void 0 ? "uk" : options.proxyCountryCode,
659
+ profileId: options.profileId,
660
+ timeout: options.cloudTimeout
661
+ });
662
+ }
538
663
  case "generic":
539
664
  if (!options.wsUrl) {
540
665
  throw new Error("Generic provider requires wsUrl");
@@ -548,6 +673,7 @@ function createProvider(options) {
548
673
  }
549
674
 
550
675
  export {
676
+ BrowserUseProvider,
551
677
  BrowserBaseProvider,
552
678
  BrowserlessProvider,
553
679
  GenericProvider,
@@ -5,6 +5,108 @@ import {
5
5
  Page
6
6
  } from "./chunk-MRY3HRFJ.mjs";
7
7
 
8
+ // src/providers/browser-use.ts
9
+ var BrowserUseProvider = class {
10
+ name = "browser-use";
11
+ apiKey;
12
+ baseUrl;
13
+ proxyCountryCode;
14
+ profileId;
15
+ timeout;
16
+ allowResizing;
17
+ customProxy;
18
+ constructor(options) {
19
+ this.apiKey = options.apiKey;
20
+ this.baseUrl = options.baseUrl ?? "https://api.browser-use.com/api/v2";
21
+ this.proxyCountryCode = options.proxyCountryCode === void 0 ? "uk" : options.proxyCountryCode;
22
+ this.profileId = options.profileId;
23
+ this.timeout = options.timeout;
24
+ this.allowResizing = options.allowResizing;
25
+ this.customProxy = options.customProxy;
26
+ }
27
+ async createSession(options = {}) {
28
+ const body = {};
29
+ body["proxyCountryCode"] = this.proxyCountryCode;
30
+ if (options.width) body["browserScreenWidth"] = options.width;
31
+ if (options.height) body["browserScreenHeight"] = options.height;
32
+ if (this.profileId) body["profileId"] = this.profileId;
33
+ if (this.timeout !== void 0) body["timeout"] = this.timeout;
34
+ if (this.allowResizing !== void 0) body["allowResizing"] = this.allowResizing;
35
+ if (this.customProxy) body["customProxy"] = this.customProxy;
36
+ const response = await fetch(`${this.baseUrl}/browsers`, {
37
+ method: "POST",
38
+ headers: {
39
+ "X-Browser-Use-API-Key": this.apiKey,
40
+ "Content-Type": "application/json"
41
+ },
42
+ body: JSON.stringify(body)
43
+ });
44
+ if (!response.ok) {
45
+ const text = await response.text();
46
+ this.throwApiError(response.status, text);
47
+ }
48
+ const session = await response.json();
49
+ if (!session.cdpUrl) {
50
+ throw new Error("Browser Use session does not have a cdpUrl");
51
+ }
52
+ return this.toProviderSession(session);
53
+ }
54
+ async resumeSession(sessionId) {
55
+ const response = await fetch(`${this.baseUrl}/browsers/${sessionId}`, {
56
+ headers: {
57
+ "X-Browser-Use-API-Key": this.apiKey
58
+ }
59
+ });
60
+ if (!response.ok) {
61
+ const text = await response.text();
62
+ throw new Error(`Browser Use resumeSession failed: ${response.status} ${text}`);
63
+ }
64
+ const session = await response.json();
65
+ if (session.status !== "active" || !session.cdpUrl) {
66
+ throw new Error(
67
+ "Browser Use session is not active or does not have a cdpUrl (may be stopped)"
68
+ );
69
+ }
70
+ return this.toProviderSession(session);
71
+ }
72
+ toProviderSession(session) {
73
+ return {
74
+ wsUrl: session.cdpUrl,
75
+ sessionId: session.id,
76
+ metadata: {
77
+ liveUrl: session.liveUrl,
78
+ status: session.status,
79
+ timeoutAt: session.timeoutAt,
80
+ proxyCountryCode: this.proxyCountryCode
81
+ },
82
+ close: async () => {
83
+ await fetch(`${this.baseUrl}/browsers/${session.id}`, {
84
+ method: "PATCH",
85
+ headers: {
86
+ "X-Browser-Use-API-Key": this.apiKey,
87
+ "Content-Type": "application/json"
88
+ },
89
+ body: JSON.stringify({ action: "stop" })
90
+ });
91
+ }
92
+ };
93
+ }
94
+ throwApiError(status, body) {
95
+ switch (status) {
96
+ case 402:
97
+ throw new Error(`Browser Use: insufficient credits (min $0.10 required). ${body}`);
98
+ case 403:
99
+ throw new Error(`Browser Use: invalid API key. ${body}`);
100
+ case 422:
101
+ throw new Error(`Browser Use: validation error. ${body}`);
102
+ case 429:
103
+ throw new Error(`Browser Use: rate limit exceeded. ${body}`);
104
+ default:
105
+ throw new Error(`Browser Use createSession failed: ${status} ${body}`);
106
+ }
107
+ }
108
+ };
109
+
8
110
  // src/providers/browserbase.ts
9
111
  var BrowserBaseProvider = class {
10
112
  name = "browserbase";
@@ -514,6 +616,17 @@ async function resolveBrowserEndpoint(options = {}, deps = defaultDependencies)
514
616
  );
515
617
  }
516
618
 
619
+ // src/runtime/env.ts
620
+ function getProcessEnv() {
621
+ if (typeof globalThis.process !== "undefined" && globalThis.process.env) {
622
+ return globalThis.process.env;
623
+ }
624
+ return {};
625
+ }
626
+ function getEnv(name) {
627
+ return getProcessEnv()[name];
628
+ }
629
+
517
630
  // src/providers/index.ts
518
631
  function createProvider(options) {
519
632
  switch (options.provider) {
@@ -535,6 +648,18 @@ function createProvider(options) {
535
648
  return new BrowserlessProvider({
536
649
  token: options.apiKey
537
650
  });
651
+ case "browser-use": {
652
+ const apiKey = options.apiKey ?? getEnv("BROWSER_USE_API_KEY");
653
+ if (!apiKey) {
654
+ throw new Error("Browser Use provider requires apiKey or BROWSER_USE_API_KEY env var");
655
+ }
656
+ return new BrowserUseProvider({
657
+ apiKey,
658
+ proxyCountryCode: options.proxyCountryCode === void 0 ? "uk" : options.proxyCountryCode,
659
+ profileId: options.profileId,
660
+ timeout: options.cloudTimeout
661
+ });
662
+ }
538
663
  case "generic":
539
664
  if (!options.wsUrl) {
540
665
  throw new Error("Generic provider requires wsUrl");
@@ -611,6 +736,9 @@ var Browser = class _Browser {
611
736
  }
612
737
  const provider = createProvider(connectOptions);
613
738
  const session = await provider.createSession(connectOptions.session);
739
+ if (session.metadata?.["liveUrl"]) {
740
+ console.error(`Live viewer: ${session.metadata["liveUrl"]}`);
741
+ }
614
742
  const cdp = await createCDPClient(session.wsUrl, {
615
743
  debug: connectOptions.debug,
616
744
  timeout: connectOptions.timeout
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createProvider,
3
3
  resolveBrowserEndpoint
4
- } from "./chunk-EZNZ72VA.mjs";
4
+ } from "./chunk-ASEIFKKV.mjs";
5
5
  import {
6
6
  createCDPClient,
7
7
  stringifyUnknown
@@ -5666,6 +5666,9 @@ var Browser = class _Browser {
5666
5666
  }
5667
5667
  const provider = createProvider(connectOptions);
5668
5668
  const session = await provider.createSession(connectOptions.session);
5669
+ if (session.metadata?.["liveUrl"]) {
5670
+ console.error(`Live viewer: ${session.metadata["liveUrl"]}`);
5671
+ }
5669
5672
  const cdp = await createCDPClient(session.wsUrl, {
5670
5673
  debug: connectOptions.debug,
5671
5674
  timeout: connectOptions.timeout
package/dist/cli.mjs CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  BrowserEndpointResolutionError,
6
6
  connect,
7
7
  resolveBrowserEndpoint
8
- } from "./chunk-IRLHCVNH.mjs";
8
+ } from "./chunk-FSB25GRR.mjs";
9
9
  import "./chunk-LCNFBXB5.mjs";
10
10
  import {
11
11
  DEEP_QUERY_SCRIPT,
@@ -2186,7 +2186,7 @@ Usage:
2186
2186
  bp connect [options]
2187
2187
 
2188
2188
  Local options:
2189
- -p, --provider <type> Provider: generic | browserbase | browserless (default: generic)
2189
+ -p, --provider <type> Provider: generic | browserbase | browserless | browser-use (default: generic)
2190
2190
  --browser-url <ws-url> Explicit browser WebSocket URL (preferred)
2191
2191
  --page-url <url> Page URL to open in the attached tab/new tab (preferred)
2192
2192
  --url <value> Compatibility shorthand; browser URL, or page URL with --new-tab
@@ -2199,6 +2199,9 @@ Local options:
2199
2199
  --target-url <str> Filter targets to those whose URL contains this string
2200
2200
  --api-key <key> API key for cloud providers
2201
2201
  --project-id <id> Project ID for BrowserBase provider
2202
+ --proxy-country <code> Proxy country code for browser-use (default: uk)
2203
+ --profile-id <id> Browser profile ID for browser-use
2204
+ --cloud-timeout <mins> Session timeout in minutes for browser-use (max 240)
2202
2205
  --export-log <path> Export session log to file on close
2203
2206
  --record Enable screenshot recording for all subsequent exec calls
2204
2207
  --record-format <fmt> Screenshot format: webp (default), png, jpeg
@@ -2224,6 +2227,10 @@ Examples:
2224
2227
  bp connect --record # Connect with session-level recording
2225
2228
  bp connect --new-tab --page-url https://example.com
2226
2229
  bp connect --no-daemon # Connect without daemon (file-based only)
2230
+ bp connect --provider browser-use # UK proxy (default)
2231
+ bp connect --provider browser-use --proxy-country de # German proxy
2232
+ bp connect --provider browser-use --proxy-country null # No proxy
2233
+ bp connect --provider browser-use --cloud-timeout 30 # 30-min session
2227
2234
 
2228
2235
  Likely next commands:
2229
2236
  bp exec -s dev '{"action":"goto","url":"https://example.com"}'
@@ -2251,9 +2258,9 @@ function parseConnectArgs(args) {
2251
2258
  const arg = args[i];
2252
2259
  if (arg === "--provider" || arg === "-p") {
2253
2260
  const p = args[++i];
2254
- if (p !== "browserbase" && p !== "browserless" && p !== "generic") {
2261
+ if (p !== "browserbase" && p !== "browserless" && p !== "browser-use" && p !== "generic") {
2255
2262
  throw new Error(
2256
- `Invalid provider: ${p}. Must be one of: browserbase, browserless, generic`
2263
+ `Invalid provider: ${p}. Must be one of: browserbase, browserless, browser-use, generic`
2257
2264
  );
2258
2265
  }
2259
2266
  options.provider = p;
@@ -2307,6 +2314,17 @@ function parseConnectArgs(args) {
2307
2314
  options.noDaemon = true;
2308
2315
  } else if (arg === "--daemon-idle") {
2309
2316
  options.daemonIdleMins = parseInt(args[++i] ?? "60", 10);
2317
+ } else if (arg === "--proxy-country") {
2318
+ const val = args[++i];
2319
+ options.proxyCountry = val === "null" ? null : val;
2320
+ } else if (arg === "--profile-id") {
2321
+ options.profileId = args[++i];
2322
+ } else if (arg === "--cloud-timeout") {
2323
+ const mins = parseInt(args[++i] ?? "", 10);
2324
+ if (Number.isNaN(mins) || mins < 1 || mins > 240) {
2325
+ throw new Error("--cloud-timeout must be 1-240 minutes");
2326
+ }
2327
+ options.cloudTimeout = mins;
2310
2328
  }
2311
2329
  }
2312
2330
  return options;
@@ -2381,7 +2399,10 @@ async function connectCommand(args, globalOptions) {
2381
2399
  channel: options.channel,
2382
2400
  userDataDir: options.userDataDir,
2383
2401
  apiKey: options.apiKey,
2384
- projectId: options.projectId
2402
+ projectId: options.projectId,
2403
+ proxyCountryCode: options.proxyCountry,
2404
+ profileId: options.profileId,
2405
+ cloudTimeout: options.cloudTimeout
2385
2406
  };
2386
2407
  const browser = await connect(connectOptions);
2387
2408
  const page = options.newTab ? await browser.newPage(pageUrl ?? "about:blank") : await browser.page(
@@ -2389,6 +2410,11 @@ async function connectCommand(args, globalOptions) {
2389
2410
  options.targetUrl ? { targetUrl: options.targetUrl } : void 0
2390
2411
  );
2391
2412
  const currentUrl = await resolveInitialPageUrl(page, pageUrl);
2413
+ if (browser.metadata?.["liveUrl"]) {
2414
+ console.error(`
2415
+ Live viewer: ${browser.metadata["liveUrl"]}
2416
+ `);
2417
+ }
2392
2418
  const sessionId = options.name ?? generateSessionId();
2393
2419
  let recordSettings;
2394
2420
  if (options.record) {
@@ -4148,7 +4174,7 @@ async function attachSession(session, options = {}) {
4148
4174
  const cdp = createCDPClientFromTransport(transport, {
4149
4175
  debug: options.trace
4150
4176
  });
4151
- const { Browser: BrowserClass } = await import("./browser-4ZHNAQR5.mjs");
4177
+ const { Browser: BrowserClass } = await import("./browser-GHQRYU4R.mjs");
4152
4178
  const { Page: PageClass } = await import("./page-SD64DY3F.mjs");
4153
4179
  const browser2 = BrowserClass.fromCDP(cdp, session);
4154
4180
  const page2 = session.daemon.cdpSessionId && session.targetId ? addBatchToPage(
@@ -8294,7 +8320,7 @@ function getCliVersion() {
8294
8320
  if (cachedCliVersion) {
8295
8321
  return cachedCliVersion;
8296
8322
  }
8297
- cachedCliVersion = "0.0.17";
8323
+ cachedCliVersion = "0.0.18";
8298
8324
  return cachedCliVersion;
8299
8325
  }
8300
8326
 
package/dist/index.cjs CHANGED
@@ -239,6 +239,7 @@ __export(src_exports, {
239
239
  Browser: () => Browser,
240
240
  BrowserBaseProvider: () => BrowserBaseProvider,
241
241
  BrowserEndpointResolutionError: () => BrowserEndpointResolutionError,
242
+ BrowserUseProvider: () => BrowserUseProvider,
242
243
  BrowserlessProvider: () => BrowserlessProvider,
243
244
  CDPError: () => CDPError,
244
245
  ElementNotFoundError: () => ElementNotFoundError,
@@ -5661,6 +5662,108 @@ function buildCDPClient(transport, options = {}) {
5661
5662
  return client;
5662
5663
  }
5663
5664
 
5665
+ // src/providers/browser-use.ts
5666
+ var BrowserUseProvider = class {
5667
+ name = "browser-use";
5668
+ apiKey;
5669
+ baseUrl;
5670
+ proxyCountryCode;
5671
+ profileId;
5672
+ timeout;
5673
+ allowResizing;
5674
+ customProxy;
5675
+ constructor(options) {
5676
+ this.apiKey = options.apiKey;
5677
+ this.baseUrl = options.baseUrl ?? "https://api.browser-use.com/api/v2";
5678
+ this.proxyCountryCode = options.proxyCountryCode === void 0 ? "uk" : options.proxyCountryCode;
5679
+ this.profileId = options.profileId;
5680
+ this.timeout = options.timeout;
5681
+ this.allowResizing = options.allowResizing;
5682
+ this.customProxy = options.customProxy;
5683
+ }
5684
+ async createSession(options = {}) {
5685
+ const body = {};
5686
+ body["proxyCountryCode"] = this.proxyCountryCode;
5687
+ if (options.width) body["browserScreenWidth"] = options.width;
5688
+ if (options.height) body["browserScreenHeight"] = options.height;
5689
+ if (this.profileId) body["profileId"] = this.profileId;
5690
+ if (this.timeout !== void 0) body["timeout"] = this.timeout;
5691
+ if (this.allowResizing !== void 0) body["allowResizing"] = this.allowResizing;
5692
+ if (this.customProxy) body["customProxy"] = this.customProxy;
5693
+ const response = await fetch(`${this.baseUrl}/browsers`, {
5694
+ method: "POST",
5695
+ headers: {
5696
+ "X-Browser-Use-API-Key": this.apiKey,
5697
+ "Content-Type": "application/json"
5698
+ },
5699
+ body: JSON.stringify(body)
5700
+ });
5701
+ if (!response.ok) {
5702
+ const text = await response.text();
5703
+ this.throwApiError(response.status, text);
5704
+ }
5705
+ const session = await response.json();
5706
+ if (!session.cdpUrl) {
5707
+ throw new Error("Browser Use session does not have a cdpUrl");
5708
+ }
5709
+ return this.toProviderSession(session);
5710
+ }
5711
+ async resumeSession(sessionId) {
5712
+ const response = await fetch(`${this.baseUrl}/browsers/${sessionId}`, {
5713
+ headers: {
5714
+ "X-Browser-Use-API-Key": this.apiKey
5715
+ }
5716
+ });
5717
+ if (!response.ok) {
5718
+ const text = await response.text();
5719
+ throw new Error(`Browser Use resumeSession failed: ${response.status} ${text}`);
5720
+ }
5721
+ const session = await response.json();
5722
+ if (session.status !== "active" || !session.cdpUrl) {
5723
+ throw new Error(
5724
+ "Browser Use session is not active or does not have a cdpUrl (may be stopped)"
5725
+ );
5726
+ }
5727
+ return this.toProviderSession(session);
5728
+ }
5729
+ toProviderSession(session) {
5730
+ return {
5731
+ wsUrl: session.cdpUrl,
5732
+ sessionId: session.id,
5733
+ metadata: {
5734
+ liveUrl: session.liveUrl,
5735
+ status: session.status,
5736
+ timeoutAt: session.timeoutAt,
5737
+ proxyCountryCode: this.proxyCountryCode
5738
+ },
5739
+ close: async () => {
5740
+ await fetch(`${this.baseUrl}/browsers/${session.id}`, {
5741
+ method: "PATCH",
5742
+ headers: {
5743
+ "X-Browser-Use-API-Key": this.apiKey,
5744
+ "Content-Type": "application/json"
5745
+ },
5746
+ body: JSON.stringify({ action: "stop" })
5747
+ });
5748
+ }
5749
+ };
5750
+ }
5751
+ throwApiError(status, body) {
5752
+ switch (status) {
5753
+ case 402:
5754
+ throw new Error(`Browser Use: insufficient credits (min $0.10 required). ${body}`);
5755
+ case 403:
5756
+ throw new Error(`Browser Use: invalid API key. ${body}`);
5757
+ case 422:
5758
+ throw new Error(`Browser Use: validation error. ${body}`);
5759
+ case 429:
5760
+ throw new Error(`Browser Use: rate limit exceeded. ${body}`);
5761
+ default:
5762
+ throw new Error(`Browser Use createSession failed: ${status} ${body}`);
5763
+ }
5764
+ }
5765
+ };
5766
+
5664
5767
  // src/providers/browserbase.ts
5665
5768
  var BrowserBaseProvider = class {
5666
5769
  name = "browserbase";
@@ -6173,6 +6276,17 @@ async function resolveBrowserEndpoint(options = {}, deps = defaultDependencies)
6173
6276
  );
6174
6277
  }
6175
6278
 
6279
+ // src/runtime/env.ts
6280
+ function getProcessEnv() {
6281
+ if (typeof globalThis.process !== "undefined" && globalThis.process.env) {
6282
+ return globalThis.process.env;
6283
+ }
6284
+ return {};
6285
+ }
6286
+ function getEnv(name) {
6287
+ return getProcessEnv()[name];
6288
+ }
6289
+
6176
6290
  // src/providers/index.ts
6177
6291
  function createProvider(options) {
6178
6292
  switch (options.provider) {
@@ -6194,6 +6308,18 @@ function createProvider(options) {
6194
6308
  return new BrowserlessProvider({
6195
6309
  token: options.apiKey
6196
6310
  });
6311
+ case "browser-use": {
6312
+ const apiKey = options.apiKey ?? getEnv("BROWSER_USE_API_KEY");
6313
+ if (!apiKey) {
6314
+ throw new Error("Browser Use provider requires apiKey or BROWSER_USE_API_KEY env var");
6315
+ }
6316
+ return new BrowserUseProvider({
6317
+ apiKey,
6318
+ proxyCountryCode: options.proxyCountryCode === void 0 ? "uk" : options.proxyCountryCode,
6319
+ profileId: options.profileId,
6320
+ timeout: options.cloudTimeout
6321
+ });
6322
+ }
6197
6323
  case "generic":
6198
6324
  if (!options.wsUrl) {
6199
6325
  throw new Error("Generic provider requires wsUrl");
@@ -10543,6 +10669,9 @@ var Browser = class _Browser {
10543
10669
  }
10544
10670
  const provider = createProvider(connectOptions);
10545
10671
  const session = await provider.createSession(connectOptions.session);
10672
+ if (session.metadata?.["liveUrl"]) {
10673
+ console.error(`Live viewer: ${session.metadata["liveUrl"]}`);
10674
+ }
10546
10675
  const cdp = await createCDPClient(session.wsUrl, {
10547
10676
  debug: connectOptions.debug,
10548
10677
  timeout: connectOptions.timeout
@@ -11401,6 +11530,7 @@ function formatWorkflowSummary(summary) {
11401
11530
  Browser,
11402
11531
  BrowserBaseProvider,
11403
11532
  BrowserEndpointResolutionError,
11533
+ BrowserUseProvider,
11404
11534
  BrowserlessProvider,
11405
11535
  CDPError,
11406
11536
  ElementNotFoundError,
package/dist/index.d.cts CHANGED
@@ -5,8 +5,8 @@ import { C as CDPClient } from './client-B5QBRgIy.cjs';
5
5
  export { a as CDPClientOptions, c as createCDPClient } from './client-B5QBRgIy.cjs';
6
6
  export { Browser, BrowserOptions, ComboboxConfig, ComboboxResult, OverlayInfo, PageOptions, PinRecoveryResult, SemanticFingerprint, SubmitAndVerifyOptions, SubmitAndVerifyResult, TargetFingerprint, UploadConfig, UploadResult, buildFingerprintMap, chooseOption, connect, createFingerprint, createTargetFingerprint, detectOverlay, fingerprintKey, fingerprintSimilarity, recoverPinnedTarget, recoverStaleRef, submitAndVerify, uploadFiles } from './browser.cjs';
7
7
  export { CDPError } from './cdp.cjs';
8
- export { BrowserBaseProvider, BrowserlessProvider, GenericProvider, createProvider, discoverTargets, getBrowserWebSocketUrl } from './providers.cjs';
9
- export { B as BrowserEndpointResolutionError, d as ChromeChannel, b as ConnectOptions, C as CreateSessionOptions, P as Provider, a as ProviderSession, R as ResolvedBrowserEndpoint, g as ResolvedBrowserSource, c as buildLocalBrowserScanTargets, f as discoverLocalBrowsers, p as parseDevToolsActivePortFile, r as resolveBrowserEndpoint, h as resolveChromeUserDataDirs } from './types-DeVSWhXj.cjs';
8
+ export { BrowserBaseProvider, BrowserUseOptions, BrowserUseProvider, BrowserlessProvider, GenericProvider, createProvider, discoverTargets, getBrowserWebSocketUrl } from './providers.cjs';
9
+ export { B as BrowserEndpointResolutionError, d as ChromeChannel, b as ConnectOptions, C as CreateSessionOptions, P as Provider, a as ProviderSession, R as ResolvedBrowserEndpoint, g as ResolvedBrowserSource, c as buildLocalBrowserScanTargets, f as discoverLocalBrowsers, p as parseDevToolsActivePortFile, r as resolveBrowserEndpoint, h as resolveChromeUserDataDirs } from './types-D2pJQpWs.cjs';
10
10
 
11
11
  /**
12
12
  * Request interception implementation
package/dist/index.d.ts CHANGED
@@ -5,8 +5,8 @@ import { C as CDPClient } from './client-B5QBRgIy.js';
5
5
  export { a as CDPClientOptions, c as createCDPClient } from './client-B5QBRgIy.js';
6
6
  export { Browser, BrowserOptions, ComboboxConfig, ComboboxResult, OverlayInfo, PageOptions, PinRecoveryResult, SemanticFingerprint, SubmitAndVerifyOptions, SubmitAndVerifyResult, TargetFingerprint, UploadConfig, UploadResult, buildFingerprintMap, chooseOption, connect, createFingerprint, createTargetFingerprint, detectOverlay, fingerprintKey, fingerprintSimilarity, recoverPinnedTarget, recoverStaleRef, submitAndVerify, uploadFiles } from './browser.js';
7
7
  export { CDPError } from './cdp.js';
8
- export { BrowserBaseProvider, BrowserlessProvider, GenericProvider, createProvider, discoverTargets, getBrowserWebSocketUrl } from './providers.js';
9
- export { B as BrowserEndpointResolutionError, d as ChromeChannel, b as ConnectOptions, C as CreateSessionOptions, P as Provider, a as ProviderSession, R as ResolvedBrowserEndpoint, g as ResolvedBrowserSource, c as buildLocalBrowserScanTargets, f as discoverLocalBrowsers, p as parseDevToolsActivePortFile, r as resolveBrowserEndpoint, h as resolveChromeUserDataDirs } from './types-DeVSWhXj.js';
8
+ export { BrowserBaseProvider, BrowserUseOptions, BrowserUseProvider, BrowserlessProvider, GenericProvider, createProvider, discoverTargets, getBrowserWebSocketUrl } from './providers.js';
9
+ export { B as BrowserEndpointResolutionError, d as ChromeChannel, b as ConnectOptions, C as CreateSessionOptions, P as Provider, a as ProviderSession, R as ResolvedBrowserEndpoint, g as ResolvedBrowserSource, c as buildLocalBrowserScanTargets, f as discoverLocalBrowsers, p as parseDevToolsActivePortFile, r as resolveBrowserEndpoint, h as resolveChromeUserDataDirs } from './types-D2pJQpWs.js';
10
10
 
11
11
  /**
12
12
  * Request interception implementation
package/dist/index.mjs CHANGED
@@ -28,10 +28,11 @@ import {
28
28
  waitForElement,
29
29
  waitForNavigation,
30
30
  waitForNetworkIdle
31
- } from "./chunk-FEEGNSHB.mjs";
31
+ } from "./chunk-SW52ALBD.mjs";
32
32
  import {
33
33
  BrowserBaseProvider,
34
34
  BrowserEndpointResolutionError,
35
+ BrowserUseProvider,
35
36
  BrowserlessProvider,
36
37
  GenericProvider,
37
38
  buildLocalBrowserScanTargets,
@@ -42,7 +43,7 @@ import {
42
43
  parseDevToolsActivePortFile,
43
44
  resolveBrowserEndpoint,
44
45
  resolveChromeUserDataDirs
45
- } from "./chunk-EZNZ72VA.mjs";
46
+ } from "./chunk-ASEIFKKV.mjs";
46
47
  import {
47
48
  createCDPClient
48
49
  } from "./chunk-BVZALQT4.mjs";
@@ -546,6 +547,7 @@ export {
546
547
  Browser,
547
548
  BrowserBaseProvider,
548
549
  BrowserEndpointResolutionError,
550
+ BrowserUseProvider,
549
551
  BrowserlessProvider,
550
552
  CDPError,
551
553
  ElementNotFoundError,
@@ -32,6 +32,7 @@ var providers_exports = {};
32
32
  __export(providers_exports, {
33
33
  BrowserBaseProvider: () => BrowserBaseProvider,
34
34
  BrowserEndpointResolutionError: () => BrowserEndpointResolutionError,
35
+ BrowserUseProvider: () => BrowserUseProvider,
35
36
  BrowserlessProvider: () => BrowserlessProvider,
36
37
  GenericProvider: () => GenericProvider,
37
38
  buildLocalBrowserScanTargets: () => buildLocalBrowserScanTargets,
@@ -45,6 +46,108 @@ __export(providers_exports, {
45
46
  });
46
47
  module.exports = __toCommonJS(providers_exports);
47
48
 
49
+ // src/providers/browser-use.ts
50
+ var BrowserUseProvider = class {
51
+ name = "browser-use";
52
+ apiKey;
53
+ baseUrl;
54
+ proxyCountryCode;
55
+ profileId;
56
+ timeout;
57
+ allowResizing;
58
+ customProxy;
59
+ constructor(options) {
60
+ this.apiKey = options.apiKey;
61
+ this.baseUrl = options.baseUrl ?? "https://api.browser-use.com/api/v2";
62
+ this.proxyCountryCode = options.proxyCountryCode === void 0 ? "uk" : options.proxyCountryCode;
63
+ this.profileId = options.profileId;
64
+ this.timeout = options.timeout;
65
+ this.allowResizing = options.allowResizing;
66
+ this.customProxy = options.customProxy;
67
+ }
68
+ async createSession(options = {}) {
69
+ const body = {};
70
+ body["proxyCountryCode"] = this.proxyCountryCode;
71
+ if (options.width) body["browserScreenWidth"] = options.width;
72
+ if (options.height) body["browserScreenHeight"] = options.height;
73
+ if (this.profileId) body["profileId"] = this.profileId;
74
+ if (this.timeout !== void 0) body["timeout"] = this.timeout;
75
+ if (this.allowResizing !== void 0) body["allowResizing"] = this.allowResizing;
76
+ if (this.customProxy) body["customProxy"] = this.customProxy;
77
+ const response = await fetch(`${this.baseUrl}/browsers`, {
78
+ method: "POST",
79
+ headers: {
80
+ "X-Browser-Use-API-Key": this.apiKey,
81
+ "Content-Type": "application/json"
82
+ },
83
+ body: JSON.stringify(body)
84
+ });
85
+ if (!response.ok) {
86
+ const text = await response.text();
87
+ this.throwApiError(response.status, text);
88
+ }
89
+ const session = await response.json();
90
+ if (!session.cdpUrl) {
91
+ throw new Error("Browser Use session does not have a cdpUrl");
92
+ }
93
+ return this.toProviderSession(session);
94
+ }
95
+ async resumeSession(sessionId) {
96
+ const response = await fetch(`${this.baseUrl}/browsers/${sessionId}`, {
97
+ headers: {
98
+ "X-Browser-Use-API-Key": this.apiKey
99
+ }
100
+ });
101
+ if (!response.ok) {
102
+ const text = await response.text();
103
+ throw new Error(`Browser Use resumeSession failed: ${response.status} ${text}`);
104
+ }
105
+ const session = await response.json();
106
+ if (session.status !== "active" || !session.cdpUrl) {
107
+ throw new Error(
108
+ "Browser Use session is not active or does not have a cdpUrl (may be stopped)"
109
+ );
110
+ }
111
+ return this.toProviderSession(session);
112
+ }
113
+ toProviderSession(session) {
114
+ return {
115
+ wsUrl: session.cdpUrl,
116
+ sessionId: session.id,
117
+ metadata: {
118
+ liveUrl: session.liveUrl,
119
+ status: session.status,
120
+ timeoutAt: session.timeoutAt,
121
+ proxyCountryCode: this.proxyCountryCode
122
+ },
123
+ close: async () => {
124
+ await fetch(`${this.baseUrl}/browsers/${session.id}`, {
125
+ method: "PATCH",
126
+ headers: {
127
+ "X-Browser-Use-API-Key": this.apiKey,
128
+ "Content-Type": "application/json"
129
+ },
130
+ body: JSON.stringify({ action: "stop" })
131
+ });
132
+ }
133
+ };
134
+ }
135
+ throwApiError(status, body) {
136
+ switch (status) {
137
+ case 402:
138
+ throw new Error(`Browser Use: insufficient credits (min $0.10 required). ${body}`);
139
+ case 403:
140
+ throw new Error(`Browser Use: invalid API key. ${body}`);
141
+ case 422:
142
+ throw new Error(`Browser Use: validation error. ${body}`);
143
+ case 429:
144
+ throw new Error(`Browser Use: rate limit exceeded. ${body}`);
145
+ default:
146
+ throw new Error(`Browser Use createSession failed: ${status} ${body}`);
147
+ }
148
+ }
149
+ };
150
+
48
151
  // src/providers/browserbase.ts
49
152
  var BrowserBaseProvider = class {
50
153
  name = "browserbase";
@@ -846,6 +949,17 @@ async function resolveBrowserEndpoint(options = {}, deps = defaultDependencies)
846
949
  );
847
950
  }
848
951
 
952
+ // src/runtime/env.ts
953
+ function getProcessEnv() {
954
+ if (typeof globalThis.process !== "undefined" && globalThis.process.env) {
955
+ return globalThis.process.env;
956
+ }
957
+ return {};
958
+ }
959
+ function getEnv(name) {
960
+ return getProcessEnv()[name];
961
+ }
962
+
849
963
  // src/providers/index.ts
850
964
  function createProvider(options) {
851
965
  switch (options.provider) {
@@ -867,6 +981,18 @@ function createProvider(options) {
867
981
  return new BrowserlessProvider({
868
982
  token: options.apiKey
869
983
  });
984
+ case "browser-use": {
985
+ const apiKey = options.apiKey ?? getEnv("BROWSER_USE_API_KEY");
986
+ if (!apiKey) {
987
+ throw new Error("Browser Use provider requires apiKey or BROWSER_USE_API_KEY env var");
988
+ }
989
+ return new BrowserUseProvider({
990
+ apiKey,
991
+ proxyCountryCode: options.proxyCountryCode === void 0 ? "uk" : options.proxyCountryCode,
992
+ profileId: options.profileId,
993
+ timeout: options.cloudTimeout
994
+ });
995
+ }
870
996
  case "generic":
871
997
  if (!options.wsUrl) {
872
998
  throw new Error("Generic provider requires wsUrl");
@@ -882,6 +1008,7 @@ function createProvider(options) {
882
1008
  0 && (module.exports = {
883
1009
  BrowserBaseProvider,
884
1010
  BrowserEndpointResolutionError,
1011
+ BrowserUseProvider,
885
1012
  BrowserlessProvider,
886
1013
  GenericProvider,
887
1014
  buildLocalBrowserScanTargets,
@@ -1,5 +1,40 @@
1
- import { P as Provider, C as CreateSessionOptions, a as ProviderSession, b as ConnectOptions } from './types-DeVSWhXj.cjs';
2
- export { B as BrowserEndpointResolutionError, d as ChromeChannel, e as ChromeUserDataDirOptions, D as DiscoverLocalBrowsersOptions, i as ProxyConfig, R as ResolvedBrowserEndpoint, g as ResolvedBrowserSource, c as buildLocalBrowserScanTargets, f as discoverLocalBrowsers, p as parseDevToolsActivePortFile, r as resolveBrowserEndpoint, h as resolveChromeUserDataDirs } from './types-DeVSWhXj.cjs';
1
+ import { P as Provider, C as CreateSessionOptions, a as ProviderSession, b as ConnectOptions } from './types-D2pJQpWs.cjs';
2
+ export { B as BrowserEndpointResolutionError, d as ChromeChannel, e as ChromeUserDataDirOptions, D as DiscoverLocalBrowsersOptions, i as ProxyConfig, R as ResolvedBrowserEndpoint, g as ResolvedBrowserSource, c as buildLocalBrowserScanTargets, f as discoverLocalBrowsers, p as parseDevToolsActivePortFile, r as resolveBrowserEndpoint, h as resolveChromeUserDataDirs } from './types-D2pJQpWs.cjs';
3
+
4
+ /**
5
+ * Browser Use provider implementation
6
+ * https://browser-use.com/
7
+ */
8
+
9
+ interface BrowserUseOptions {
10
+ apiKey: string;
11
+ baseUrl?: string;
12
+ proxyCountryCode?: string | null;
13
+ profileId?: string;
14
+ timeout?: number;
15
+ allowResizing?: boolean;
16
+ customProxy?: {
17
+ host: string;
18
+ port: number;
19
+ username?: string;
20
+ password?: string;
21
+ };
22
+ }
23
+ declare class BrowserUseProvider implements Provider {
24
+ readonly name = "browser-use";
25
+ private readonly apiKey;
26
+ private readonly baseUrl;
27
+ private readonly proxyCountryCode;
28
+ private readonly profileId?;
29
+ private readonly timeout?;
30
+ private readonly allowResizing?;
31
+ private readonly customProxy?;
32
+ constructor(options: BrowserUseOptions);
33
+ createSession(options?: CreateSessionOptions): Promise<ProviderSession>;
34
+ resumeSession(sessionId: string): Promise<ProviderSession>;
35
+ private toProviderSession;
36
+ private throwApiError;
37
+ }
3
38
 
4
39
  /**
5
40
  * BrowserBase provider implementation
@@ -83,4 +118,4 @@ declare function getBrowserWebSocketUrl(host?: string): Promise<string>;
83
118
  */
84
119
  declare function createProvider(options: ConnectOptions): Provider;
85
120
 
86
- export { type BrowserBaseOptions, BrowserBaseProvider, type BrowserlessOptions, BrowserlessProvider, ConnectOptions, CreateSessionOptions, GenericProvider, type GenericProviderOptions, Provider, ProviderSession, createProvider, discoverTargets, getBrowserWebSocketUrl };
121
+ export { type BrowserBaseOptions, BrowserBaseProvider, type BrowserUseOptions, BrowserUseProvider, type BrowserlessOptions, BrowserlessProvider, ConnectOptions, CreateSessionOptions, GenericProvider, type GenericProviderOptions, Provider, ProviderSession, createProvider, discoverTargets, getBrowserWebSocketUrl };
@@ -1,5 +1,40 @@
1
- import { P as Provider, C as CreateSessionOptions, a as ProviderSession, b as ConnectOptions } from './types-DeVSWhXj.js';
2
- export { B as BrowserEndpointResolutionError, d as ChromeChannel, e as ChromeUserDataDirOptions, D as DiscoverLocalBrowsersOptions, i as ProxyConfig, R as ResolvedBrowserEndpoint, g as ResolvedBrowserSource, c as buildLocalBrowserScanTargets, f as discoverLocalBrowsers, p as parseDevToolsActivePortFile, r as resolveBrowserEndpoint, h as resolveChromeUserDataDirs } from './types-DeVSWhXj.js';
1
+ import { P as Provider, C as CreateSessionOptions, a as ProviderSession, b as ConnectOptions } from './types-D2pJQpWs.js';
2
+ export { B as BrowserEndpointResolutionError, d as ChromeChannel, e as ChromeUserDataDirOptions, D as DiscoverLocalBrowsersOptions, i as ProxyConfig, R as ResolvedBrowserEndpoint, g as ResolvedBrowserSource, c as buildLocalBrowserScanTargets, f as discoverLocalBrowsers, p as parseDevToolsActivePortFile, r as resolveBrowserEndpoint, h as resolveChromeUserDataDirs } from './types-D2pJQpWs.js';
3
+
4
+ /**
5
+ * Browser Use provider implementation
6
+ * https://browser-use.com/
7
+ */
8
+
9
+ interface BrowserUseOptions {
10
+ apiKey: string;
11
+ baseUrl?: string;
12
+ proxyCountryCode?: string | null;
13
+ profileId?: string;
14
+ timeout?: number;
15
+ allowResizing?: boolean;
16
+ customProxy?: {
17
+ host: string;
18
+ port: number;
19
+ username?: string;
20
+ password?: string;
21
+ };
22
+ }
23
+ declare class BrowserUseProvider implements Provider {
24
+ readonly name = "browser-use";
25
+ private readonly apiKey;
26
+ private readonly baseUrl;
27
+ private readonly proxyCountryCode;
28
+ private readonly profileId?;
29
+ private readonly timeout?;
30
+ private readonly allowResizing?;
31
+ private readonly customProxy?;
32
+ constructor(options: BrowserUseOptions);
33
+ createSession(options?: CreateSessionOptions): Promise<ProviderSession>;
34
+ resumeSession(sessionId: string): Promise<ProviderSession>;
35
+ private toProviderSession;
36
+ private throwApiError;
37
+ }
3
38
 
4
39
  /**
5
40
  * BrowserBase provider implementation
@@ -83,4 +118,4 @@ declare function getBrowserWebSocketUrl(host?: string): Promise<string>;
83
118
  */
84
119
  declare function createProvider(options: ConnectOptions): Provider;
85
120
 
86
- export { type BrowserBaseOptions, BrowserBaseProvider, type BrowserlessOptions, BrowserlessProvider, ConnectOptions, CreateSessionOptions, GenericProvider, type GenericProviderOptions, Provider, ProviderSession, createProvider, discoverTargets, getBrowserWebSocketUrl };
121
+ export { type BrowserBaseOptions, BrowserBaseProvider, type BrowserUseOptions, BrowserUseProvider, type BrowserlessOptions, BrowserlessProvider, ConnectOptions, CreateSessionOptions, GenericProvider, type GenericProviderOptions, Provider, ProviderSession, createProvider, discoverTargets, getBrowserWebSocketUrl };
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  BrowserBaseProvider,
3
3
  BrowserEndpointResolutionError,
4
+ BrowserUseProvider,
4
5
  BrowserlessProvider,
5
6
  GenericProvider,
6
7
  buildLocalBrowserScanTargets,
@@ -11,12 +12,13 @@ import {
11
12
  parseDevToolsActivePortFile,
12
13
  resolveBrowserEndpoint,
13
14
  resolveChromeUserDataDirs
14
- } from "./chunk-EZNZ72VA.mjs";
15
+ } from "./chunk-ASEIFKKV.mjs";
15
16
  import "./chunk-BVZALQT4.mjs";
16
17
  import "./chunk-JXAUPHZM.mjs";
17
18
  export {
18
19
  BrowserBaseProvider,
19
20
  BrowserEndpointResolutionError,
21
+ BrowserUseProvider,
20
22
  BrowserlessProvider,
21
23
  GenericProvider,
22
24
  buildLocalBrowserScanTargets,
@@ -120,7 +120,7 @@ interface ProxyConfig {
120
120
  }
121
121
  interface ConnectOptions {
122
122
  /** Provider type */
123
- provider: 'browserbase' | 'browserless' | 'generic';
123
+ provider: 'browserbase' | 'browserless' | 'browser-use' | 'generic';
124
124
  /** API key for hosted providers */
125
125
  apiKey?: string;
126
126
  /** Project ID (for BrowserBase) */
@@ -137,6 +137,12 @@ interface ConnectOptions {
137
137
  debug?: boolean;
138
138
  /** Connection timeout in ms */
139
139
  timeout?: number;
140
+ /** Proxy country code for Browser Use provider (default: 'uk'). Set null to disable. */
141
+ proxyCountryCode?: string | null;
142
+ /** Browser profile ID for Browser Use provider */
143
+ profileId?: string;
144
+ /** Session timeout in minutes for Browser Use provider (max 240) */
145
+ cloudTimeout?: number;
140
146
  }
141
147
 
142
148
  export { BrowserEndpointResolutionError as B, type CreateSessionOptions as C, type DiscoverLocalBrowsersOptions as D, type Provider as P, type ResolvedBrowserEndpoint as R, type ProviderSession as a, type ConnectOptions as b, buildLocalBrowserScanTargets as c, type ChromeChannel as d, type ChromeUserDataDirOptions as e, discoverLocalBrowsers as f, type ResolvedBrowserSource as g, resolveChromeUserDataDirs as h, type ProxyConfig as i, parseDevToolsActivePortFile as p, resolveBrowserEndpoint as r };
@@ -120,7 +120,7 @@ interface ProxyConfig {
120
120
  }
121
121
  interface ConnectOptions {
122
122
  /** Provider type */
123
- provider: 'browserbase' | 'browserless' | 'generic';
123
+ provider: 'browserbase' | 'browserless' | 'browser-use' | 'generic';
124
124
  /** API key for hosted providers */
125
125
  apiKey?: string;
126
126
  /** Project ID (for BrowserBase) */
@@ -137,6 +137,12 @@ interface ConnectOptions {
137
137
  debug?: boolean;
138
138
  /** Connection timeout in ms */
139
139
  timeout?: number;
140
+ /** Proxy country code for Browser Use provider (default: 'uk'). Set null to disable. */
141
+ proxyCountryCode?: string | null;
142
+ /** Browser profile ID for Browser Use provider */
143
+ profileId?: string;
144
+ /** Session timeout in minutes for Browser Use provider (max 240) */
145
+ cloudTimeout?: number;
140
146
  }
141
147
 
142
148
  export { BrowserEndpointResolutionError as B, type CreateSessionOptions as C, type DiscoverLocalBrowsersOptions as D, type Provider as P, type ResolvedBrowserEndpoint as R, type ProviderSession as a, type ConnectOptions as b, buildLocalBrowserScanTargets as c, type ChromeChannel as d, type ChromeUserDataDirOptions as e, discoverLocalBrowsers as f, type ResolvedBrowserSource as g, resolveChromeUserDataDirs as h, type ProxyConfig as i, parseDevToolsActivePortFile as p, resolveBrowserEndpoint as r };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browser-pilot",
3
- "version": "0.0.17",
3
+ "version": "0.0.18",
4
4
  "description": "Lightweight CDP-based browser automation for Node.js, Bun, and Cloudflare Workers",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",